服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Android - Android实现随意拖动View效果的实例代码

Android实现随意拖动View效果的实例代码

2022-10-25 14:55龙旋 Android

这篇文章主要介绍了Android实现随意拖动View效果,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

项目过程中要实现能在页面中随意的拖动,刚开始实现是用悬浮球的形式进行实现,因为之前项目中用过,实现后发现用户每次安装后,都有权限的限制,甚至有些用户关闭悬浮球权限之后,不知道怎么在手机上打开悬浮球的权限,这样的话用户体验很不好,所以自己重新自定义实现在页面中拖动,不需要请求权限。

自定义随意拖动View:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package com.dragdemo;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.widget.ImageView;
/**
 *随意拖动的view
 */
@SuppressLint("AppCompatCustomView")
public class DragView extends ImageView {
  private int width;
  private int height;
  private int screenWidth;
  private int screenHeight;
  private Context context;
  //是否拖动
  private boolean isDrag=false;
  public boolean isDrag() {
    return isDrag;
  }
  public DragView(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.context=context;
  }
  @Override
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    width=getMeasuredWidth();
    height=getMeasuredHeight();
    screenWidth= ScreenUtil.getScreenWidth(context);
    screenHeight=ScreenUtil.getScreenHeight(context)-getStatusBarHeight();
  }
  public int getStatusBarHeight(){
    int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
    return getResources().getDimensionPixelSize(resourceId);
  }
  private float downX;
  private float downY;
  @Override
  public boolean onTouchEvent(MotionEvent event) {
    super.onTouchEvent(event);
    if (this.isEnabled()) {
      switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
          isDrag=false;
          downX = event.getX();
          downY = event.getY();
          break;
        case MotionEvent.ACTION_MOVE:
          Log.e("kid","ACTION_MOVE");
          final float xDistance = event.getX() - downX;
          final float yDistance = event.getY() - downY;
          int l,r,t,b;
          //当水平或者垂直滑动距离大于10,才算拖动事件
          if (Math.abs(xDistance) >10 ||Math.abs(yDistance)>10) {
            Log.e("kid","Drag");
            isDrag=true;
             l = (int) (getLeft() + xDistance);
             r = l+width;
             t = (int) (getTop() + yDistance);
             b = t+height;
            //不划出边界判断,此处应按照项目实际情况,因为本项目需求移动的位置是手机全屏,
            // 所以才能这么写,如果是固定区域,要得到父控件的宽高位置后再做处理
            if(l<0){
              l=0;
              r=l+width;
            }else if(r>screenWidth){
              r=screenWidth;
              l=r-width;
            }
            if(t<0){
              t=0;
              b=t+height;
            }else if(b>screenHeight){
              b=screenHeight;
              t=b-height;
            }
            this.layout(l, t, r, b);
          }
          break;
        case MotionEvent.ACTION_UP:
          setPressed(false);
          break;
        case MotionEvent.ACTION_CANCEL:
          setPressed(false);
          break;
      }
      return true;
    }
    return false;
  }
}

用到的工具类:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
package com.dragdemo;
import android.content.Context;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
public class ScreenUtil {
  private static int width = 0;
  private static int height = 0;
  private static int showHeight = 0;
  private static int statusHeight = 0;
  private static float density = 0;
  public static int getScreenWidth(Context context) {
    if (width == 0) {
      WindowManager manager = (WindowManager) context
          .getSystemService(Context.WINDOW_SERVICE);
      Display display = manager.getDefaultDisplay();
      width = display.getWidth();
    }
    return width;
  }
  public static int getScreenHeight(Context context) {
    if (height == 0) {
      WindowManager manager = (WindowManager) context
          .getSystemService(Context.WINDOW_SERVICE);
      Display display = manager.getDefaultDisplay();
      height = display.getHeight();
    }
    return height;
  }
  public static int getScreenShowHeight(Context context) {
    if (showHeight == 0) {
      showHeight = getScreenHeight(context) - getStatusBarHeight(context);
    }
    return showHeight;
  }
  public static int getStatusBarHeight(Context context) {
    if (statusHeight > 0) {
      return statusHeight;
    }
    Class<?> c = null;
    Object obj = null;
    java.lang.reflect.Field field = null;
    int x = 0;
    try {
      c = Class.forName("com.android.internal.R$dimen");
      obj = c.newInstance();
      field = c.getField("status_bar_height");
      x = Integer.parseInt(field.get(obj).toString());
      statusHeight = context.getResources().getDimensionPixelSize(x);
      return statusHeight;
    } catch (Throwable e) {
      e.printStackTrace();
    }
    return statusHeight;
  }
  public static float getScreenDensity(Context context) {
    if (density == 0) {
      try {
        DisplayMetrics dm = new DisplayMetrics();
        WindowManager manager = (WindowManager) context
            .getSystemService(Context.WINDOW_SERVICE);
        manager.getDefaultDisplay().getMetrics(dm);
        density = dm.density;
      } catch (Exception ex) {
        ex.printStackTrace();
        density = 1.0f;
      }
    }
    return density;
  }
  public static float getScreentMinLength(Context context) {
    return getScreenHeight(context) > getScreenWidth(context) ? getScreenWidth(context)
        : getScreenHeight(context);
  }
  /**
   * 根据指定k的系数获取屏幕在max范围内的最大长宽,默认宽比较小
   *
   * @param context
   * @param k
   * @return
   */
  public static DrawWrap getCutWrap(Context context, float k, float max) {
    float tWidth = getScreenWidth(context);
    float tHeight = getScreenHeight(context);
    if (tWidth * max * k > tHeight) {
      return new DrawWrap(tHeight * max / k, tHeight * max);
    } else {
      return new DrawWrap(tWidth * max, tWidth * max * k);
    }
  }
  public static class DrawWrap {
    public float width;
    public float height;
    public DrawWrap(float width, float height) {
      this.width = width;
      this.height = height;
    }
  }
  public static int dip2px(Context context, float dipValue) {
    return (int) (dipValue * getScreenDensity(context) + 0.5f);
  }
  /**
   * 将sp值转换为px值,保证文字大小不变
   *
   * @param context
   * @param spValue
   *      (DisplayMetrics类中属性scaledDensity)
   * @return
   */
  public static int sp2px(Context context, float spValue) {
    final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
    return (int) (spValue * fontScale + 0.5f);
  }
  /**
   * 根据手机的分辨率从 px(像素) 的单位 转成为 dp
   */
  public static int px2dip(Context context, float pxValue) {
    final float scale = context.getResources().getDisplayMetrics().density;
    return (int) (pxValue / scale + 0.5f);
  }
  /**
   * 获取屏幕中控件顶部位置的高度--即控件顶部的Y点
   *
   * @return
   */
  public static int getScreenViewTopHeight(View view) {
    return view.getTop();
  }
  /**
   * 获取屏幕中控件底部位置的高度--即控件底部的Y点
   *
   * @return
   */
  public static int getScreenViewBottomHeight(View view) {
    return view.getBottom();
  }
  /**
   * 获取屏幕中控件左侧的位置--即控件左侧的X点
   *
   * @return
   */
  public static int getScreenViewLeftHeight(View view) {
    return view.getLeft();
  }
  /**
   * 获取屏幕中控件右侧的位置--即控件右侧的X点
   *
   * @return
   */
  public static int getScreenViewRightHeight(View view) {
    return view.getRight();
  }
  /*
   * 获取控件宽
   */
  public static int getWidth(View view) {
    int w = View.MeasureSpec.makeMeasureSpec(0,
        View.MeasureSpec.UNSPECIFIED);
    int h = View.MeasureSpec.makeMeasureSpec(0,
        View.MeasureSpec.UNSPECIFIED);
    view.measure(w, h);
    return (view.getMeasuredWidth());
  }
  /*
   * 获取控件高
   */
  public static int getHeight(View view) {
    int w = View.MeasureSpec.makeMeasureSpec(0,
        View.MeasureSpec.UNSPECIFIED);
    int h = View.MeasureSpec.makeMeasureSpec(0,
        View.MeasureSpec.UNSPECIFIED);
    view.measure(w, h);
    return (view.getMeasuredHeight());
  }
}

XML文件:

?
1
2
3
4
5
6
7
<com.dragdemo.DragView
    android:id="@+id/iv_drag"
    android:layout_gravity="center"
    android:src="@drawable/function_night_open"
    android:layout_width="80dp"
    android:layout_height="80dp"
    />

MainActivity:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.dragdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
  DragView iv_drag;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    iv_drag= (DragView) findViewById(R.id.iv_drag);
    iv_drag.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        if(!iv_drag.isDrag()){
          Toast.makeText(MainActivity.this, "响应点击", Toast.LENGTH_SHORT).show();
        }
      }
    });
  }
}

总结

以上所述是小编给大家介绍的Android实现随意拖动View效果的实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

原文链接:https://segmentfault.com/a/1190000019808180

延伸 · 阅读

精彩推荐