Android 跟随手指移动的圆
来源:互联网 发布:模糊c均值聚类算法 编辑:程序博客网 时间:2024/04/29 22:49
通过onTouchEvent实现一个简单的跟随触摸点移动的圆
public class CircleFollowView extends View {private static final String Tag = "CircleFollowView";private float currentX = 50;private float currentY = 50;private int radius = 50;// 控件宽度private int mWidth;// 控件高度private int mHeight;private int lastX;private int lastY;public CircleFollowView(Context context) {super(context);}public CircleFollowView(Context context, AttributeSet attrs) {super(context, attrs);}public CircleFollowView(Context context, AttributeSet attrs,int defStyleAttr) {super(context, attrs, defStyleAttr);}private void initView() {// 取最小的长度的一半作为半径// layout中View要设定绝对大小,例如具体dp或者match_patent,否则点击屏幕其他地方也可能移动圆this.radius = (mWidth / 2 < mHeight / 2) ? mWidth / 2 : mHeight / 2;this.currentX = mWidth / 2;this.currentY = mHeight / 2;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {int widthMode = MeasureSpec.getMode(widthMeasureSpec);int heightMode = MeasureSpec.getMode(heightMeasureSpec);int widthSize = MeasureSpec.getSize(widthMeasureSpec);int heightSize = MeasureSpec.getSize(heightMeasureSpec);if (widthMode == MeasureSpec.EXACTLY) {mWidth = widthSize;} else if (widthMode == MeasureSpec.AT_MOST) {throw new IllegalArgumentException("width must be EXACTLY,you should set like android:width=\"200dp\"");}if (heightMode == MeasureSpec.EXACTLY) {mHeight = heightSize;} else if (widthMeasureSpec == MeasureSpec.AT_MOST) {throw new IllegalArgumentException("height must be EXACTLY,you should set like android:height=\"200dp\"");}setMeasuredDimension(mWidth, mHeight);}@SuppressLint("DrawAllocation")@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);initView();Paint p = new Paint();p.setColor(Color.RED);canvas.drawCircle(currentX, currentY, radius, p);}@Overridepublic boolean onTouchEvent(MotionEvent event) {// 触摸点到屏幕左上角的距离int rawX = (int) event.getRawX();int rawY = (int) event.getRawY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:lastX = rawX;lastY = rawY;break;case MotionEvent.ACTION_MOVE:int offsetX = rawX - lastX;int offsetY = rawY - lastY;offsetLeftAndRight(offsetX);offsetTopAndBottom(offsetY);lastX = rawX;lastY = rawY;break;case MotionEvent.ACTION_UP:lastX = rawX;lastY = rawY;break;}return true;}}
上面一种方式是通过修改View距离屏幕的位置实现滑动,下面使用Scroller(其他内容相同,只展示onTouchEvent部分):
int offsetX;int offsetY;@Overridepublic boolean onTouchEvent(MotionEvent event) {int x = (int) event.getX();int y = (int) event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:lastX = (int) event.getX();lastY = (int) event.getY();break;case MotionEvent.ACTION_MOVE:offsetX = x - lastX;offsetY = y - lastY; ((View) getParent()).scrollBy(-offsetX, -offsetY); invalidate();break;default:break;}return true;}
scroll的位移从左到右为负值,从右到左是正值,从上到下是负值,从下到上是正值,所以使用scrollBy时参数取负。
((View) getParent()).scrollBy(-offsetX, -offsetY);如果替换为
View viewGroup = ((View) getParent());
mScroller.startScroll(viewGroup.getScrollX(), viewGroup.getScrollY(), -offsetX, -offsetY,1000);//1s完成滑动
需要配合
public void computeScroll() {super.computeScroll();if (mScroller.computeScrollOffset()) {((View) getParent()).scrollTo(mScroller.getCurrX(),mScroller.getCurrY());// 通过重绘来不断调用computeScrollinvalidate();}}
通过invalidate()->onDraw()->computeScroll()一部分一部分重绘实现滑动,但是不能实时,可以实现一种延迟的滑动效果。
scrollTo/scrollBy这种方式能比较方便的实现滑动效果并且不影响点击时间,但是他只能滑动View的内部,所以上面代码中滑动使用的是getParent(),实际运用时,滑动的部分最好单独写在一个ViewGroup中,否则父组件内的所有内容会一起滑动。
第三种修改LayoutParams,向左移动,就增加marginLeft:
public boolean onTouchEvent(MotionEvent event) {// 触摸点到屏幕左上角的距离int rawX = (int) event.getRawX();int rawY = (int) event.getRawY();VelocityTracker velocityTracker = VelocityTracker.obtain();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:lastX = rawX;lastY = rawY;break;case MotionEvent.ACTION_MOVE:int offsetX = rawX - lastX;int offsetY = rawY - lastY;MarginLayoutParams layoutParams = (MarginLayoutParams) getLayoutParams();layoutParams.leftMargin += offsetX;layoutParams.topMargin += offsetY;requestLayout();//或者setLayoutParams(layoutParams);lastX = rawX;lastY = rawY;break;case MotionEvent.ACTION_UP:lastX = rawX;lastY = rawY;break;}return true;}
最后,如果滑动的效果不是实时的,也可以采用动画的方式,动画比较适合复杂的效果和没有交互的View。
0 0
- Android 跟随手指移动的圆
- Android---26---跟随手指移动的小球
- android 跟随手指移动的 view
- android 控件跟随手指移动
- 跟随手指移动的小球
- android从零开始-开发自定义View-跟随手指移动的小球
- android View 跟随手指移动的7种方式
- Android——控件跟随手指移动
- Android拖动小球跟随手指移动Demo
- Android跟随手指的小球
- 自定义ViewGroup[跟随手指移动的view]
- 一个可以跟随手指移动的PopupWindow
- 实现跟随手指移动的小球
- 实现跟随手指移动的小球
- 跟随手指移动小球
- button跟随手指移动
- 小球跟随手指移动
- android引导页下方圆点位置跟随手指移动的实现
- Redis常用几种数据类型
- 安装 Kali Linux 后需要做的 20 件事
- Intent和IntentFilter
- cmake:用add_subdirectory()添加外部项目文件夹
- java之时间格式
- Android 跟随手指移动的圆
- 不忘历史、维护中国海权
- 内存分配函数malloc calloc realloc
- BJOI2011 严格次小生成树
- Android四大基本组件介绍与生命周期
- phpmyadmin增加外键
- 桥接模式
- nginx 的日志记录 response 的报文头
- UVA1616 商队抢劫者