您好,登錄后才能下訂單哦!
Android中怎么實現可拖拽列表和多選功能,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
主窗口JAVA代碼
/** * 編輯狀態下長按拖動條目 * 1.通過ItemTouchHelper.Callback實現長按拖動 * 2.通過isEditable的值判斷是否編輯狀態,初值是false * 3.切換編輯狀態要把isEditable的值取反,并改變復選框圖標狀態 * 4.在編輯狀態下,按返回鍵回到非編輯狀態 * 5.RecyclerView的點擊事件通過RecyclerAdapter.Callback實現 */public class ReportListActivity extends AppCompatActivity implements View.OnClickListener { private static final String TAG = "ReportListActivity"; @BindView(R.id.tv_title_middle) TextView title; @BindView(R.id.title_left) ImageView backButton; @BindView(R.id.online_report_listview) RecyclerView mRecyclerView; @BindView(R.id.edit_tv) TextView edit; @BindView(R.id.filter_tv) TextView filter; @BindView(R.id.btn_delete) TextView delete; @BindView(R.id.btn_release) TextView release; @BindView(R.id.btn_close) TextView close; @BindView(R.id.btn_top) TextView top; @BindView(R.id.toolbar) LinearLayout mToolbar; private Context mContext; private boolean isEditable; private RecyclerAdapter mAdapter; private List<ClsOnlineReport> mClsOnlineReportList; private ItemTouchHelper itemTouchHelper; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_online_report); ButterKnife.bind(this); initView(); initData(); initListener(); } private void initData() { mContext = this; mClsOnlineReportList = new ArrayList<>(); mAdapter = new RecyclerAdapter(mClsOnlineReportList); mRecyclerView.setAdapter(mAdapter); getOfflineData(20); //初始狀態為非編輯模式 setIsEditable(false); //初始化拖動接口 OnlineReportListCallback callback = new OnlineReportListCallback(mAdapter); itemTouchHelper = new ItemTouchHelper(callback); //初始狀態為不可拖動 setRecyclerViewDraggable(false); } //生成模擬數據 private void getOfflineData(int num) { List<ClsOnlineReport> clsOnlineReportList = new ArrayList<>(); for (int i = 0; i < num; i++) { ClsOnlineReport onlineReport = new ClsOnlineReport(); onlineReport.setActiveDate("activeDate " + i); onlineReport.setAutoCloseDate("autoCloseDate " + i); onlineReport.setBulletinID("bulletinID " + i); onlineReport.setBulletinTime("bulletinTime " + i); onlineReport.setBulletinTitle("bulletinTitle " + i); onlineReport.setCreater("creater " + i); clsOnlineReportList.add(onlineReport); } mClsOnlineReportList.addAll(clsOnlineReportList); mAdapter.notifyDataSetChanged(); } private void initView() { title.setText("可拖拽列表"); edit.setVisibility(View.VISIBLE); mToolbar.setVisibility(View.GONE); //設置RecyclerView的布局 mRecyclerView.setLayoutManager(new LinearLayoutManager(mContext)); } private void initListener() { filter.setOnClickListener(this); backButton.setOnClickListener(this); edit.setOnClickListener(this); delete.setOnClickListener(this); release.setOnClickListener(this); close.setOnClickListener(this); top.setOnClickListener(this); mAdapter.setmCallback((v, position) -> { switch (v.getId()) { case R.id.view_parent_1: case R.id.view_parent_2: ClsOnlineReport clsOnlineReport = mClsOnlineReportList.get(position); //在編輯模式下,點擊條目切換顯示checkbox,并且判斷選中條目的數量, if (getIsEditable()) { if (clsOnlineReport.getIsCheckBoxVisible()) { clsOnlineReport.setIsChecked(!clsOnlineReport.getIsChecked()); mAdapter.notifyDataSetChanged(); } for (int i = 0; i < mClsOnlineReportList.size(); i++) { //數量等于0,隱藏工具條,否則顯示工具條 ClsOnlineReport onlineReport = mClsOnlineReportList.get(i); if (onlineReport.getIsChecked()) { mToolbar.setVisibility(View.VISIBLE); break; } if (i == mClsOnlineReportList.size() - 1) { mToolbar.setVisibility(View.GONE); } } } else { //在非編輯模式下,點擊條目直接跳轉詳情頁,并把bulletinID傳過去 Intent intent = new Intent(mContext, ReportDetailActivity.class); intent.putExtra("bulletinID", clsOnlineReport.getBulletinID()); startActivityForResult(intent, 16371); } } }); } @Override public void onBackPressed() { //編輯狀態下,按返回鍵回到非編輯狀態,否則退出 if (getIsEditable()) { switchEditable(); } else { finish(); } } @Override public void onClick(View v) { //編輯狀態下,按返回鍵回到非編輯狀態,否則退出 if (v.getId() == R.id.title_left) { if (getIsEditable()) { switchEditable(); } else { finish(); } } //點擊編輯按鈕切換編輯狀態 if (v.getId() == R.id.edit_tv) { switchEditable(); } //工具條的按鈕對應不同的接口 switch (v.getId()) { case R.id.btn_top: case R.id.btn_close: case R.id.btn_release: case R.id.btn_delete: Toast.makeText(mContext, "在此處調用接口", Toast.LENGTH_SHORT).show(); } } private void switchEditable() { //將屬性取反 setIsEditable(!getIsEditable()); //遍歷列表并賦值 for (ClsOnlineReport clsOnlineReport : mClsOnlineReportList) { clsOnlineReport.setIsCheckBoxVisible(getIsEditable()); clsOnlineReport.setIsChecked(false); } //通知適配器刷新 mAdapter.notifyDataSetChanged(); //隱藏工具條 mToolbar.setVisibility(View.GONE); //切換拖動狀態 setRecyclerViewDraggable(getIsEditable()); } public boolean getIsEditable() { return isEditable; } public void setIsEditable(boolean isEditable) { this.isEditable = isEditable; } //設置能否拖動 private void setRecyclerViewDraggable(boolean draggable) { if (draggable) { itemTouchHelper.attachToRecyclerView(mRecyclerView); } else { itemTouchHelper.attachToRecyclerView(null); } } @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { //當詳情頁的數據有變動則刷新列表 if (requestCode == 16371 && resultCode == RESULT_OK) { refreshData(); } super.onActivityResult(requestCode, resultCode, data); } private void refreshData() { Toast.makeText(mContext, "在此處調用接口", Toast.LENGTH_SHORT).show(); }}
適配器代碼
/** * 可拖拽列表的適配器, * 1.需要實現OnlineReportListCallback.ItemTouchMoveListener * 2.持有一個接口用于傳遞position */public class RecyclerAdapter extends RecyclerView.Adapter implements OnlineReportListCallback.ItemTouchMoveListener, View.OnClickListener { private List<ClsOnlineReport> mList; private Callback mCallback; public RecyclerAdapter(List<ClsOnlineReport> mList) { this.mList = mList; } public void setmCallback(Callback mCallback) { this.mCallback = mCallback; } @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { LayoutInflater inflater = LayoutInflater.from(parent.getContext()); View v = inflater.inflate(R.layout.item_report_list, parent, false); return new ItemHolder(v); } @Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { ClsOnlineReport clsOnlineReport = mList.get(position); ItemHolder itemHolder = (ItemHolder) holder; if (clsOnlineReport.getIsCheckBoxVisible()) { itemHolder.checkbox.setVisibility(View.VISIBLE); itemHolder.drag.setVisibility(View.VISIBLE); } else { itemHolder.checkbox.setVisibility(View.GONE); itemHolder.drag.setVisibility(View.GONE); } if (clsOnlineReport.getIsChecked()) { itemHolder.checkbox.setImageResource(R.drawable.ic_check_box_black_24dp); } else { itemHolder.checkbox.setImageResource(R.drawable.ic_check_box_outline_blank_black_24dp); } itemHolder.parent1.setTag(position); itemHolder.parent2.setTag(position); itemHolder.parent1.setOnClickListener(this); itemHolder.parent2.setOnClickListener(this); itemHolder.time.setText(clsOnlineReport.getBulletinTime()); itemHolder.title.setText(clsOnlineReport.getBulletinTitle()); itemHolder.author.setText(clsOnlineReport.getCreater()); } @Override public int getItemCount() { return mList.size(); } @Override public boolean onItemMove(int fromPosition, int toPosition) { Collections.swap(mList, fromPosition, toPosition); notifyItemMoved(fromPosition, toPosition); return true; } class ItemHolder extends RecyclerView.ViewHolder { @BindView(R.id.online_report_time) TextView time; @BindView(R.id.online_report_title) TextView title; @BindView(R.id.online_report_author) TextView author; @BindView(R.id.online_report_drag) ImageView drag; @BindView(R.id.online_report_checkbox) ImageView checkbox; @BindView(R.id.view_parent_1) LinearLayout parent1; @BindView(R.id.view_parent_2) LinearLayout parent2; ItemHolder(View itemView) { super(itemView); ButterKnife.bind(this, itemView); } } @Override public void onClick(View v) { mCallback.onClick(v, (int) v.getTag()); } public interface Callback { void onClick(View v, int position); }}
需要實現的接口
/** * 用來完成RecyclerView長按拖拽的關鍵接口 * 1.getMovementFlags里面表示設置為上下拖動 * 2.onSelectedChanged里面表示拖動狀態下改變背景色,拖動完成后恢復背景色 * 3.拖動完成的時候viewHolder的值為空!!!所以要用srcHolder */public class OnlineReportListCallback extends ItemTouchHelper.Callback { private ColorDrawable drawable; private RecyclerView.ViewHolder srcHolder; public interface ItemTouchMoveListener { boolean onItemMove(int fromPosition, int toPosition); } private ItemTouchMoveListener moveListener; public OnlineReportListCallback(ItemTouchMoveListener moveListener) { this.moveListener = moveListener; int rgb = Color.rgb(0xff, 0xff, 0xff); drawable = new ColorDrawable(rgb); } @Override public int getMovementFlags(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) { int dragFlags = ItemTouchHelper.UP | ItemTouchHelper.DOWN; return makeMovementFlags(dragFlags, ItemTouchHelper.ACTION_STATE_IDLE); } @Override public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder srcHolder, RecyclerView.ViewHolder targetHolder) { this.srcHolder = srcHolder; return srcHolder.getItemViewType() == targetHolder.getItemViewType() && moveListener.onItemMove(srcHolder.getAdapterPosition(), targetHolder.getAdapterPosition()); } @Override public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) { } @Override public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) { super.onSelectedChanged(viewHolder, actionState); if (actionState == ItemTouchHelper.ACTION_STATE_DRAG) { viewHolder.itemView.setBackground(null); } if (actionState == ItemTouchHelper.ACTION_STATE_IDLE) { srcHolder.itemView.setBackground(drawable); } }}
圖片使用Android Studio內置的SVG,引入了ButterKnife綁定控件,另外內部類使用了lambda表達式折疊了,重點說一下RecyclerAdapter.Callback,這個接口的內部方法 void onClick(View v, int position) 是在View.OnClickListener的void onClick(View v)的基礎上多傳了一個參數,這個參數是放在tag里面的,其他難點注釋里面都有
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。