自定义可拖动GridView 仿android桌面launcher

本文介绍如何创建一个可拖动的GridView,模仿Android桌面启动器的效果。通过长按开始拖动,获取当前位置的item并隐藏,然后在窗口管理器中添加镜像视图,实时更新镜像位置,改变数据并通知适配器更新,最后显示新的位置并释放资源完成交换。
摘要由CSDN通过智能技术生成

思路:1、长按视为开始拖动,根据poionToPosition()获取当前点击的itemView,并隐藏
2、调用windowManager.addView()添加当前itemView的镜像
3、在onTouchEvent中获取手指移动的moveX,moveY,不断重绘镜像
4、在相应位置更改item数据,直接调用adapter.nodifyDataSetChanged();
5、显示当前位置的item,并释放镜像资源,完成交换

注意:
图中红色框为我们的GridView
1:mPoint2ItemTop点击坐标到该itemView的上边距
event.getX()-itemView.getLeft();

   2:mPoint2ItemLeft点击坐标到该itemView的左边距

event.getY()-itemView.getTop();

   3:mOffsetTop  GridView到屏幕上方的偏移值

event.getRawY()-event.getY();

mDownX - mPoint2ItemLeft + mOffsetLeft

   4:mOffsetLeftGridView到屏幕左边的偏移值

event.getRawX()-event.getX();

   5:mStartDownScrollHeight 滑动到该位置开始向下滚动

GridView.getHeight() / 4;

   6:mStartUpScrollHeight滑动到该位置开始向上滚动

GridView.getHeight() *3 /4;

这里写图片描述

GetRawX():相对于屏幕原点的X轴坐标
GetX():相对于父空间的X轴坐标
getLeft():相对于父控件坐标

注意:当listView或者GridView滚动之后,getChildAt()获取的子组件可能为空,
此方法为获取当前可视的视图,如果需要正确获取当前屏幕中显示的第几个控件需:
getChildAt(mDragPosition- getFirstVisiblePosition()

代码实现:

package com.example.draggridview;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.os.Handler;
import android.os.Vibrator;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.ImageView;

public class DragGridView extends GridView {
   

    private static final String TAG = "DragGridView";

    private static final int scrollSpeed = 20;
    /**
     * 长按视为拖动图标
     */
    private long dragRespondTime = 1000;

    /**
     * 手指按下的点坐标
     */
    private int mDownX, mDownY;

    /**
     * 手指移动的距离
     */
    private int moveX, moveY;

    /**
     * 手指按下坐标到该item的边缘偏移值
     */
    private int mPoint2ItemTop, mPoint2ItemLeft;

    /**
     * 开始自动滚动的高度
     */
    private int mStartUpScrollHeight, mStartDownScrollHeight;

    /**
     * 状态栏高度
     */
    private int mStatusHeight = 0;

    /**
     * 手指按下坐标到屏幕边框的偏移值
     */
    private int mOffsetTop, mOffsetLeft;

    /**
     * 手指按下的position
     */
    private int mDragPosition = 0;

    /**
     * 手指按下的view
     */
    private View mStartDragItemView;

    /**
     * 镜像view
     */
    private Bitmap mDragBitmap;

    /**
     * 镜像imageview组件
     */
    private ImageView mDragImageView;

    WindowManager.LayoutParams winLayoutParams;

    /**
     * 是否支持拖动界面
     */
    private boolean isDrag = false;

    OnItemChangerListener listener;

    /**
     * 震动
     */
    private Vibrator vibrator;

    private WindowManager windowManager;

    private Handler handler = new Handler();

    private Runnable dragRunnable = new Runnable() {

        @Override
        public void run() {
            isDrag = true;
            // 隐藏当前点击的item
            mStartDragItemView.setVisibility(View.INVISIBLE);
            // 震动
            vibrator.vibrate(50);
            // 生成镜像
            createDr
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值