好吧,我想出了一个不是最优雅的解决方案,但我可以工作。我扩展了开关控件并为想要对某些拖动事件采取行动的对象创建了一个界面。请看下文。
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);
}
}
您现在要做的就是在布局中使用此开关,然后在主类中设置适当的侦听器。希望这可以帮助某人(即使它非常具体)。