安卓多级列表简单实现

      二级listview我们可以使用expandablelistview,可以解决问题,但是要是多级的listview我们该怎么办。

       网上有一个办法就是expandablelistview嵌套expandablelistview,我曾经以为这个可以解决问题,但是在实际应用中发现,子expandablelistview是不能张开的,整个视图的效果不是很好。

       现在我来介绍一下我的方法。首先我们需要理解数据和视图是分开的,抛开两级、三级listview的束缚,界面是界面,数据是数据。我们只用最简单的listview,然后我们不改变数据源,那么我们改变的是什么了,通过索引寻找数据的方式。进一步说就是改变adapter中计算数据的数目方法和通过position找数据的方法。

                                                                                 

       这是一张树形数据结构的图,上面标注了每个索引。我们可以把它当作是完全展开,或者有些数据被隐藏了,我们不考虑隐藏的节点,它无关整个数据的多少和每个节点的索引。

下面是我的数据模型。

       private Object obj;
       public List<TreeNode> child;
       public boolean isOpenChild;

       obj代表自己的数据,child代表子类的数据,每个子类必须放在父类的child列表中去,isOpenChild是否开发子类,这个和adapter中数据的多少和寻找数据的方法有关。
       下面是计算当前状态下有多少数据,listview中显示多少计算多少,会更具数据的isOpenChild计算。当前索引值的只计算子类和子类的子类的数据,不计算自身。

// 只计算子类和子类的直接子类、间接子类的数目
 public int getChildSize() {
		int size = 0;
		// 判断子类集合对象是否为空
		if (child == null) {
			System.out.println("子类对象为空" + obj.toString());
			return size;
		}
		// 子类集合大小为零 或者 不开放子类
		if (child.size() == 0 || isOpenChild == false) {
			System.out.println("子类对象数目为空" + obj.toString());
			return size;
		}

		for (int i = 0; i < child.size(); i++) {
			// 计算特定索引值的子类的所包含的大小
			// 1 代表子类 child.get(i).getSize()是子类的所包含的数目
			size += child.get(i).getChildSize() + 1;
		}

		return size;
	}

        下面是通过position寻找子类的方法。


                                                       

       假如上面的数据的第一个结点的子点被隐藏了,那么树形数据的数目变成了5,而有些结点的索引也发生了改变。

        我们根据索引值i进行寻找数据,如果i==3:

                            1.第0个点不对,那进入第一个子树,i需要减少1。   i = 2

                            2.第1个节点的子结点为零,     2 - 0 -1 > 0 进入第2个节点,  i =  i - 1 =1;

                            3.第二个节点的子树数目为 2,1 - 2 - 1 < 0  进入第2个节点的第一个子节点, i =  i - 1 =0;

                            3.第2个节点的第一个子节点     i  = 0; 找到了。


                           原则:1.判断i==0? 等于0说明找到了;

                                      2.进入子树 i--;

                                      3.进入兄弟减去子树的数目(包括子树和子树下面的所有节点);

       /**
	 * 通过索引值寻找子类信息
	 * 
	 * @param index
	 * @return
	 */
	public TreeNode findItemById(int index) {
		int secondIndex = index;
		int size = child.size();
		TreeNode node = null;
		for (int i = 0; i < size; i++) {
			// 判断当前索引是否为0
			if (secondIndex == 0) {
				node = child.get(i);
				break;
			}

			// 判断第二索引值和第i项item的子类数目
			int reduce = secondIndex - child.get(i).getChildSize() - 1;
			if (reduce >= 0) {
				// 如果大于,继续寻找
				secondIndex = reduce;
			} else {
				// 如果小于,寻找子类的子类
				node = child.get(i).findItemById(secondIndex - 1);
				break;
			}
		}

		return node;
	}

          这两个方法已经介绍完毕,它们会被运用与adpater的getItem()和getCount()两个函数中去,listview的getview改怎么写怎么写,不用管多少级。当你点击的时候,改变当前item对应数据的isOpenChild的值,然后刷新一下列表。





欢迎大家多评论、多交流共同进步

发布了2 篇原创文章 · 获赞 5 · 访问量 1万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览