Android實(shí)現(xiàn)可拖拽列表和多選功能
本文實(shí)例為大家分享了Android實(shí)現(xiàn)可拖拽列表和多選的具體代碼,供大家參考,具體內(nèi)容如下
這是我已經(jīng)完成的一個(gè)已經(jīng)上線的OA軟件的一個(gè)模塊,這個(gè)模塊的功能不多,已經(jīng)放到GitHub上面開(kāi)源了,有感興趣的朋友可以看看UIFrame
主窗口JAVA代碼
/**
* 編輯狀態(tài)下長(zhǎng)按拖動(dòng)條目
* 1.通過(guò)ItemTouchHelper.Callback實(shí)現(xiàn)長(zhǎng)按拖動(dòng)
* 2.通過(guò)isEditable的值判斷是否編輯狀態(tài),初值是false
* 3.切換編輯狀態(tài)要把isEditable的值取反,并改變復(fù)選框圖標(biāo)狀態(tài)
* 4.在編輯狀態(tài)下,按返回鍵回到非編輯狀態(tài)
* 5.RecyclerView的點(diǎn)擊事件通過(guò)RecyclerAdapter.Callback實(shí)現(xiàn)
*/
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);
//初始狀態(tài)為非編輯模式
setIsEditable(false);
//初始化拖動(dòng)接口
OnlineReportListCallback callback = new OnlineReportListCallback(mAdapter);
itemTouchHelper = new ItemTouchHelper(callback);
//初始狀態(tài)為不可拖動(dòng)
setRecyclerViewDraggable(false);
}
//生成模擬數(shù)據(jù)
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);
//設(shè)置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);
//在編輯模式下,點(diǎn)擊條目切換顯示checkbox,并且判斷選中條目的數(shù)量,
if (getIsEditable()) {
if (clsOnlineReport.getIsCheckBoxVisible()) {
clsOnlineReport.setIsChecked(!clsOnlineReport.getIsChecked());
mAdapter.notifyDataSetChanged();
}
for (int i = 0; i < mClsOnlineReportList.size(); i++) {
//數(shù)量等于0,隱藏工具條,否則顯示工具條
ClsOnlineReport onlineReport = mClsOnlineReportList.get(i);
if (onlineReport.getIsChecked()) {
mToolbar.setVisibility(View.VISIBLE);
break;
}
if (i == mClsOnlineReportList.size() - 1) {
mToolbar.setVisibility(View.GONE);
}
}
} else {
//在非編輯模式下,點(diǎn)擊條目直接跳轉(zhuǎn)詳情頁(yè),并把bulletinID傳過(guò)去
Intent intent = new Intent(mContext, ReportDetailActivity.class);
intent.putExtra("bulletinID", clsOnlineReport.getBulletinID());
startActivityForResult(intent, 16371);
}
}
});
}
@Override
public void onBackPressed() {
//編輯狀態(tài)下,按返回鍵回到非編輯狀態(tài),否則退出
if (getIsEditable()) {
switchEditable();
} else {
finish();
}
}
@Override
public void onClick(View v) {
//編輯狀態(tài)下,按返回鍵回到非編輯狀態(tài),否則退出
if (v.getId() == R.id.title_left) {
if (getIsEditable()) {
switchEditable();
} else {
finish();
}
}
//點(diǎn)擊編輯按鈕切換編輯狀態(tài)
if (v.getId() == R.id.edit_tv) {
switchEditable();
}
//工具條的按鈕對(duì)應(yīng)不同的接口
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, "在此處調(diào)用接口", 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);
//切換拖動(dòng)狀態(tài)
setRecyclerViewDraggable(getIsEditable());
}
public boolean getIsEditable() {
return isEditable;
}
public void setIsEditable(boolean isEditable) {
this.isEditable = isEditable;
}
//設(shè)置能否拖動(dòng)
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) {
//當(dāng)詳情頁(yè)的數(shù)據(jù)有變動(dòng)則刷新列表
if (requestCode == 16371 && resultCode == RESULT_OK) {
refreshData();
}
super.onActivityResult(requestCode, resultCode, data);
}
private void refreshData() {
Toast.makeText(mContext, "在此處調(diào)用接口", Toast.LENGTH_SHORT).show();
}
}
適配器代碼
/**
* 可拖拽列表的適配器,
* 1.需要實(shí)現(xiàn)OnlineReportListCallback.ItemTouchMoveListener
* 2.持有一個(gè)接口用于傳遞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);
}
}
需要實(shí)現(xiàn)的接口
/**
* 用來(lái)完成RecyclerView長(zhǎng)按拖拽的關(guān)鍵接口
* 1.getMovementFlags里面表示設(shè)置為上下拖動(dòng)
* 2.onSelectedChanged里面表示拖動(dòng)狀態(tài)下改變背景色,拖動(dòng)完成后恢復(fù)背景色
* 3.拖動(dòng)完成的時(shí)候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內(nèi)置的SVG,引入了ButterKnife綁定控件,另外內(nèi)部類(lèi)使用了lambda表達(dá)式折疊了,重點(diǎn)說(shuō)一下RecyclerAdapter.Callback,這個(gè)接口的內(nèi)部方法 void onClick(View v, int position) 是在View.OnClickListener的
void onClick(View v)的基礎(chǔ)上多傳了一個(gè)參數(shù),這個(gè)參數(shù)是放在tag里面的,其他難點(diǎn)注釋里面都有,不懂的話要自己動(dòng)手跑一下程序,然后也可以問(wèn)我
效果如下圖:

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- android ItemTouchHelper實(shí)現(xiàn)可拖拽和側(cè)滑的列表的示例代碼
- Android自定義ListView實(shí)現(xiàn)仿QQ可拖拽列表功能
- Android checkbox的listView(多選,全選,反選)具體實(shí)現(xiàn)方法
- Android中ListView + CheckBox實(shí)現(xiàn)單選、多選效果
- Android Recyclerview實(shí)現(xiàn)多選,單選,全選,反選,批量刪除的功能
- android GridView多選效果的實(shí)例代碼
- Android的ListView多選刪除操作實(shí)現(xiàn)代碼
- Android中創(chuàng)建對(duì)話框(確定取消對(duì)話框、單選對(duì)話框、多選對(duì)話框)實(shí)例代碼
- Android使用AlertDialog實(shí)現(xiàn)的信息列表單選、多選對(duì)話框功能
- Android自定義控件實(shí)現(xiàn)可多選課程日歷CalendarView
相關(guān)文章
Android5.1系統(tǒng)通過(guò)包名給應(yīng)用開(kāi)放系統(tǒng)權(quán)限的方法
這篇文章主要介紹了Android5.1系統(tǒng)通過(guò)包名給應(yīng)用開(kāi)放系統(tǒng)權(quán)限的方法,此文介紹一種通過(guò)修改Android平臺(tái)系統(tǒng)層代碼,根據(jù)指定的應(yīng)用包名給對(duì)應(yīng)的應(yīng)用在該平臺(tái)上開(kāi)放系統(tǒng)權(quán)限,需要的朋友可以參考下2017-11-11
Android中判斷網(wǎng)絡(luò)連接是否可用及監(jiān)控網(wǎng)絡(luò)狀態(tài)
獲取網(wǎng)絡(luò)信息需要在AndroidManifest.xml文件中加入相應(yīng)的權(quán)限,接下來(lái)詳細(xì)介紹Android中判斷網(wǎng)絡(luò)連接是否可用及監(jiān)控網(wǎng)絡(luò)狀態(tài),感興趣的朋友可以參考下2012-12-12
Android 快速繪制一個(gè)圓角矩形的實(shí)例
下面小編就為大家分享一篇Android 快速繪制一個(gè)圓角矩形的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01
Android-實(shí)現(xiàn)切換Fragment頁(yè)功能的實(shí)現(xiàn)代碼
本篇文章主要介紹了Android-實(shí)現(xiàn)切換Fragment頁(yè)功能的實(shí)現(xiàn)代碼,具有一定的參加價(jià)值,有興趣的可以了解一下。2017-02-02
Win8下Android SDK安裝與環(huán)境變量配置教程
這篇文章主要為大家詳細(xì)介紹了Win8下Android SDK安裝與環(huán)境變量配置教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
Android開(kāi)發(fā)跳轉(zhuǎn)應(yīng)用市場(chǎng)進(jìn)行版本更新功能實(shí)現(xiàn)
這篇文章主要為大家介紹了Android實(shí)現(xiàn)跳轉(zhuǎn)到應(yīng)用市場(chǎng)進(jìn)行版本更新功能,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04
PagerSlidingTabStrip制作Android帶標(biāo)簽的多界面滑動(dòng)切換
這篇文章主要介紹了使用PagerSlidingTabStrip制作Android帶標(biāo)簽的多界面滑動(dòng)切換效果的方法,PagerSlidingTabStrip是GitHub上的一個(gè)開(kāi)源項(xiàng)目,調(diào)用這個(gè)庫(kù)可以少寫(xiě)不少代碼XD 需要的朋友可以參考下2016-04-04

