Android中的多级可扩展ListView

10
我正在尝试从给定的未知大小和级别的类别列表中创建一个类别树。因此,我正在尝试创建一个通用的可扩展列表,可以包含2个或更多级别。
一般的想法是在每个具有子项的子项中添加另一个ExpandableListView。问题在于第二级不会打开,看起来好像它将其渲染在子项上方或其他位置。以下是结果的一些屏幕截图:
这是在打开之前的样子
这是在打开第一个选项后的样子(应该是空的)

enter image description here

现在打开第二个:(有4个子元素,其中一个拥有自己的子元素)

enter image description here

正如您所看到的,第三个选项似乎已经被渲染成了另一个选项或者在其上添加了一些内容,在单击打开它后:

enter image description here

这段代码除了改变箭头的状态外,没有做任何事情。至少它试图打开它...

以下是代码:

CatAdapter.java: (继承自BaseExpandableListAdapter) http://pastebin.com/6yUTkMbJ

Category.java: http://pastebin.com/E7yWwpna

catitem.xml: http://pastebin.com/G5MPT3Ua

使用方法: http://pastebin.com/Wk0FqJhn 抱歉问题有点长,我尽可能清楚明了。
提前感谢!对不起我的英语不好!
编辑:
最终我为此任务创建了一个自定义视图,感谢大家的回答!

嗨,你介意分享一下你成功制作的自定义视图吗?或者说你能分享一下你的做法吗? - Rat-a-tat-a-tat Ratatouille
1
你解决了你的问题吗?我也有同样的问题stackoverflow.com/questions/18765638/… 如果你已经解决了你的问题,请帮助我。 - Cropper
我已经成功解决了问题,创建了一个自定义视图并实现了自定义的OnDraw()方法。 - UnTraDe
你能更新一下你自定义视图的代码并/或者解释一下你的解决方案吗?我有点绝望了。我的三级可扩展列表视图没有按预期工作,我似乎漏掉了什么。我在getChild中填充的第二个列表行与父行不匹配,并且在单击任何节点时也遇到了一些麻烦...非常感谢您的帮助! - cesards
很抱歉,我很久以前就丢失了这段代码。但基本上你只需要实现自己的自定义视图并通过覆盖onDraw()方法来绘制所有内容,你可以在Android官方文档中阅读相关内容。 - UnTraDe
2个回答

7
我认为问题在您的getChildView()方法中:
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {

            convertView = inflater.inflate(R.layout.catitem, parent, false);
            TextView textView_catName = (TextView)convertView.findViewById(R.id.textView_catName);
            Category current = categories.get(groupPosition).childs.get(childPosition);
            textView_catName.setText(groupPosition + " , " + childPosition);

            if(current.childs.size() > 0 ) {
                    ExpandableListView elv = new ExpandableListView(context);
                    elv.setLayoutParams(new AbsListView.LayoutParams(AbsListView.LayoutParams.WRAP_CONTENT,  AbsListView.LayoutParams.WRAP_CONTENT));
                    elv.setAdapter(new CatAdapter(context, current.childs));
                    ((ViewGroup)convertView).addView(elv);
            }

            return convertView;
    }

当您遇到一个“可展开”的子元素时,您仍然会膨胀R.layout.catitem并将您的新elv添加到其中。由于catitem是一个RelativeLayout,您没有添加任何对齐参数,每个视图都放置在左上角,覆盖其他内容。
您可能想尝试将R.layout.catitem更改为具有垂直LinearLayout作为其根。这应该可以防止它们重叠子标题,但我不能保证子级的子级不会仍然重叠。不过这是一个简单的更改,值得一试。
此外,在ExpandableListView的文档中也有说明:
注意:如果父容器的大小也没有严格指定(例如,如果父容器是ScrollView,则无法在XML中使用android:layout_height属性的wrap_content值,因为它也可以是任意长度。但是,如果ExpandableListView父容器具有特定大小,例如100像素,则可以使用wrap_content。
这是说“在XML中”,所以我不确定是否适用于代码。我认为他们会使用相同的机制,所以它可能值得研究。我不确定如何设置父级的最大大小。您可以测量一个项目的大小,并乘以子项的数量。您必须考虑边距/分隔符,因此可能并不简单。
如果这行不通,您可能需要直接滚动自己的ViewGroup。从头开始实现它应该不难,只是不要忘记尝试利用视图回收(您当前的方法也没有执行)。

非常感谢您的回答!我会尝试您建议的方法,并告诉您它是否有效。 - UnTraDe
好的,我已经按照你建议的使用LinearLayout进行了测试,它确实解决了我的重叠视图问题。但是现在我仍然无法打开第二层以下的子项(父->子),就像在ExpandableListView中通常可以打开父项的子项一样,但我无法打开子项的子项。你有任何解决办法吗?提前感谢! - UnTraDe
你能否记录日志以查看是否已经注册了点击事件?你可能需要手动在每个项目上调用 setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS) 以允许点击事件通过。有时候,ListView 对于触摸优先级的处理比较奇怪。 - Geobits

2
我曾经遇到过同样的情况,需要使用ExpandableList,并且在每个级别上都需要groupPositionchildPosition,但是使用多级ExpandableList时,无法准确获取第二级数据的groupPosition。因此,我采用了另一种方法。我提供了一个演示链接,该链接在项目中使用。
1)在这个库中,你需要在绑定实际数据之前预先绑定父子关系。 2)在你的Layout中,顶层布局必须是LinearLayout。请参考演示链接中的header.xmlgroups.xmlchilds.xml
演示链接:MultiLevelTreeView 谢谢。

我正在寻找一个更易于管理的代码和在视图被点击时能够准确地给出所有groupPositionchildPosition的“可扩展列表”。谢谢,你让我的一天。 - user744881
@Abhan 在 ThreeLevelAdapter 类中的 updateView 方法中出现了一个错误信息 Header不能被解析或不是字段. - Gödel77
抱歉,我需要一个提示来处理第三级复选框。是否有必须重写的方法? - nurgasemetey
@SudheeshMohan 是的,不幸的是整个代码库都被删除了。对此给您带来的不便深感抱歉。我相信您可以在这里找到类似的开源项目:http://android-arsenal.com/free。 - user456118
@nurgasemetey 不是特定的方法,但在适配器层面上,您可以管理任何小部件。试一试。查看此链接 https://github.com/Polidea/tree-view-list-android。 - user456118
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接