上一篇介紹了RecyclerView的基本使用,本篇來介紹左右滑動刪除與上下拖曳。這些手勢控制提升了使用者使用時的方便,本篇的核心主要是透過ItemTouchHelper來處理。
本篇會接續上一篇的範例,繼續延伸。本篇小目標:
在開始之前我們先將Github上的第三方的函式庫套件導入自己的專案:
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
.
.
.
maven { url 'https://jitpack.io' }
}
}
implementation 'com.github.xabaras:RecyclerViewSwipeDecorator:1.4'
先在RecyclerViewAdapter中加入,ItemTouchHelper方法:
public void recyclerViewItemTouchHelper(RecyclerView recyclerView,List<StudentData> studentDataList) {
ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
//管理RecyclerView的操作 上下左右
return makeMovementFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN , ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
//管理RecyclerView上下拖曳操作 01 12 23 34
int position_dragged = viewHolder.getAdapterPosition(); //初始位置
int position_target = target.getAdapterPosition(); //結束位置
Log.e("position_f", String.valueOf(viewHolder.getAdapterPosition()));
Log.e("position_b", String.valueOf(target.getAdapterPosition()));
Collections.swap(studentDataList, position_dragged, position_target); //將 索引position_dragged 與 索引position_target 的值交換位置
//只管RecyclerView的交換 不管原始陣列的交換
notifyItemMoved(position_dragged, position_target);
return false;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
//管理RecyclerView滑動操作
int position = viewHolder.getAdapterPosition();
switch (direction) {
case ItemTouchHelper.LEFT:
case ItemTouchHelper.RIGHT:
//刪除List中的position項資料
studentDataList.remove(position);
//於RecyclerView刪除position項資料
notifyItemRemoved(position);
break;
}
}
//管理Item左右滑動時圖示的樣式
@Override
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
new RecyclerViewSwipeDecorator.Builder(c,recyclerView,viewHolder,dX,dY,actionState,isCurrentlyActive)
.addBackgroundColor(Color.parseColor("#CB1B45"))
.addActionIcon(R.drawable.ic_baseline_delete_forever_24)
.create()
.decorate();
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
});
helper.attachToRecyclerView(recyclerView);
}
接下來我們在前一篇的MainActivity基礎中加入:
recyclerViewAdapter.recyclerViewItemTouchHelper(recyclerView,studentDataList);
完整程式碼如下:
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
RecyclerViewAdapter recyclerViewAdapter;
StudentData student;
List<StudentData> studentDataList = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//建立假資料
for(int i = 0;i<30;i++){
student = new StudentData(i+1,
"09"+String.format("%08d",i+1),
"XXX");
studentDataList.add(student);
}
recyclerView = findViewById(R.id.recyclerView);
//設置布局管理器
recyclerView.setLayoutManager(new LinearLayoutManager(this));
//設置RecyclerViewAdapter與傳入要顯示的資料
recyclerViewAdapter = new RecyclerViewAdapter(this);
recyclerViewAdapter.setStudentData(studentDataList);
recyclerView.setAdapter(recyclerViewAdapter);
//添加底線樣式
recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
//RecyclerViewItemTouchHelper
recyclerViewAdapter.recyclerViewItemTouchHelper(recyclerView,studentDataList);
}
}
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder>{
List<StudentData> studentDataList = new ArrayList<>();
Context context;
public RecyclerViewAdapter(Context context){
this.context = context;
}
public class ViewHolder extends RecyclerView.ViewHolder{
TextView textView_number,textView_name,textView_phone;
public ViewHolder(@NonNull View itemView) {
super(itemView);
textView_name = itemView.findViewById(R.id.textView_name);
textView_number = itemView.findViewById(R.id.textView_number);
textView_phone = itemView.findViewById(R.id.textView_phone);
}
void setShowValue(int position){
textView_number.setText(String.format("%02d",studentDataList.get(position).getNumber()));
textView_name.setText(studentDataList.get(position).getName());
textView_phone.setText(studentDataList.get(position).getPhone());
}
void setItemViewOnclick(int position){
//itemView點擊事件
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(v.getContext(),"您選擇的是第 " + ( position + 1 ) + " 項", Toast.LENGTH_SHORT).show();
}
});
}
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//加載Item布局
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item, parent,false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
//設定顯示資料
holder.setShowValue(position);
//設定ItemView的點擊事件
holder.setItemViewOnclick(position);
}
@Override
public int getItemCount() {
//設定顯示數量
return studentDataList.size();
}
//傳入MainActivity中的studentDataList
public void setStudentData(List<StudentData> studentDataList){
this.studentDataList = studentDataList;
notifyDataSetChanged();
}
public void recyclerViewItemTouchHelper(RecyclerView recyclerView,List<StudentData> studentDataList) {
ItemTouchHelper helper = new ItemTouchHelper(new ItemTouchHelper.Callback() {
@Override
public int getMovementFlags(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder) {
//管理RecyclerView的操作 上下左右
return makeMovementFlags(ItemTouchHelper.UP | ItemTouchHelper.DOWN , ItemTouchHelper.LEFT | ItemTouchHelper.RIGHT);
}
@Override
public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
//管理RecyclerView上下拖曳操作 01 12 23 34
int position_start = viewHolder.getAdapterPosition(); //初始位置
int position_end = target.getAdapterPosition(); //結束位置
Log.e("position_f", String.valueOf(viewHolder.getAdapterPosition()));
Log.e("position_b", String.valueOf(target.getAdapterPosition()));
Collections.swap(studentDataList, position_start, position_end); //將 索引position_start 與 索引position_end 的值交換位置
//只管RecyclerView的交換 不管原始陣列的交換
notifyItemMoved(position_start, position_end);
return false;
}
@Override
public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
//管理RecyclerView滑動操作
int position = viewHolder.getAdapterPosition();
switch (direction) {
case ItemTouchHelper.LEFT:
case ItemTouchHelper.RIGHT:
//刪除List中的position項資料
studentDataList.remove(position);
//於RecyclerView中刪除position項資料
notifyItemRemoved(position);
break;
}
}
//管理Item左右滑動時圖示的樣式
@Override
public void onChildDraw(@NonNull Canvas c, @NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
new RecyclerViewSwipeDecorator.Builder(c,recyclerView,viewHolder,dX,dY,actionState,isCurrentlyActive)
.addBackgroundColor(Color.parseColor("#CB1B45"))
.addActionIcon(R.drawable.ic_baseline_delete_forever_24)
.create()
.decorate();
super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
}
});
helper.attachToRecyclerView(recyclerView);
}
}