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

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

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

                                                                                 

android多级下拉列表菜单 安卓多级列表_子类

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

下面是我的数据模型。

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寻找子类的方法。



                                                       

android多级下拉列表菜单 安卓多级列表_子树_02

节点被隐藏了,那么树形数据的数目变成了5,而有些结点的索引也发生了改变。

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

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

进入第2个节点,  i =  i - 1 =1;

进入第2个节点的第一个子节点, i =  i - 1 =0;

第2个节点的第一个子节点


                           原则: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的值,然后刷新一下列表。





android多级下拉列表菜单 安卓多级列表_子树_03




android多级下拉列表菜单 安卓多级列表_android多级下拉列表菜单_04


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