前幾天搗鼓了一下分割線,今天來看看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());
}
效果如下圖
拖拽和滑動刪除.gif
圖中有一些動畫效果不透明,同樣可以做一些其他的效果,例如拖拽的時候突出那一項等等可以在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的側滑刪除應該有思路了吧