代码改造自任玉刚 《Android开发艺术探索》第三章《View的实践体系》
github地址是:
https://github.com/singwhatiwanna/android-art-res
原来的代码如下:
package com.ryg.chapter_3.ui;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.ViewConfiguration;
import android.widget.TextView;
import com.nineoldandroids.view.ViewHelper;
public class TestButton extends TextView {
private static final String TAG = "TestButton";
private int mScaledTouchSlop;
// 分别记录上次滑动的坐标
private int mLastX = 0;
private int mLastY = 0;
public TestButton(Context context) {
this(context, null);
}
public TestButton(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public TestButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
mScaledTouchSlop = ViewConfiguration.get(getContext())
.getScaledTouchSlop();
Log.d(TAG, "sts:" + mScaledTouchSlop);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getRawX();
int y = (int) event.getRawY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
break;
}
case MotionEvent.ACTION_MOVE: {
int deltaX = x - mLastX;
int deltaY = y - mLastY;
Log.d(TAG, "move, deltaX:" + deltaX + " deltaY:" + deltaY);
int translationX = (int)ViewHelper.getTranslationX(this) + deltaX;
int translationY = (int)ViewHelper.getTranslationY(this) + deltaY;
ViewHelper.setTranslationX(this, translationX);
ViewHelper.setTranslationY(this, translationY);
break;
}
case MotionEvent.ACTION_UP: {
break;
}
default:
break;
}
mLastX = x;
mLastY = y;
return true;
}
}
该组件可以做到自由在父容器中移动,甚至可以移动到父容器的外面,就是出现了直接消失的情况;
因此需要对其移动范围做一定的限制,限制在父容器中,上下左右4个边界均不超过父容器的边界,修改后如下:
package com.ryg.chapter_3.ui;
import android.annotation.SuppressLint;
import android.content.Context;
import android.support.v7.widget.AppCompatTextView;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
public class TestButton2 extends AppCompatTextView {
private static final String TAG = "TestButton2";
private int mScaledTouchSlop;
// 分别记录上次滑动的坐标
private int mLastX = 0;
private int mLastY = 0;
private int mParentWidth;
private int mParentHeight;
private int mWidth;
private int mHeight;
/**
* 初始位置
*/
private int mStartTop;
private int mStartBottom;
private int mStartLeft;
private int mStartRight;
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
this.mHeight = getHeight();
this.mWidth = getWidth();
}
public TestButton2(Context context) {
this(context, null);
}
public TestButton2(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public TestButton2(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
//最小滑动距离:大于这个值时 触发移动
mScaledTouchSlop = ViewConfiguration.get(getContext())
.getScaledTouchSlop();
Log.d(TAG, "sts:" + mScaledTouchSlop);
post(new Runnable() {
@Override
public void run() {
mParentWidth = ((View) getParent()).getWidth();
mParentHeight = ((View) getParent()).getHeight();
mWidth = getWidth();
mHeight = getHeight();
mStartTop = getTop();
mStartBottom = getBottom();
mStartLeft = getLeft();
mStartRight = getRight();
}
});
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int) event.getRawX();
int y = (int) event.getRawY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
break;
}
case MotionEvent.ACTION_MOVE: {
int deltaX = x - mLastX;
int deltaY = y - mLastY;
Log.d(TAG, "move, deltaX:" + deltaX + " deltaY:" + deltaY);
int translationX = (int) this.getTranslationX() + deltaX;
int translationY = (int) this.getTranslationY() + deltaY;
//add by duoxioo start
//ok
if (translationX > mParentWidth - mStartRight) {
translationX = mParentWidth - mStartRight;
} else if (translationX < -mStartLeft) {
translationX = -mStartLeft;
}
//ok
//ok
if (translationY > mParentHeight - mStartBottom) {
translationY = mParentHeight - mStartBottom;
} else if (translationY < -mStartTop) {
translationY = -mStartTop;
}
//ok
Log.d(TAG, "onTouchEvent: translationX = " + translationX);
Log.d(TAG, "onTouchEvent: translationY = " + translationY);
//add by duoxioo end
this.setTranslationX(translationX);
this.setTranslationY(translationY);
break;
}
case MotionEvent.ACTION_UP: {
break;
}
default:
break;
}
mLastX = x;
mLastY = y;
return true;
}
}
这样子可以有限的移动了,不会滑动到容器之外了。
网友评论