View滑动的七种方法
2015-12-16 17:38
204 查看
最近总是感觉自己力不从心,好多都不会啊,都不会,所以想从基础学起一些东西,总结一下自定义view滑动的方式。这里以可以随手指滑动的textview 为例子:
上效果图:
直接上源码:
第一种方式:
第二种方式:
由于都是重写onTouch ,重复的代码就不粘贴了
第三种方式:
第四种方式:
第五种方式:
第六种方式:
第七种方式:
上面的貌似是个假的第七种方法,这里面其实主要说的是scroller这个类的使用!~
上效果图:
直接上源码:
第一种方式:
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这个类的使用!~
相关文章推荐
- 浅析Tomcat之Pipeline和Value
- Python数据类型:列表、阵列
- CityEngine中的坐标系统
- codecademy笔记,二维list
- QTreeWidget树的三态操作
- OC对文本的操作
- StringBuffer代码优化
- ie 7/8/9 placeholder 不显示 解决方案
- 机器学习入门(一)朴素贝叶斯解析
- 应用EL表达式显示客户端能够接收的内容类型
- oracle11G使用DGbroker创建dg
- iframe自适应高度
- android 友盟 用户反馈 自定义界面发图片问题
- MySQL中列子查询与行子查询操作的学习教程
- Canvas 的绘制图表的基本用法
- 1.6---旋转二维数组,旋转图像像素,旋转矩阵,90度(CC150)
- iOS真机调试报错 A valid provisioning profile for this executable was not found.
- 开启Instruments之旅吧
- 自定义View执行invalidate()方法
- 最最简单又实用的ftp安装以及使用