欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2022-04-09 13:42:40
项目过程中要实现能在页面中随意的拖动,刚开始实现是用悬浮球的形式进行实现,因为之前项目中用过,实现后发现用户每次安装后,都有权限的限制,甚至有些用户关闭悬浮球权限之后,不知...

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

自定义随意拖动view:

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;
  }
}

用到的工具类:

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文件:

<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:

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效果的实例代码,希望对大家有所帮助