zoukankan      html  css  js  c++  java
  • View拖拽 自定义绑定view拖拽的工具类

    由于工作需求,需要用到这种处理方法所以我就写了这个

    废话不多说先看效果图

    接下来就看代码吧 DragDropManager

    import android.app.Activity;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.PixelFormat;
    import android.util.Log;
    import android.view.Gravity;
    import android.view.MotionEvent;
    import android.view.View;
    import android.view.ViewGroup;
    import android.view.WindowManager;
    import android.widget.ImageView;
    import android.widget.TextView;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    /**
     * 拖拽工具类
     */
    public class DragDropManager implements View.OnTouchListener {
    
        /**
         * View 集合
         */
        private List<View> viewList;
    
        private static Activity mActivity;
        private static DragDropManager mManager;
    
        private Map<View, ViewInfo> mViewMap;
    
        /**
         * 窗口管理器,用于显示条目的快照
         */
        private WindowManager mWindowManager;
    
        /**
         * 窗口管理的布局参数
         */
        private WindowManager.LayoutParams mWindowLayoutParams;
    
        /**
         * 悬浮的imageView
         */
        private ImageView mDragPhotoView;
        private Bitmap mDragPhotoBitmap;
        private float moveX;
        private float moveY;
    
        private IDragDropListener listener;
    
        public DragDropManager() {
            viewList = new ArrayList<>();
            mViewMap = new HashMap<>();
        }
    
        public static DragDropManager getInstance(Activity activity) {
            mActivity = activity;
            if (mManager == null) {
                mManager = new DragDropManager();
            }
            return mManager;
        }
    
        /**
         * 绑定view
         */
        public void bindView(View... views) {
            viewList.clear();
            for (View view : views) {
                view.setOnTouchListener(this);
                if(view instanceof TextView){
                    view.setOnClickListener(null);
                }else if(view instanceof ViewGroup){
                    view.setOnClickListener(null);
                }
                viewList.add(view);
            }
        }
    
        /**
         * 添加view
         *
         * @param views
         */
        public void addView(View... views) {
            for (View view : views) {
                view.setOnTouchListener(this);
                viewList.add(view);
            }
        }
    
        /**
         * 设置监听事件
         * @param listener
         */
        public void setListener(IDragDropListener listener){
            this.listener = listener;
        }
    
        @Override
        public boolean onTouch(View view, MotionEvent event) {
    
            int action = event.getAction();
            switch (action) {
                case MotionEvent.ACTION_DOWN:
                    Log.i("tag", "生成图像");
                    //首先初始化每个控件的坐标信息
                    initViewLayout();
                    //判断出点击的是哪个控件 并悬浮出哪个控件
                    createDragPhotoView(view);
                    moveX = event.getX();
                    moveY = event.getY();
                    //回调监听
                    if(listener != null){
                        listener.startDragDrop(view.getId());
                    }
                    break;
                case MotionEvent.ACTION_MOVE:
                    mWindowLayoutParams.x = (int) (mViewMap.get(view).x + (event.getX() - moveX));
                    mWindowLayoutParams.y = (int) (mViewMap.get(view).y + (event.getY() - moveY));
                    mWindowManager.updateViewLayout(mDragPhotoView, mWindowLayoutParams);
                    Log.i("tag", "移动图像 x:"+(view.getX() + (event.getX() - moveX))+"  y:" + (view.getY() + (event.getY() - moveY)));
                    break;
                case MotionEvent.ACTION_UP:
                    Log.i("tag", "去掉图像");
    
                    //
                    if(listener != null) {
                        for (View tempView : viewList) {
                            if (tempView.getId() != view.getId()) {
                                ViewInfo viewInfo = mViewMap.get(tempView);
                                if (event.getRawX() > viewInfo.x && event.getRawY() > viewInfo.y
                                        && event.getRawX() < (viewInfo.x + viewInfo.width) && event.getRawY() < (viewInfo.y + viewInfo.height)) {
                                    listener.endDragDrop(view.getId(),tempView.getId());
                                    break;
                                }
                            }
                        }
                    }
    
                    // 移除快照
                    if (mDragPhotoView != null) {
                        mWindowManager.removeView(mDragPhotoView);
                        mDragPhotoView.setImageDrawable(null);
                        mDragPhotoBitmap.recycle();
                        mDragPhotoBitmap = null;
                        mDragPhotoView = null;
                    }
                    break;
            }
            return false;
        }
    
        /**
         * 初始化每个控件的坐标信息
         */
        private void initViewLayout() {
            mViewMap.clear();
            int[] location = new int[2];
            for (View view : viewList) {
                view.getLocationInWindow(location);
                ViewInfo viewInfo = new ViewInfo(view, location[0], location[1], view.getMeasuredHeight(), view.getMeasuredWidth());
                mViewMap.put(view, viewInfo);
            }
        }
    
        /**
         * 创建拖拽快照
         */
        private void createDragPhotoView(View view) {
            // 进行绘图缓存
            view.setDrawingCacheEnabled(true);
            // 提取缓存中的图片
            mDragPhotoBitmap = Bitmap.createBitmap(view.getDrawingCache());
            // 获取当前窗口管理器
            mWindowManager = (WindowManager) mActivity.getSystemService(Context.WINDOW_SERVICE);
            // 创建布局参数
            mWindowLayoutParams = new WindowManager.LayoutParams();
            mWindowLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
            mWindowLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
            mWindowLayoutParams.gravity = Gravity.TOP | Gravity.START;
            mWindowLayoutParams.format = PixelFormat.TRANSLUCENT; // 期望的图片为半透明效果,但设置其他值并没有看到不一样的效果
            // 下面这些参数能够帮助准确定位到选中项点击位置
            mWindowLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                    | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
                    | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
                    | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
            mWindowLayoutParams.windowAnimations = 0; // 无动画
            mWindowLayoutParams.alpha = 0.6f; // 微透明
    
            mWindowLayoutParams.x = (int) mViewMap.get(view).x;
            mWindowLayoutParams.y = (int) mViewMap.get(view).y;
            mDragPhotoView = new ImageView(mActivity);
            mDragPhotoView.setImageBitmap(mDragPhotoBitmap);
            mWindowManager.addView(mDragPhotoView, mWindowLayoutParams);
        }
    
    
        /**
         * 监听接口
         */
        public interface IDragDropListener{
    
            /**
             * 开始拖动
             * @param startViewId 返回当前view的ID
             */
            void startDragDrop(int startViewId);
    
    
            /**
             * 结束拖动
             * @param startViewId 返回当前view的ID
             * @param endViewId 返回覆盖在某个view的ID
             */
            void endDragDrop(int startViewId,int endViewId);
        }
    
        /**
         * 记录当前view的坐标和宽高信息
         */
        class ViewInfo {
    
            private View view;
            private float x;
            private float y;
            private float height;
            private float width;
    
            public ViewInfo(View view, float x, float y, float height, float width) {
                this.view = view;
                this.x = x;
                this.y = y;
                this.height = height;
                this.width = width;
            }
        }
    }

    使用方法

    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    import android.widget.Toast;
    
    public class MainActivity extends AppCompatActivity {
    
    
        private DragDropManager dragDropManager;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            TextView textView = findViewById(R.id.tvTitle);
            TextView tegg = findViewById(R.id.tvTitlegg);
            Button btnTuo = findViewById(R.id.btnTuo);
            dragDropManager = DragDropManager.getInstance(this);
            dragDropManager.bindView(textView,btnTuo,tegg);
            dragDropManager.setListener(new DragDropManager.IDragDropListener() {
                @Override
                public void startDragDrop(int startViewId) {
                    Toast.makeText(MainActivity.this,"开始悬浮",0).show();
                }
    
                @Override
                public void endDragDrop(int startViewId, int endViewId) {
                    Toast.makeText(MainActivity.this,"开始悬浮 sID:" + startViewId + "//endID : " + endViewId,0).show();
                }
            });
    
            textView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(MainActivity.this,"text dianji",0).show();
                }
            });
            btnTuo.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Toast.makeText(MainActivity.this,"btnTuo dianji",0).show();
                }
            });
        }
    }

    代码demo
    demo下载

    参考博客:https://blog.csdn.net/a10615/article/details/51366459

  • 相关阅读:
    useState回调函数
    Ahook
    我的创业和职业观点
    一个超级工业软件的能力在哪
    【542】Mac上面修改jupyter notebook默认打开页面
    【541】shapely 相关功能
    【540】时间戳数字转换为格式化时间
    【539】地球两点距离以及面积计算
    【538】二维数据实现随机采样
    新春首发!Spring Boot 2 个新版本...
  • 原文地址:https://www.cnblogs.com/woaixingxing/p/8986790.html
Copyright © 2011-2022 走看看