iT邦幫忙

2022 iThome 鐵人賽

DAY 18
0
Mobile Development

Android studio 30天新手筆記系列 第 18

Day18-Android新手筆記-RecyclerView滑動刪除與上下拖曳

  • 分享至 

  • xImage
  •  

上一篇介紹了RecyclerView的基本使用,本篇來介紹左右滑動刪除與上下拖曳。這些手勢控制提升了使用者使用時的方便,本篇的核心主要是透過ItemTouchHelper來處理。

/images/emoticon/emoticon31.gif

本篇會接續上一篇的範例,繼續延伸。本篇小目標:

在開始之前我們先將Github上的第三方的函式庫套件導入自己的專案:

  • 於setting.gradel中加入
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        .
        .
        .
        maven { url 'https://jitpack.io' }
    }
}
  • build.gradle中加入
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);
    }
  • getMovementFlags 方法管理RecyclerView的上下左右的操作權限。
  • onMove 方法管理RecyclerView上下拖的操作。
  • onSwiped 方法管理RecyclerView滑動操作。
  • onChildDraw 方法管理Item左右滑動時圖示的樣式。

接下來我們在前一篇的MainActivity基礎中加入:

recyclerViewAdapter.recyclerViewItemTouchHelper(recyclerView,studentDataList);

完整程式碼如下:

  • MainActivity
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);
    }
}
  • RecyclerViewAdapter
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);
    }
}

/images/emoticon/emoticon41.gif


上一篇
Day17-Android新手筆記-RecyclerView元件基本介紹
下一篇
Day19-Android新手筆記-Retrofit使用與天氣API連線
系列文
Android studio 30天新手筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言