先上效果
流畅效果超越了网易新闻和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(...);
注意
- 不能给DragSortGridView设置padding,但是可以用margin,不能使用横竖间隙,要item之间的间距只能在adapter生成item里面设置padding
- 必须做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 =