note_37:树形列表

24 篇文章 0 订阅

树形列表


缩进目录



假设json数据的bean类如下:

DataBean.java

public class DataBean {
	private List<MainChapterBean> mainChapterList;

	public List<MainChapterBean> getMainChapterList() {
		return mainChapterList;
	}

	public void setMainChapterList(List<MainChapterBean> mainChapterList) {
		this.mainChapterList = mainChapterList;
	}

	public static class MainChapterBean {
		private int chapterId;
		private String chapterTitle;
		private List<SubChapterBean> subChapterList;

		public int getChapterId() {
			return chapterId;
		}

		public void setChapterId(int chapterId) {
			this.chapterId = chapterId;
		}

		public String getChapterTitle() {
			return chapterTitle;
		}

		public void setChapterTitle(String chapterTitle) {
			this.chapterTitle = chapterTitle;
		}

		public List<SubChapterBean> getSubChapterList() {
			return subChapterList;
		}

		public void setSubChapterList(List<SubChapterBean> subChapterList) {
			this.subChapterList = subChapterList;
		}

		public static class SubChapterBean {
			private int chapterId;
			private String chapterTitle;
			private List<SubChapterBean> subChapterList;

			public int getChapterId() {
				return chapterId;
			}

			public void setChapterId(int chapterId) {
				this.chapterId = chapterId;
			}

			public String getChapterTitle() {
				return chapterTitle;
			}

			public void setChapterTitle(String chapterTitle) {
				this.chapterTitle = chapterTitle;
			}

			public List<SubChapterBean> getSubChapterList() {
				return subChapterList;
			}

			public void setSubChapterList(List<SubChapterBean> subChapterList) {
				this.subChapterList = subChapterList;
			}

			@NonNull
			@Override
			public String toString() {
				return new Gson().toJson(this);
			}

		}


		@NonNull
		@Override
		public String toString() {
			return new Gson().toJson(this);
		}

	}

	@NonNull
	@Override
	public String toString() {
		return new Gson().toJson(this);
	}

}

这个bean类数据类似于

node =
    {title:“1”, id:1, children:[
       {title:“1.1”, id:2, children:[ {title:“1.1.1”, id:3 children:[ ] }, {title:“1.1.2”, id:4, children:[ ] } ] },
       {title:“2”, id:5, children:[ {title:“2.1”, id:6, children:[ ] }, {title:“2.2”, id:7, children:[ ] } ] }
    ] }


1. 打印列表

总之就是一个list包含一个childrenList,childrenList里面可能又包含另一个childrenList。

要把这些数据全部读出来并且排成一个目录列表,显然是使用深度优先搜索:遍历完一个章节的所有子目录之后,把数据塞到另一个list里面,然后再去遍历另一个章节。

AdapterBean.java

public class AdapterBean {
	private int chapterId;
	private String chapterTitle;
	private int level;

	public int getChapterId() {
		return chapterId;
	}

	public void setChapterId(int chapterId) {
		this.chapterId = chapterId;
	}

	public String getChapterTitle() {
		return chapterTitle;
	}

	public void setChapterTitle(String chapterTitle) {
		this.chapterTitle = chapterTitle;
	}

	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}
}

MainActivity.java

private void handleList(List<DataBean> dataList) {
	if (dataList == null || dataList.getMainChapterList() == null) return;
	List<AdapterBean> adapterList = createAdapterList(dataList.getMainChapterList());
	adapter.setData(adapterList);
}

private void createAdapterList(List<MainChapterBean> mainChapterList) {
	List<AdapterBean> adapterList = new ArrayList<>();
	for (int i = 0; i < mainChapterList.size(); i++) {
		MainChapterBean item = mainChapterList.get(i);
		AdapterBean bean = new AdapterBean();
		bean.setChapterId(item.getChapterId);
		bean.setChapterTitle(item.getChapterTitle);
		bean.setLevel(0);
		adapterList.add(bean);
		if (item.getSubChapterList() != null && !item.getSubChapterList().isEmpty()) {
			dfs(1, item.getSubChapterList(), adapterList);
		}

	}
}

private void dfs(int level, List<SubChapterBean> subChapterList, List<AdapterBean> adapterList) {
	if (subChapterList == null) return;
	for (int i = 0; i < subChapterList.size(); i++) {
		SubChapterBean item = subChapterList.get(i);
		AdapterBean bean = new AdapterBean();
		bean.setChapterTitle(item.getChapterTitle());
		bean.setChapterId(item.getChapterId());
		bean.setLevel(level);
		adapterList.add(bean);
		if (item.getSubChapterList() != null && !item.getSubChapterList().isEmpty()) {
			dfs(level + 1, item.getSubChapterList(), adapterList);
		}

	}
}


如果要对位于不同层的目录应用不同样式的话,那么在遍历的过程中就要额外加入一个level变量来记录当前遍历到第几层,在onBindViewHolder()里面根据每个item的level来设置样式。

如果是设置缩进的话,尽量使用padding而不是margin,防止之后要进行item的显示和隐藏操作的时候,因为ViewHolder的itemView的margin而造成就算item隐藏了也出现空白的间隔。


2. 树形列表

如果要实现点击父目录的时候子目录可以显示或隐藏的话,需要在AdapterBean里面额外添加参数来记录。
实现点击显示,显示的是点击的那个目录的一层子目录,用循环。
实现点击隐藏,隐藏的是点击的那个目录的所有子目录,用递归。

AdapterBean

public class AdapterBean {
	private int chapterId = 0;
	private String chapterTitle = "";
	private int level = 0;

	private AdapterBean parent = null; // 父目录节点

	private boolean hasChild = false; // 该节点有没有子目录
	private boolean showChild = false; // 该节点的子目录有没有显示
	private List<AdapterBean> childNodeList = null;

	private int visibility = View.GONE; // 该节点有没有显示


	public int getChapterId() {
		return chapterId;
	}

	public void setChapterId(int chapterId) {
		this.chapterId = chapterId;
	}

	public String getChapterTitle() {
		return chapterTitle;
	}

	public void setChapterTitle(String chapterTitle) {
		this.chapterTitle = chapterTitle;
	}

	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public AdapterBean getParent() {
		return parent;
	}

	public void setParent(AdapterBean parent) {
		this.parent = parent;
	}

	public boolean getHasChild() {
		return hasChild;
	}

	public void setHasChild(boolean hasChild) {
		this.hasChild = hasChild;
	}

	public boolean getShowChild() {
		return showChild;
	}

	public void setShowChild(boolean showChild) {
		this.showChild = showChild;
	} 

	public List<AdapterBean> getChildNodeList() {
		return childNodeList;
	}

	public void setChildNodeList(List<AdapterBean> childNodeList) {
		this.childNodeList = childNodeList;
	}

	public int getVisibility() {
		return visibility;
	}

	public void setVisibility(int visibility) {
		this.visibility = visibility;
	}
}

所以前面遍历的代码就需要改一下了

MainActivity.java

private void handleList(List<DataBean> dataList) {
	if (dataList == null || dataList.getMainChapterList() == null) return;
	List<AdapterBean> adapterList = createAdapterList(dataList.getMainChapterList());
	adapter.setData(adapterList);
}

private void createAdapterList(List<MainChapterBean> mainChapterList) {
	List<AdapterBean> adapterList = new ArrayList<>();
	for (int i = 0; i < mainChapterList.size(); i++) {
		MainChapterBean item = mainChapterList.get(i);
		AdapterBean bean = new AdapterBean();
		bean.setChapterId(item.getChapterId);
		bean.setChapterTitle(item.getChapterTitle);
		bean.setLevel(0);
		bean.setParent(null);
		bean.setHasChild(item.getSubChapterList() != null && !item.getSubChapterList().isEmpty);
		bean.setShowChild(false);
		bean.setVisibility(View.VISIBLE); // 第一层目录是默认显示的
		adapterList.add(bean);
		if (bean.getHasChild()) {
			bean.setChildNodeList(new ArrayList<>());
			dfs(1, item.getSubChapterList(), adapterList, bean);
		}

	}
}

private void dfs(int level, List<SubChapterBean> subChapterList, List<AdapterBean> adapterList, AdapterBean parent) {
	if (subChapterList == null) return;
	for (int i = 0; i < subChapterList.size(); i++) {
		SubChapterBean item = subChapterList.get(i);
		AdapterBean bean = new AdapterBean();
		parent.getChildNodeList().add(bean);
		bean.setChapterTitle(item.getChapterTitle());
		bean.setChapterId(item.getChapterId());
		bean.setLevel(level);
		bean.setParent(parent);
		bean.setShowChild(false);
		node.setHasChild(item.getSubChapterList() != null && !item.getSubChapterList().isEmpty());
		node.setVisibility(View.GONE);
		adapterList.add(bean);
		if (node.getHasChild()) {
			node.setChildNodeList(new ArrayList<>());
			dfs(level + 1, item.getSubChapterList(), adapterList, bean);
		}
	}
}

MyAdapter.java

/** 点击了某个有子目录的节点时 显示第一层孩子节点
  *  @parem position 点击的节点的位置
  *  @parem bean 点击的节点
  */

public void showNode(int posiiton, AdapterBean bean) {
	bean.setShowChild(true);
	for (int i = position + 1; i < mAdapterList.size(); i++) {
		AdapterBean item = mAdapterList.get(i);
		if (item.getParent() == bean) item.setVisibility(View.VISIBLE);
	}
	notifyDataSetChanged();
}

/** 点击了某个有子目录的节点时 隐藏这个节点下所有层的子目录
  *  @parem position 点击的节点的位置
  *  @parem bean 点击的节点
  */

public void hideNode(int position, AdapterBean bean) {
	bean.setShowChild(false);
	List<AdapterBean> list = bean.getChildNodeList();
	for (int i = 0; i < list.size(); i++) {
		AdapterBean item = list.get(i);
		// 如果这个节点没有子目录或者第一层子目录没有显示的话 那就不用遍历了
		if (item.getShowChild() && item.getHasChild()) {
			recurseHideNode(item.getChildNodeList());
		}
		item.setShowChild(false);
		item.setVisibility(View.GONE);
	}
	notifyDataSetChanged();
}

private void recurseHideNode(List<AdapterBean> childList) {
	if (childList == null) return;
	for (int i = 0; i < childList.size(); i++) {
		AdapterBean item = childList.get(i);
		if (item.getShowChild() && item.getHasChild()) {
			recurseHideNode(item.getChildNodeList());
		}
		item.setShowChild(false);
		item.setVisibility(View.GONE);
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值