我有一些关于 Android 切换按钮和创建一些自定义行为的具体问题。所以...我需要的是只允许开关在从 OFF 位置转换到 ON 位置时可拖动。我能够得到它,这样如果我在关闭位置单击开关,它就不会转换。但是,我不想将开关从关闭位置拨到打开位置。我希望用户不得不不断地拖动它。现在您可能认为搜索栏就是我要找的东西。也许吧,但我需要拇指部分的文本过渡在进行切换时从关闭变为打开。在使用搜索栏时,这看起来并不是一个真正的选择。此外,如果用户在打开位置时单击拇指,它可以转换到关闭位置。此外,没有介于两者之间。如果用户从关闭到打开(仅拖动),他们必须一直走到最后。任何帮助表示赞赏。我的基本代码如下:
public class MainActivity extends Activity {
private TextView switchStatus;
private Switch mySwitch;
private Handler handler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
switchStatus = (TextView) findViewById(R.id.switchStatus);
mySwitch = (Switch) findViewById(R.id.mySwitch);
//set the switch to ON
mySwitch.setChecked(true);
//attach a listener to check for changes in state
mySwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if(isChecked){
switchStatus.setText("Switch is currently ON");
}else{
switchStatus.setText("Switch is currently OFF");
}
}
});
mySwitch.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(mySwitch.isChecked()) {
mySwitch.setChecked(false);
}
}
});
//check the current state before we display the screen
if(mySwitch.isChecked()){
switchStatus.setText("Switch is currently ON");
}
else {
switchStatus.setText("Switch is currently OFF");
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
最佳答案
好吧,我想出了一个不是最优雅的解决方案,但我的作品。我扩展了开关控件并为想要对某些拖动事件起作用的对象创建了一个界面。请看下面。
public class CustomSwitch extends Switch {
private static final String TAG = CustomSwitch.class.getSimpleName();
private Method getThumbScrollRange;
private int thumbScrollRange;
private float thumbPosition;
private boolean isMiddleOn = false;
private boolean isMiddleOff = true;
private boolean isOnMax = false;
private boolean isOffMin = true;
private boolean isMoving = false;
private final int PIVOT_PERCENT = 50;
private final int OFF_PERCENT_TOLERANCE = 10;
private final int ON_PERCENT_TOLERANCE = 10;
private final int ON_MAX_PERCENT = 100;
private final int OFF_MIN_PERCENT = 0;
private onDraggableSwitchListener onDraggableSwitchListener;
public CustomSwitch(Context context) {
this(context, null);
}
public CustomSwitch(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CustomSwitch(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs);
this.setOnTouchListener(new OnTouchListener() {
// set via variable since the switch will trigger a move
// action on toggle, but the on draw event will trigger
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE) {
isMoving = true;
}
else {
isMoving = false;
}
if (onDraggableSwitchListener != null) {
onDraggableSwitchListener.onTouchEvent(v, event);
}
return false;
}
});
this.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
isOnMax = isMiddleOn = isChecked;
isOffMin = isMiddleOff = !isChecked;
if (onDraggableSwitchListener != null) {
onDraggableSwitchListener.onCheckedChanged(buttonView, isChecked);
}
}
});
try {
getThumbScrollRange = Switch.class.getDeclaredMethod("getThumbScrollRange");
getThumbScrollRange.setAccessible(true);
}
catch (NoSuchMethodException e) {
Log.e(TAG, "Error", e);
}
}
/**
* Registers the {@link on}
* */
public void setOnDraggableSwitchListener(onDraggableSwitchListener listener) {
onDraggableSwitchListener = listener;
}
@Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
try {
thumbScrollRange = (Integer) getThumbScrollRange.invoke(this);
}
catch (Exception e) {
Log.e(TAG, "", e);
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
try {
thumbPosition = getField("mThumbPosition").getFloat(this);
int percentage = (thumbScrollRange == 0 ? 0 : ((int) ((thumbPosition / thumbScrollRange) * 100)));
Log.v(TAG, "Percentage: " + percentage);
if ((percentage > PIVOT_PERCENT) && !isMiddleOn && isMoving) {
if (onDraggableSwitchListener != null) onDraggableSwitchListener.onDraggableSwitchOnMiddle(percentage);
isMiddleOn = true;
isOffMin = isMiddleOff = false;
Log.v(TAG, "MIDDLE ON TRUE");
}
else if ((percentage < PIVOT_PERCENT) && !isMiddleOff && isMoving) {
if (onDraggableSwitchListener != null) onDraggableSwitchListener.onDraggableSwitchOffMiddle(percentage);
isMiddleOff = true;
isOnMax = isMiddleOn = false;
Log.v(TAG, "MIDDLE OFF TRUE");
}
if ((percentage <= (OFF_MIN_PERCENT + OFF_PERCENT_TOLERANCE)) && !isOffMin && isMoving) {
if (onDraggableSwitchListener != null) onDraggableSwitchListener.onDraggableSwitchOffMin();
isOffMin = true;
Log.v(TAG, "OFF MIN TRUE");
}
else if ((percentage >= (ON_MAX_PERCENT - ON_PERCENT_TOLERANCE)) && !isOnMax && isMoving) {
if (onDraggableSwitchListener != null) onDraggableSwitchListener.onDraggableSwitchOnMax();
isOnMax = true;
Log.v(TAG, "ON MAX TRUE");
}
}
catch (IllegalArgumentException e) {
Log.e(TAG, "", e);
}
catch (IllegalAccessException e) {
Log.e(TAG, "", e);
}
}
/** Cache of private fields from superclass */
private Map<String, Field> fieldCache = new HashMap<String, Field>();
private Field getField(String name) {
try {
if (!fieldCache.containsKey(name)) {
Field f = Switch.class.getDeclaredField(name);
f.setAccessible(true);
fieldCache.put(name, f);
}
return fieldCache.get(name);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
public static interface onDraggableSwitchListener {
public void onDraggableSwitchOnMax();
public void onDraggableSwitchOffMin();
public void onDraggableSwitchOnMiddle(int percentage);
public void onDraggableSwitchOffMiddle(int percentage);
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked);
public void onTouchEvent(View v, MotionEvent event);
}
}
您现在所要做的就是在您的布局中使用此开关,然后在您的主类中您可以设置适当的监听器。希望这对某人有所帮助(即使它非常具体)。
关于Android Switch Button Drag off 点击/拖动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26589568/