前几天捣鼓了一下分割线,今天来看看RecyclerView的交互吧,RecyclerView的交互离不开ItemTouchHelp这个类直接进入正题
首先导入依赖库
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
testCompile 'junit:junit:4.12'
compile 'com.android.support:design:25.0.0'
compile 'com.android.support:recyclerview-v7:25.0.0'
compile 'com.android.support:appcompat-v7:25.0.0'
}
在MainActivity中完成RecyclerView的设置和数据的初始化
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getData();
recyclerView = findViewById(R.id.rv);
recyclerView.setLayoutManager(new LinearLayoutManager(MainActivity.this));
adapter = new RecyclerViewAdapter(datas,this);
recyclerView.setAdapter(adapter);
//条目帮助类
itemTouchHelper = new ItemTouchHelper(new MyItemTouchHelpCallBack(this));
itemTouchHelper.attachToRecyclerView(recyclerView);
}
private void getData() {
datas = new ArrayList<>();
for(int i=0;i<20;i++) {
datas.add("lkadsjfasdfsadfsa " + i);
}
}
这里我们自定义一个MyItemTouchHelpCallBack 继承 CallBack并实现它的方法
//callback回调监听时先调用这个方法,判断当前是什么动作,例如判断当前动作的方向
@Override
public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
//方向有up down left right
int up = ItemTouchHelper.UP;//0x0001
int down = ItemTouchHelper.DOWN;//0x0010
int left = ItemTouchHelper.LEFT;//0x0100
int right = ItemTouchHelper.RIGHT;//0x1000
//如果只判断上下方向就应该返回0x0011 up|down
//同理只判断左右方向就应该返回0x1100 left|right
//那系统怎么判断呢?比如用0x0011 & 0x0001 = 0x0001 0x0011 & 0x0010 = 0x0010 这样就判断出上下方向了
//源码这里也提供了方法很方便,上面解释方便理解
//监听上下方向的拖拽
int dragFlags = up | down;
//监听左右方向的滑动
int swipeFlags = left | right;
int flags = makeMovementFlags(dragFlags, swipeFlags);
return flags;
}
//拖拽移动
@Override
public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder srcHold, RecyclerView.ViewHolder targetHold) {
//在此方法中不停调用adapter.notifyItemChanged方法刷新recyclerview中的数据
if (srcHold.getItemViewType() != targetHold.getItemViewType()) {
return false;
}
itemMoveListener.onItemMove(srcHold.getAdapterPosition(),targetHold.getAdapterPosition());
return false;
}
//侧滑 滑动
@Override
public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
//监听侧滑1.调用adapter.notifyRemove
itemMoveListener.onItemRemove(viewHolder.getAdapterPosition());
}
效果如下图
图中有一些动画效果不透明,同样可以做一些其他的效果,例如拖拽的时候突出那一项等等可以在onSelectedChanged、clearView、onChildDraw中实现
//选中某一项的时候可以做背景等处理
@Override
public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {
//半透明
viewHolder.itemView.setAlpha(0.6f);
}
super.onSelectedChanged(viewHolder, actionState);
}
//将那一项的背景等清除
@Override
public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
//恢复背景
viewHolder.itemView.setAlpha(1f);
super.clearView(recyclerView, viewHolder);
}
@Override
public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
//dX 水平方向移动 往左为负 往右为正
if (actionState == ItemTouchHelper.ACTION_STATE_SWIPE) {
//透明度动画
viewHolder.itemView.setAlpha(1-Math.abs(dX)/viewHolder.itemView.getWidth());
}else{
if (actionState != ItemTouchHelper.ACTION_STATE_DRAG)
viewHolder.itemView.setAlpha(1f);
}
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
好了,到这里就结束了,看源码真的能发现不少东西,还能做好多交互的方式。明白了吗?知道了这些原理类似与QQ的侧滑删除应该有思路了吧
项目链接 https://github.com/389987790/TouchedRecyclerView