大佬教程收集整理的这篇文章主要介绍了Android实现控件的缩放移动功能,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
上篇文章给大家介绍了 Android控件实现图片缩放功能 ,需要的朋友点击查看。
话不多说先来张效果图
控件缩放移动.gif
上面的gif中,依次进行了拖动――>触摸右上角放大,缩小――>触摸上方与右测边缘――>双指放大缩小。
2.1 布局。外层一个linearLayout,里面一个自定义的控件DragScaleVIEw,为了能够更清楚的看到控件的变化过程,就给控件加了一个灰色带虚线的边框bg_dashgap。
layout文件
<?xml version="1.0" enCoding="utf-8"?> <linearLayout xmlns:androID="http://scheR_520_11845@as.androID.com/apk/res/androID" androID:orIEntation="vertical" androID:ID="@+ID/root" androID:layout_wIDth="match_parent" androID:layout_height="match_parent" androID:BACkground="#80ce3d3a" androID:gravity="center_horizontal" androID:fitsSystemwindows="true"> <com.xxx.xxx.ui.DragScaleVIEw androID:ID="@+ID/hair_dv" androID:src="@drawable/ic_sure" androID:BACkground="@drawable/bg_dashgap" androID:adjustVIEwBounds="true" androID:layout_marginleft="50dp" androID:layout_margintop="10dp" androID:layout_wIDth="100dp" androID:layout_height="120dp" androID:clickable="true"/> </linearLayout>
在drawable文件夹下的bg_dashgap.xml
<?xml version="1.0" enCoding="utf-8"?> <shape xmlns:androID="http://scheR_520_11845@as.androID.com/apk/res/androID" > <!-- 圆角 --> <corners androID:bottomLefTradius="8dp" androID:bottomrighTradius="8dp" androID:radius="15dp" androID:topLefTradius="8dp" androID:topRighTradius="8dp" /> <!-- 描边 --> <stroke androID:dashGap="4dp" androID:dashWIDth="4dp" androID:wIDth="2dp" androID:color="@color/my_gery" /> </shape>
2.2 自定义的控件
单指触摸:
当ACTION_DOWN时如果坐标为1.2.3.4四个区域,则对VIEw进行相应的左上/右上/左下/右下拉伸;
当ACTION_DOWN时如果坐标为5.6.7.8四个区域,则分别对上/右/下/左四个方向进行拉伸;
当ACTION_DOWN时如果坐标为9这个区域,则对VIEw进行移动;
双指触摸:
先计算出触摸时双指的距离,float oridist=distance(event);
再得到双指离开屏幕的距离,float newdist =distance(event);
得到两者之间的比例 float scale = newdist / oridist;
计算双指间距离的方法
/** * 计算两个手指间的距离 * @param event 触摸事件 * @return 放回两个手指之间的距离 */ private float distance(MotionEvent event) { float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); return (float) Math.sqrt(x * x + y * y);//两点间距离公式 }
自定义的控件
ontouch(VIEw v,MotionEvent event)的触摸事件中代码块
image.png
其他的关键地方,代码中都有比较详细的注释了。思路就是
触摸监听
判断不同情况---getDirection(v,(int) event.getX(),(int) event.getY())
计算得到新的orileft,oritop,oriRight,oriBottom
重新绘制---v.layout(orileft,oriBottom)
public class DragScaleVIEw extends androID.support.v7.Widget.AppCompatimageVIEw implements VIEw.ontouchListener { protected int screenWIDth; protected int screenHeight; protected int lastX; protected int lastY; privatE int orileft; privatE int oriRight; privatE int oritop; privatE int oriBottom; privatE int dragDirection; private static final int top = 0x15; private static final int left = 0x16; private static final int BottOM = 0x17; private static final int RIGHT = 0x18; private static final int left_top = 0x11; private static final int RIGHT_top = 0x12; private static final int lefT_BottOM = 0x13; private static final int RIGHT_BottOM = 0x14; private static final int touch_TWO = 0x21; private static final int CENTER = 0x19; privatE int offset = 0; //可超出其父控件的偏移量 protected Paint paint = new Paint(); private static final int touchdistance = 80; //触摸边界的有效距离 // 初始的两个手指按下的触摸点的距离 private float oridis = 1f; /** * 初始化获取屏幕宽高 */ protected voID initScreenW_H() { screenHeight = getresources().getdisplaymetrics().heightPixels - 40; screenWIDth = getresources().getdisplaymetrics().wIDthPixels; } public DragScaleVIEw(Context context,AttributeSet attrs,int defStylE) { super(context,attrs,defStylE); setontouchListener(this); initScreenW_H(); } public DragScaleVIEw(Context context,AttributeSet attrs) { super(context,attrs); setontouchListener(this); initScreenW_H(); } public DragScaleVIEw(Context context) { super(context); setontouchListener(this); initScreenW_H(); } @OverrIDe protected voID onDraw(Canvas canvas) { super.onDraw(canvas); paint.setcolor(color.GRAY); paint.setstrokeWIDth(4.0f); paint.setStyle(Paint.Style.strokE); } @OverrIDe public Boolean ontouch(VIEw v,MotionEvent event) { setBACkgroundresource(R.drawable.bg_dashgap); int action = event.getAction()& MotionEvent.ACTION_MASK; if (action == MotionEvent.ACTION_DOWN) { orileft = v.getleft(); oriRight = v.getright(); oritop = v.gettop(); oriBottom = v.getBottom(); lastY = (int) event.getRawY(); lastX = (int) event.getRawX(); dragDirection = getDirection(v,(int) event.getY()); } if (action == MotionEvent.ACTION_POINTER_DOWN){ orileft = v.getleft(); oriRight = v.getright(); oritop = v.gettop(); oriBottom = v.getBottom(); lastY = (int) event.getRawY(); lastX = (int) event.getRawX(); dragDirection = touch_TWO; oridis = distance(event); } // 处理拖动事件 delDrag(v,event,action); invalIDate(); return false; } /** * 处理拖动事件 * * @param v * @param event * @param action */ protected voID delDrag(VIEw v,MotionEvent event,int action) { switch (action) { case MotionEvent.ACTION_MOVE: int dx = (int) event.getRawX() - lastX; int dy = (int) event.getRawY() - lastY; switch (dragDirection) { case left: // 左边缘 left(v,dX); break; case RIGHT: // 右边缘 right(v,dX); break; case BottOM: // 下边缘 bottom(v,dy); break; case top: // 上边缘 top(v,dy); break; case CENTER: // 点击中心-->>移动 center(v,dx,dy); break; case lefT_BottOM: // 左下 left(v,dX); bottom(v,dy); break; case left_top: // 左上 left(v,dX); top(v,dy); break; case RIGHT_BottOM: // 右下 right(v,dy); break; case RIGHT_top: // 右上 right(v,dy); break; case touch_TWO: //双指操控 float newdist =distance(event); float scale = newdist / oridis; //控制双指缩放的敏感度 int distX = (int) (scale*(oriRight-orileft)-(oriRight-orileft))/50; int distY = (int) (scale*(oriBottom-oritop)-(oriBottom-oritop))/50; if (newdist>10f){//当双指的距离大于10时,开始相应处理 left(v,-distX); top(v,-distY); right(v,distX); bottom(v,distY); } break; } if (dragDirection != CENTER) { v.layout(orileft,oriBottom); } lastX = (int) event.getRawX(); lastY = (int) event.getRawY(); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: dragDirection = 0; break; } } /** * 触摸点为中心->>移动 * * @param v * @param dx * @param dy */ private voID center(VIEw v,int dx,int dy) { int left = v.getleft() + dx; int top = v.gettop() + dy; int right = v.getright() + dx; int bottom = v.getBottom() + dy; if (left < -offset) { left = -offset; right = left + v.getWIDth(); } if (right > screenWIDth + offset) { right = screenWIDth + offset; left = right - v.getWIDth(); } if (top < -offset) { top = -offset; bottom = top + v.getHeight(); } if (bottom > screenHeight + offset) { bottom = screenHeight + offset; top = bottom - v.getHeight(); } Log.d("raydrag",left+" "+top+" "+right+" "+bottom+" "+dX); v.layout(left,top,right,bottom); } /** * 触摸点为上边缘 * * @param v * @param dy */ private voID top(VIEw v,int dy) { oritop += dy; if (oritop < -offset) { //对vIEw边界的处理,如果子vIEw达到父控件的边界,offset代表允许超出父控件多少 oritop = -offset; } if (oriBottom - oritop - 2 * offset < 200) { oritop = oriBottom - 2 * offset - 200; } } /** * 触摸点为下边缘 * * @param v * @param dy */ private voID bottom(VIEw v,int dy) { oriBottom += dy; if (oriBottom > screenHeight + offset) { oriBottom = screenHeight + offset; } if (oriBottom - oritop - 2 * offset < 200) { oriBottom = 200 + oritop + 2 * offset; } } /** * 触摸点为右边缘 * * @param v * @param dx */ private voID right(VIEw v,int dX) { oriRight += dx; if (oriRight > screenWIDth + offset) { oriRight = screenWIDth + offset; } if (oriRight - orileft - 2 * offset < 200) { oriRight = orileft + 2 * offset + 200; } } /** * 触摸点为左边缘 * * @param v * @param dx */ private voID left(VIEw v,int dX) { orileft += dx; if (orileft < -offset) { orileft = -offset; } if (oriRight - orileft - 2 * offset < 200) { orileft = oriRight - 2 * offset - 200; } } /** * 获取触摸点flag * * @param v * @param x * @param y * @return */ protected int getDirection(VIEw v,int x,int y) { int left = v.getleft(); int right = v.getright(); int bottom = v.getBottom(); int top = v.gettop(); if (x < touchdistance && y < touchdistancE) { return left_top; } if (y < touchdistance && right - left - x < touchdistancE) { return RIGHT_top; } if (x < touchdistance && bottom - top - y < touchdistancE) { return lefT_BottOM; } if (right - left - x < touchdistance && bottom - top - y < touchdistancE) { return RIGHT_BottOM; } if (x < touchdistancE) { return left; } if (y < touchdistancE) { return top; } if (right - left - x < touchdistancE) { return RIGHT; } if (bottom - top - y < touchdistancE) { return BottOM; } return CENTER; } /** * 计算两个手指间的距离 * * @param event 触摸事件 * @return 放回两个手指之间的距离 */ private float distance(MotionEvent event) { float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); return (float) Math.sqrt(x * x + y * y);//两点间距离公式 } }
总结
以上所述是小编给大家介绍的AndroID控件的缩放移动功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!
以上是大佬教程为你收集整理的Android实现控件的缩放移动功能全部内容,希望文章能够帮你解决Android实现控件的缩放移动功能所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。