您的位置:首页 > 其它

View滑动的七种方法

2015-12-16 17:38 204 查看
最近总是感觉自己力不从心,好多都不会啊,都不会,所以想从基础学起一些东西,总结一下自定义view滑动的方式。这里以可以随手指滑动的textview 为例子:

上效果图:



直接上源码:

第一种方式:

public class MyTextView extends TextView {

private int x, y, dx, dy, offX, offY;

public MyTextView(Context context) {
this(context, null);
}

public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);

}

/**
* getX getY ,layout实现
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {

x = (int) event.getX();
y = (int) event.getY();

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:
dx = x;
dy = y;

break;

case MotionEvent.ACTION_MOVE:
offX = x - dx;
offY = y - dy;
layout(getLeft()+offX,getTop()+offY,getRight()+offX,getBottom()+offY);

break;

}

return super.onTouchEvent(event);
}
}


第二种方式:

由于都是重写onTouch ,重复的代码就不粘贴了

/**
* getRawX getRawY 跟上面的一样,只不过需要注意的是初始化
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {

x = (int) event.getRawX();
y = (int) event.getRawY();

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:
dx = x;
dy = y;
break;

case MotionEvent.ACTION_MOVE:
offX = x - dx;
offY = y - dy;
layout(getLeft()+offX,getTop()+offY,getRight()+offX,getBottom()+offY);
Log.d("dx---------------------", "" + dx);
Log.d("x---------------------",""+x);

//需要重新初始化手指按下的坐标 如果dx dy不跟随手指而变化的话,会导致变化过大,view飞出去,或者连续移动一大段距离
dx=x;
dy=y;

break;

}

return super.onTouchEvent(event);
}


第三种方式:

/**
* getRawX getRawY 跟上面的一样,只不过需要注意的是初始化
* offsetLeftAndRight offsetTopAndBottom 实现
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {

x = (int) event.getRawX();
y = (int) event.getRawY();

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:
dx = x;
dy = y;
break;

case MotionEvent.ACTION_MOVE:
offX = x - dx;
offY = y - dy;
offsetLeftAndRight(offX);
offsetTopAndBottom(offY);
Log.d("dx---------------------", "" + dx);
Log.d("x---------------------",""+x);

//需要重新初始化手指按下的坐标 如果dx dy不跟随手指而变化的话,会导致变化过大,view飞出去,或者连续移动一大段距离
dx=x;
dy=y;

break;

}

return super.onTouchEvent(event);
}


第四种方式:

/**
* LinearLayout.LayoutParams RelativeLayout.layoutParams 需要注意父容器的类型
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {

x = (int) event.getRawX();
y = (int) event.getRawY();

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:
dx = x;
dy = y;
break;

case MotionEvent.ACTION_MOVE:
offX = x - dx;
offY = y - dy;
LinearLayout.LayoutParams layoutParams=(LinearLayout.LayoutParams)getLayoutParams();
layoutParams.leftMargin=getLeft()+offX;
layoutParams.topMargin=getTop()+offY;
setLayoutParams(layoutParams);

Log.d("dx---------------------", "" + dx);
Log.d("x---------------------",""+x);

//需要重新初始化手指按下的坐标 如果dx dy不跟随手指而变化的话,会导致变化过大,view飞出去,或者连续移动一大段距离
dx=x;
dy=y;

break;

}

return super.onTouchEvent(event);
}


第五种方式:

/**
* ViewGroup.MarginLayoutParams 跟上面的方法比较类似,但是不必要注意父布局的类型了,没有限制
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {

x = (int) event.getRawX();
y = (int) event.getRawY();

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:
dx = x;
dy = y;
break;

case MotionEvent.ACTION_MOVE:
offX = x - dx;
offY = y - dy;

ViewGroup.MarginLayoutParams layoutParams=(ViewGroup.MarginLayoutParams)getLayoutParams();
layoutParams.leftMargin=getLeft()+offX;
layoutParams.topMargin=getTop()+offY;
setLayoutParams(layoutParams);

Log.d("dx---------------------", "" + dx);
Log.d("x---------------------",""+x);

//需要重新初始化手指按下的坐标 如果dx dy不跟随手指而变化的话,会导致变化过大,view飞出去,或者连续移动一大段距离
dx=x;
dy=y;

break;

}

return super.onTouchEvent(event);
}


第六种方式:

/**
* scrollBy 实现 scroll移动的是内容,例如本例是个textview那么移动的就是textview的文字了,所以需要getParent
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {

x = (int) event.getRawX();
y = (int) event.getRawY();

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:
dx = x;
dy = y;
break;

case MotionEvent.ACTION_MOVE:
offX = x - dx;
offY = y - dy;

//由于参考系的不同所以需要前面加上"-"号
((ViewGroup)getParent()).scrollBy(-offX,-offY);

Log.d("dx---------------------", "" + dx);
Log.d("x---------------------",""+x);

//需要重新初始化手指按下的坐标 如果dx dy不跟随手指而变化的话,会导致变化过大,view飞出去,或者连续移动一大段距离
dx=x;
dy=y;

break;

}

return super.onTouchEvent(event);
}


第七种方式:

上效果图:




public class MyTextView extends TextView {

private int x, y, dx, dy, offX, offY;

private Scroller mScroller;

public MyTextView(Context context) {
this(context, null);
}

public MyTextView(Context context, AttributeSet attrs) {
super(context, attrs);
mScroller = new Scroller(context);//初始化scroller对象

}

@Override
public void computeScroll() {
super.computeScroll();
//会循环调用下面的代码直到到达指定位置
if (mScroller.computeScrollOffset()) {

((ViewGroup) getParent()).scrollTo(mScroller.getCurrX(), mScroller.getCurrY());
invalidate();
}

}

/**
* scroller 方法实现滑动
*
* @param event
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
ViewGroup viewGroup = (ViewGroup) getParent();

x = (int) event.getRawX();
y = (int) event.getRawY();

switch (event.getAction()) {

case MotionEvent.ACTION_DOWN:

dx = x;
dy = y;

break;

case MotionEvent.ACTION_MOVE:

offX = x - dx;
offY = y - dy;

viewGroup.scrollBy(-offX, -offY);

dx = x;
dy = y;

break;

case MotionEvent.ACTION_UP:

//回滚回原来的位置,也可以加上时间
mScroller.startScroll(viewGroup.getScrollX(), viewGroup.getScrollY(),
-(viewGroup.getScrollX()), -(viewGroup.getScrollY()));

invalidate();

break;

}

return super.onTouchEvent(event);
}

}


上面的貌似是个假的第七种方法,这里面其实主要说的是scroller这个类的使用!~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: