一个流畅的拖动排序DragSortGridView,自动滚屏

先上效果

这里写图片描述

流畅效果超越了网易新闻和UC浏览器的栏目收藏.gif图和实际效果有差距

1.拖拽可以移动item,并且其他item会立即自动补位,快速拖拽也非常流畅
2.item太多时,拖拽到边缘时会自动滚屏.
3.可以自定义被拖拽的的View放大,添加阴影等效果
4.长按启动删除模式,需要自己实现item的删除按钮展示,自己管理删除模式的切换
5.可以放在ScrollView中拖动排序,需要ScrollView继承ListenScrollView,不影响外面控件的大部分事件.
6.可以长按启动item拖拽,也可以触摸直接开始拖动

简单使用方法

        dragSortGridView = (DragSortGridView) findViewById(R.id.dragSort1);
        //长按item响应该item的拖动排序,默认是触摸就开始拖动
        dragSortGridView.setDragModel(DragSortGridView.DRAG_BY_LONG_CLICK);
        dragAdapter = new MyAdapter();
        dragSortGridView.setAdapter(dragAdapter);

dragAdapter 需要多实现onDataModelMove一个方法,界面排序改变需要提供真实数据排序改变.示例

class MyAdapter extends DragAdapter {
        @Override
        public void onDataModelMove(int from, int to) {
            String s = list.remove(from);
            list.add(to, s);
        }

        @Override
        public int getCount() {
            return list.size();
        }

        @Override
        public String getItem(int position) {
            return list.get(position);
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView textView;
            if (convertView == null) {
                FrameLayout frameLayout = new FrameLayout(SecondActivity.this);
                convertView = frameLayout;
                textView = new TextView(SecondActivity.this);
                frameLayout.setPadding(20, 20, 20, 20);
                textView.setPadding(20, 100, 20, 100);
                frameLayout.addView(textView);
                textView.setBackgroundColor(0x33ff00ff);
                textView.setGravity(Gravity.CENTER);
            } else {
                textView = (TextView) ((FrameLayout) convertView).getChildAt(0);
            }
            textView.setText(getItem(position));
            return convertView;
        }
    }

扩展可以改变的功能

            //设置每行个数
        dragSortGridView.setNumColumns(4);

            /*改变拖动item所在动画层,例如frameLayout是位于最上册的全屏透明层,
            则item拖拽可以在全屏范围内,超出dragSortGridView本身范围,
            这个一般用来配合外层是ListenScrollView用*/
        dragSortGridView.setAnimFrame(frameLayout);

            //设置前面多少个位置固定,不能拖动
        dragSortGridView.setNoPositionChangeItemCount(2);
            //设置尾部多少个位置固定,不能拖动
        dragSortGridView.setFootNoPositionChangeItemCount(1);
            //修改item响应拖动时的效果,默认是放大到120%
        dragSortGridView.setOnDragSelectListener(new DragSortGridView.OnDragSelectListener() {
            @Override
            public void onDragSelect(View mirror) {
                //当item开始拖动时调用该方法
            }

            @Override
            public void onPutDown(View itemView) {
                //当item被放时是调用该方法
            }
        });
        //修改长按拖动的响应时间
        dragSortGridView.setDragLongPressTime(1500);

        dragSortGridView.setOnItemClickListener(...);
        dragSortGridView.setOnLongClickListener(...);

注意

  1. 不能给DragSortGridView设置padding,但是可以用margin,不能使用横竖间隙,要item之间的间距只能在adapter生成item里面设置padding
  2. 必须做contentView的复用,不做则不流畅.

下面是源码
有一个R.id.first,需要在values的ids.xml里面添加

<item name="first" type="id" />


/**
 * Copyright (C), 2008-2015, Huawei Tech. Co., Ltd.
 * <p/>
 * Description : 拖动排序布局
 *
 * @version V100R001
 * @since V100R001
 */
@SuppressLint({ "NewApi", "Override" })
public class DragSortGridView extends FrameLayout {
    
    protected NoScrollGridView mGridView;
    private ScrollView mScrollView;
    private int headDragPosition = 0;
    private int footDragPosition = 0;
    private FrameLayout mDragFrame;
    private View mCopyView, hideView;
    private GestureDetector detector;
    /** 动画时间 */
    private static final long ANIM_DURING = 250;
    protected int mNumColumns = 3, mColHeight = 0, mColWidth = 0, mChildCount = 0, mMaxHeight = 0;
    private int currentDragPosition = -1;
    private DragAdapter adapter;
    /** 持有子view */
    private List<View> mChilds = new ArrayList<View>();
    private static final int TAG_KEY = R.id.first;
    // private static final int TAG_KEY = R.id.tag_key;
    private int mCurrentY = 0;
    /**
     * 触摸区域,0不滚动区域,1可向上滚动的区域,-1可向下滚动的区域
     */
    private int mTouchArea = 0;
    /**
     * gridview能否滚动,是否内容太多
     */
    private boolean canScroll = true;
    /**
     * 是否可以拖动,点击拖动策略下直接开启,长按拖动需要长按以后开启
     */
    private boolean isDragable = true;
    /**
     * 自动滚屏的动画
     */
    private ValueAnimator animator;
    /**
     * view是否加载完成,如果未加载完成,没有宽高,无法接受事件
     */
    private boolean isViewInitDone = false;

    /** 是否有位置发生改变,否则不用重绘 */
    private boolean hasPositionChange = 
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值