手指拖动一个滑块在屏幕中来回的移动例子:
摘要:通过ViewGroup中的onLayout() 方法来重新布局子类的位置。
自定义ViewCustom继承ViewGroup,重写onLayout()方法,在该方法中调用子类滑块(SquareView)的layout()方法。
@Override
protected void onLayout(boolean b, int i, int i1, int i2, int i3) {
View localView = getChildAt(0);
if (localView != null) {
int left = localView.getLeft() + moveX;
int top = localView.getTop() + moveY;
Log.d(TAG, "(left, top) = (" + left + "," + top + ")");
localView.layout(left, top, left + 100, top + 100);
}
}
SquareView继承View,重写onDraw(Canvas canvas)方法,绘制一个正方形。
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
int left = getLeft();
int top = getTop();
rfClip = new RectF(left, top, left + 100, top + 100);
canvas.drawRect(rfClip, mPaint);
}
两个核心类定义完成,接下来详解整个过程的代码实现。
当手指按到滑块,滑块才会随着手指移动。也就是说手指按在滑块上,才会调用父类ViewCustom中的onLayout()方法。
如何判断手指按到滑动上呢?滑块类SquareView中重写onTouchEvent(MontionEvent event)方法,在该方法中捕获到ACTION_DOWN即可知道手机按在了滑动上。
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
Log.d(TAG, "View 中的ACTION_DOWN事件不处理");
ViewParent viewParent = getParent();
if (viewParent instanceof ViewCustom) {
ViewCustom localViewCustom = (ViewCustom) viewParent;
localViewCustom.SetMoveFlag(true);
}
}
break;
}
在该方法中,调用父类ViewCustom的setMoveFlag()方法,该方法的作用就是设置一个表识来判断手指按在了滑动上。
接下来重写ViewCustom中的onTouchEvent(MotionEvent event)方法。
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_MOVE: {
if (setMoveFlag) {
requestLayout();
}
}
break;
case MotionEvent.ACTION_UP: {
}
break;
}
return super.onTouchEvent(event);
}
如果手指按在了滑块上,那么调用requestLayout()方法,该方法是ViewGroup类中的方法,主要作用回调onLayout()方法。
Code过程中发现一个问题,对于事件ACTION_MOVE的理解,当按下屏幕后,不移动手指也会频繁的回调该事件。