转载请注明原创出处,谢谢!
- GitHub: @Ricco
最近在公司项目中,需要实现一个类似QQ空间发说说的功能,其中在照片处理功能中,有一个有意思的东西,花费了一点时间,所以写一篇笔记,记录一下。
功能需求,如下
- 照片之间可以互相[拖拽]换位置,点击删除按钮[删除]照片,单击照片[查看]照片
- 加号[固定]在最后一个位置,点击加号[打开]图片浏览,选择更多图片,
主要功能,照片直接可以拖拽,最后一个加号不能拖拽,网上大多数的例子,虽然实现了最后一个不能拖拽,但是当把其他item拖拽到最后一个加号的位置,加号的位置会有被移动到其他位置。也就是所,并没有真正的固定加号(最后一个item)
项目基于BRVAH(万能适配器),只是为了简化Adapter,如果你使用官方原生的Adapter,可以下载搜索ItemTouchHelper,看看具体使用方法
看懂这篇文档,你只是要了解RecyclerView,ItemTouchHelper
BRVAH(万能适配器)
compile 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.33'
直接上代码,如果有需求可以直接CV代码
MainActivity
public class MainActivity extends BaseActivity {
private static final String TAG = ItemDragAndSwipeUseActivity.class.getSimpleName();
private RecyclerView mRecyclerView;
private List<String> mData;
private ItemDragAdapter mAdapter; // BRVAH Demo,没有做任何修改
private ItemTouchHelper mItemTouchHelper; // BRVAH Demo,没有做任何修改
private ItemDragAndSwipeCallback mItemDragAndSwipeCallback; // BRVAH Demo,没有做任何修改
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_item_touch_use);
mRecyclerView = findViewById(R.id.rv_list);
mRecyclerView.setLayoutManager(new GridLayoutManager(this, 3));
mData = getData(50);
mAdapter = new ItemDragAdapter(mData);
mRecyclerView.setAdapter(mAdapter);
// 实现开始
mItemDragAndSwipeCallback = new ItemDragAndSwipeCallback(mAdapter) {
/**
* 用来判断 target是否可以被替换位置
* @return false 不可以被替换位置
*/
@Override
public boolean canDropOver(RecyclerView recyclerView, RecyclerView.ViewHolder current, RecyclerView.ViewHolder target) {
// 最后一个为加号,所以不支持【拖拽换位置】
return target.getAdapterPosition() != recyclerView.getAdapter().getItemCount() - 1 && super.canDropOver(recyclerView, current, target);
}
};
mItemTouchHelper = new ItemTouchHelper(mItemDragAndSwipeCallback);
mItemTouchHelper.attachToRecyclerView(mRecyclerView); // 附加到RecyclerView
// 如果自己写Callback,请确保** ItemDragAndSwipeCallback.isLongPressDragEnabled返回false **
// mAdapter.enableDragItem(mItemTouchHelper); // 启用拖拽,有这行代码,mAdapter的上按监听无效
// 如果你不需要对最后一张图片做特殊处理,只需要去掉注释,删除canDropOver和startDrag就可以了
// 长按事件
mAdapter.setOnItemLongClickListener(new BaseQuickAdapter.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(BaseQuickAdapter adapter, View view, int position) {
// 如果item不是最后一个,则可以拖拽【不是加号,可以拖拽】
if (position != adapter.getData().size() - 1) {
mItemTouchHelper.startDrag(mRecyclerView.getChildViewHolder(view));
}
Log.i(TAG, "onItemLongClick: " + position);
return false;
}
});
// 点击事件
mAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
@Override
public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
// 如果item是最后一个【加号点击事件】
if (position == adapter.getData().size() - 1) {
Log.i(TAG, "onItemChildClick: " + position);
}
}
});
}
// 加数据[现实中是图片地址]
private List<String> getData(int size) {
ArrayList<String> data = new ArrayList<>(size);
for (int i = 0; i < size; i++) {
data.add("item " + i);
}
return data;
}
}