Android实现跟随手指拖动并自动贴边的View样式(实例demo)

发布时间 - 2026-01-10 22:30:38    点击率:

效果图

代码

/**
 * 根据手指拖动的当前位置,自动贴边的View
 */
public class DragView extends ImageView implements View.OnTouchListener{
 private int screenWidth;
 private int screenHeight;
 private Context mContext;
 private int lastX, lastY;
 private int left ,top;
 private ViewGroup.MarginLayoutParams layoutParams;
 private int startX;
 private int endX;
 private boolean isMoved = false;
 private onDragViewClickListener mLister;
 public interface onDragViewClickListener{
  void onDragViewClick();
 }
 public void setOnDragViewClickListener(onDragViewClickListener listener){
  this.mLister = listener;
 }
 public DragView(Context context) {
  this(context,null);
 }
 public DragView(Context context, AttributeSet attrs) {
  super(context, attrs);
  mContext = context;
  DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
  screenWidth = displayMetrics.widthPixels;
  screenHeight = displayMetrics.heightPixels-getStatusBarHeight();
  init();
 }
 public void init(){
  setOnTouchListener(this);
  post(new Runnable() {
   @Override
   public void run() {
    layoutParams = (ViewGroup.MarginLayoutParams)getLayoutParams();
    layoutParams.topMargin = screenHeight - getHeight();
    layoutParams.leftMargin = screenWidth - getWidth();
    setLayoutParams(layoutParams);
   }
  });
 }
 @Override
 public boolean onTouch(View v, MotionEvent event) {
  switch (event.getAction()) {
   case MotionEvent.ACTION_DOWN:
    lastX = (int) event.getRawX();
    lastY = (int) event.getRawY();
    startX = lastX;
    break;
   case MotionEvent.ACTION_MOVE:
    isMoved = true;
    int dx = (int) event.getRawX() - lastX;
    int dy = (int) event.getRawY() - lastY;
    left = v.getLeft() + dx;
    top = v.getTop() + dy;
    int right = v.getRight() + dx;
    int bottom = v.getBottom() + dy;
    // 设置不能出界
    if (left < 0) {
     left = 0;
     right = left + v.getWidth();
    }
    if (right > screenWidth) {
     right = screenWidth;
     left = right - v.getWidth();
    }
    if (top < 0) {
     top = 0;
     bottom = top + v.getHeight();
    }
    if (bottom > screenHeight) {
     bottom = screenHeight;
     top = bottom - v.getHeight();
    }
    v.layout(left, top, right, bottom );
    lastX = (int) event.getRawX();
    lastY = (int) event.getRawY();
    break;
   case MotionEvent.ACTION_UP:
    //只有滑动改变上边距时,抬起才进行设置
    if (isMoved) {
     layoutParams = (ViewGroup.MarginLayoutParams)getLayoutParams();
     layoutParams.topMargin = top;
     setLayoutParams(layoutParams);
    }
    endX = (int) event.getRawX();
    //滑动距离比较小,当作点击事件处理
    if (Math.abs(startX - endX) < 6) {
     return false;
    }
    if (left +v.getWidth()/2 < screenWidth/2) {
     startScroll(left,screenWidth/2,true);
    } else {
     startScroll(left,screenWidth/2,false);
    }
    break;
  }
  return true;
}
 //在此处理点击事件
 @Override
 public boolean onTouchEvent(MotionEvent event) {
  mLister.onDragViewClick();
  return super.onTouchEvent(event);
 }
 public void startScroll(final int start, int end, final boolean isLeft){
  ValueAnimator valueAnimator = ValueAnimator.ofFloat(start,end).setDuration(800);
  valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
   @Override
   public void onAnimationUpdate(ValueAnimator animation) {
    if (isLeft) {
     layoutParams.leftMargin = (int) (start*(1-animation.getAnimatedFraction()));
    } else {
     layoutParams.leftMargin = (int) (start + (screenWidth - start - getWidth())*(animation.getAnimatedFraction()));
    }
    setLayoutParams(layoutParams);
   }
  });
  valueAnimator.start();
 }
 /**
  * 获取状态栏的高度
  * @return 状态栏高度
  */
 public int getStatusBarHeight() {
  int result = 0;
  int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
  if (resourceId > 0) {
   result = getResources().getDimensionPixelSize(resourceId);
  }
  return result;
 }
}

以上所述是小编给大家介绍的Android实现跟随手指拖动并自动贴边的View样式,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


# android  # 手指拖动view  # view跟随手指  # 使用PlatformView将 Android 控件view制作成Flutter插件  # Android开发自定义实时图表控件实现示例  # Android开发手册TextView控件及阴影效果实现  # Android开发手册自定义Switch开关按钮控件  # Android开发自定义双向SeekBar拖动条控件  # Android开发手册RatingBar星级评分控件实例  # Android 控件自动贴边实现实例详解  # 在此  # 拖动  # 小编  # 状态栏  # 给大家  # 较小  # 所述  # 给我留言  # 感谢大家  # 疑问请  # 有任何  # mLister  # setOnDragViewClickListener  # listener  # onDragViewClick  # interface  # void  # endX  # startX  # layoutParams 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Win11怎么关闭专注助手 Win11关闭免打扰模式设置【操作】  Laravel如何操作JSON类型的数据库字段?(Eloquent示例)  实例解析Array和String方法  php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】  如何在IIS7上新建站点并设置安全权限?  Laravel N+1查询问题如何解决_Eloquent预加载(Eager Loading)优化数据库查询  Laravel路由Route怎么设置_Laravel基础路由定义与参数传递规则【详解】  详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)  Mybatis 中的insertOrUpdate操作  移动端手机网站制作软件,掌上时代,移动端网站的谷歌SEO该如何做?  如何在Tomcat中配置并部署网站项目?  Windows家庭版如何开启组策略(gpedit.msc)?(安装方法)  如何彻底删除建站之星生成的Banner?  七夕网站制作视频,七夕大促活动怎么报名?  ChatGPT怎么生成Excel公式_ChatGPT公式生成方法【指南】  如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?  邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?  在Oracle关闭情况下如何修改spfile的参数  JS去除重复并统计数量的实现方法  Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】  EditPlus中的正则表达式实战(6)  Laravel项目怎么部署到Linux_Laravel Nginx配置详解  网站制作大概要多少钱一个,做一个平台网站大概多少钱?  百度浏览器网页无法复制文字怎么办 百度浏览器复制修复  Laravel如何集成Inertia.js与Vue/React?(安装配置)  原生JS实现图片轮播切换效果  实现点击下箭头变上箭头来回切换的两种方法【推荐】  Laravel如何与Pusher实现实时通信?(WebSocket示例)  Java解压缩zip - 解压缩多个文件或文件夹实例  网站制作公司哪里好做,成都网站制作公司哪家做得比较好,更正规?  网易LOFTER官网链接 老福特网页版登录地址  如何构建满足综合性能需求的优质建站方案?  大连网站制作公司哪家好一点,大连买房网站哪个好?  Java类加载基本过程详细介绍  Windows11怎样设置电源计划_Windows11电源计划调整攻略【指南】  如何用AI帮你把自己的生活经历写成一个有趣的故事?  如何用ChatGPT准备面试 模拟面试问答与职场话术练习教程  如何打造高效商业网站?建站目的决定转化率  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  Laravel如何实现全文搜索_Laravel Scout集成Algolia或Meilisearch教程  如何用PHP工具快速搭建高效网站?  laravel怎么通过契约(Contracts)编程_laravel契约(Contracts)编程方法  PHP 500报错的快速解决方法  如何快速搭建高效服务器建站系统?  Win11怎么更改系统语言为中文_Windows11安装语言包并设为显示语言  Laravel如何创建和注册中间件_Laravel中间件编写与应用流程  Laravel中的Facade(门面)到底是什么原理  如何快速搭建高效香港服务器网站?  php后缀怎么变mp4格式错误_修改扩展名提示格式不对怎么办【技巧】  详解CentOS6.5 安装 MySQL5.1.71的方法