android 多級列表的實現
樹形結果的多級列表,其實就是不同級別資料的縮排位移不同;
兩個關鍵點,一是在adapter中根據級別設定縮排的數值;
二是對資料的處理;
首先定義一個數據bean:
在bean中 定義資料的級別level顯示時縮排的設定就是依據這個level
例如第二級有多個數據 每個資料都有自己的下一級也就是第三級 這個時候為了區分第三級也就是子集歸屬哪個父級用分組的方式:父級有組id 子集有所在組的id 如果子集所在組的id與父級的組id相同那這個子級就是這個父級的;
isOpen:有子級的父級會在展示時在最左側新增一個加號的可點選圖示用以區分展示子級(變為減號)收起子級(變回加號)
public class GustInformationBean { private String id; private boolean isGroup;//是否是組(此賬號下是否包含子賬號) private int gId;//組id private int belongToID;//所在組的id private int level;//自身的級別 private boolean isOpen;// private String name; public String getId() { return id; } public void setId(String id) { this.id = id; } public boolean isGroup() { return isGroup; } public void setGroup(boolean group) { isGroup = group; } public int getgId() { return gId; } public void setgId(int gId) { this.gId = gId; } public int getBelongToID() { return belongToID; } public void setBelongToID(int belongToID) { this.belongToID = belongToID; } public int getLevel() { return level; } public void setLevel(int level) { this.level = level; } public boolean isOpen() { return isOpen; } public void setOpen(boolean open) { isOpen = open; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
Ac'ti'vi't'y中操作,繫結recyclerview 生成模擬資料來源 資料操作方法
public class F_FilterUser extends BaseFragment { private RecyclerView recyclerView; private List<GustInformationBean> dataList; private List<GustInformationBean> dataListForShowData; private F_FilterUserAdapter adapter; @Override public View onCreateView() { View view = LayoutInflater.from(getActivity()).inflate(R.layout.fragment_filter_user, null); init(view); return view; } private void init(View view) { recyclerView = view.findViewById(R.id.filterUserList); dataList = new ArrayList<>(); dataListForShowData = new ArrayList<>(); adapter = new F_FilterUserAdapter(getActivity(), dataListForShowData); LinearLayoutManager layoutManager = new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false); recyclerView.setLayoutManager(layoutManager); DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(getActivity(), DividerItemDecoration.VERTICAL); dividerItemDecoration.setDrawable(getResources().getDrawable(R.drawable.item_divide)); recyclerView.addItemDecoration(dividerItemDecoration); recyclerView.setAdapter(adapter); adapter.setOnItemClickListener(position -> { }); adapter.setOnDownArrowClickListener(position -> setData(position)); obtainData(); } private void obtainData() {//模擬展示資料 for (int i = 0; i < 10; i++) { GustInformationBean gustInformationBean = new GustInformationBean(); if (i < 4) { gustInformationBean.setLevel(1); gustInformationBean.setGroup(true); gustInformationBean.setgId(i); gustInformationBean.setBelongToID(-1); gustInformationBean.setName("xxxx" + (i)); } else if (i == 4 || i == 5 || i == 6 || i == 7) { gustInformationBean.setLevel(2); gustInformationBean.setGroup(true); gustInformationBean.setBelongToID(i - 4); gustInformationBean.setgId(i); gustInformationBean.setName("xxxx 2級" + (i)); } else { gustInformationBean.setLevel(3); gustInformationBean.setGroup(false); gustInformationBean.setBelongToID(4); gustInformationBean.setName("xxxx 3級" + (i)); } dataList.add(gustInformationBean); } for (int i = 0; i < dataList.size(); i++) { GustInformationBean gustInformationBean = dataList.get(i); if (gustInformationBean.getLevel() == 1) { dataListForShowData.add(gustInformationBean); } } adapter.notifyDataSetChanged(); } /** * 根據子級執行的展開還是關閉的操作來重組資料,然後重新整理列表達到展示子級或關閉子級的顯示效果 * @param position */ private void setData(int position) { GustInformationBean gustInformationBean = dataListForShowData.get(position); boolean isOpen = gustInformationBean.isOpen(); gustInformationBean.isGroup(); gustInformationBean.getgId(); if (isOpen) {//當前為開啟狀態所以此次點選執行關閉子級的操作 dataListForShowData.get(position).setOpen(false);//因為是關閉操作將open屬性設定為關閉 List<GustInformationBean> dataListNew = new ArrayList<>(); int level = dataListForShowData.get(position).getLevel(); //在當前展示資料中刪除符合範圍的子級 for (int i = position + 1; i < dataListForShowData.size(); i++) { GustInformationBean gustInformationBean1 = dataListForShowData.get(i); int childLevel = gustInformationBean1.getLevel(); if (childLevel > level) {//因為當前展示的資料是有序的所以只要刪除在當前所選項與相鄰下一個與所選項級別相同的項之間的資料就可以了 gustInformationBean1.setOpen(false); dataListNew.add(gustInformationBean1); } else { break; } } dataListForShowData.removeAll(dataListNew); adapter.notifyDataSetChanged(); } else {//當前為關閉狀態執行開啟操作 dataListForShowData.get(position).setOpen(true); List<GustInformationBean> dataListNew = new ArrayList<>(); dataListNew.addAll(dataListForShowData); int gId = dataListForShowData.get(position).getgId(); //在總的資料來源中篩選 for (int i = 0; i < dataList.size(); i++) { GustInformationBean gustInformationBean1 = dataList.get(i); int btId = gustInformationBean1.getBelongToID(); if (btId == gId) {//找出所歸屬的組id與所選項組id相同的項 dataListNew.add(position + 1, gustInformationBean1); } } dataListForShowData.clear(); dataListForShowData.addAll(dataListNew); adapter.notifyDataSetChanged(); } } }
adapter 操作 根據level設定資料左縮排的程度public class F_FilterUserAdapter extends Adapter {
private List<GustInformationBean> listData;
private Context context;
public F_FilterUserAdapter(Context context, List<GustInformationBean> listData) {
this.context = context;
this.listData = listData;
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_filter_user_adapter, null);
return new MyViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
MyViewHolder myViewHolder = (MyViewHolder) viewHolder;
GustInformationBean gustInformationBean = listData.get(i);
if (gustInformationBean != null) {
boolean isG = gustInformationBean.isGroup();
if (isG) {//判斷是否時組即有沒有子級
myViewHolder.itemFilterUserGroupIcon.setVisibility(View.VISIBLE);//顯示錶示有子級的圖示
boolean isOpen = gustInformationBean.isOpen();
if (isOpen) {//判斷當前是加號圖示還是減號圖示
myViewHolder.itemFilterUserGroupIcon.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_arrow_drop_up_black_24dp));
} else {
myViewHolder.itemFilterUserGroupIcon.setImageDrawable(context.getResources().getDrawable(R.drawable.ic_arrow_drop_down_black_24dp));
}
//為圖示新增點選監聽用以展開和關閉子級
myViewHolder.itemFilterUserGroupIcon.setOnClickListener(v -> {
if (onDownArrowClickListener != null) {
onDownArrowClickListener.onDownArrowClick(i);
}
});
} else {
myViewHolder.itemFilterUserGroupIcon.setVisibility(View.INVISIBLE);
}
//根據級別設定資料的左側縮排
int level = gustInformationBean.getLevel();
myViewHolder.itemFilterUserGroupIcon.setPadding(25 * level, myViewHolder.itemFilterUserGroupIcon.getPaddingTop()
, myViewHolder.itemFilterUserGroupIcon.getPaddingRight()
, myViewHolder.itemFilterUserGroupIcon.getPaddingBottom());
String nameStr = gustInformationBean.getName();
if (nameStr != null) {
myViewHolder.itemFilterUserName.setText(nameStr);
}
}
myViewHolder.itemView.setOnClickListener(v -> {
if (onItemClickListener != null) {
onItemClickListener.onItemClick(i);
}
});
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemCount() {
return listData.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
private TextView itemFilterUserName;
private ImageView itemFilterUserGroupIcon;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
itemFilterUserName = itemView.findViewById(R.id.itemFilterUserName);
itemFilterUserGroupIcon = itemView.findViewById(R.id.itemFilterUserGroupIcon);
}
}
//定義的item的點選監聽
public interface OnItemClickListener {
void onItemClick(int position);
}
private OnItemClickListener onItemClickListener;
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
//定義的執行展開和關閉操作的按鈕的點選監聽
public interface OnDownArrowClickListener {
void onDownArrowClick(int position);
}
private OnDownArrowClickListener onDownArrowClickListener;
public void setOnDownArrowClickListener(OnDownArrowClickListener onDownArrowClickListener) {
this.onDownArrowClickListener = onDownArrowClickListener;
}
}
layout都很簡單,activity就一個recycler view ; adapter中橫向排佈一個image view和一個text view;