Multi-level ExpandableListView in Android
Asked Answered
R

2

10

I'm trying to create a category tree from a given unknown-size nor level list of categories. So I'm trying to create a general expandable list which can contain 2+ number of levels. The general idea is to add to every child who has childs another ExpandableListView in it's layout. The problem is that the second level wont open, it looks like it rendered it over the child or something. Here's some screen-shots of the result:

Here's how it's look like before openingenter image description here

And after opening the first option: (It's supposed to be empty)

enter image description here

And now open the second one: (Has 4 childs and one of them have childs of his own)

enter image description here

As you can see the third option looks like it's been rendered another option or something on it, after clicking to open it:

enter image description here

It's does nothing except change the state of the arrow. At least it tries to open it...

Here's the code:

CatAdapter.java: (extends BaseExpandableListAdapter) http://pastebin.com/6yUTkMbJ

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

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

The usage: http://pastebin.com/Wk0FqJhn

Sorry for the long question, I was trying to be clear as possible.

Thanks in advance! Sorry for my bad english!

Edit:

I ended up making a custom view for this task, thank you all for your answers!

Rough answered 21/7, 2013 at 12:28 Comment(5)
Hi, do you mind sharing the piece of custom view that you managed to make or probably share in as to what you did?Moskva
Have u solved ur problem I have also same problem stackoverflow.com/questions/18765638/… If u have solved ur problem please help me.Slating
I have managed to solve the problem creating a Custom View and implement custom OnDraw().Rough
Can you update your code of your custom view and/or explain a little bit your solution plz? I'm a little bit desperate. I'm missing something because my 3 level expandable listview doesn't work as expected. The second list rows I inflate in getChild doesn't match the parent and I have some troubles too during click on any node... Thank you so much in advance!Antre
I lost this piece of code alot time ago, sorry. But basically you just need to implement your own custom view and draw everything by overriding onDraw(), you can read about it in the android official documentation.Rough
L
7

I believe the problem is in your getChildView() method:

    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;
    }

When you encounter an 'expandable' child, you are still inflating R.layout.catitem and adding your new elv to it. Since the catitem is a RelativeLayout and you don't add any parameters for alignment, each view is placed at the top-left corner, overlaying whatever else is there.

You may want to try changing R.layout.catitem to have a vertical LinearLayout as its root. This should prevent them from overlapping the child's title, but I can't guarantee that the children's children will not still overlap. It's an easy change, though, and worth a shot.


Also, from the docs for ExpandableListView:

Note: You cannot use the value wrap_content for the android:layout_height attribute of a ExpandableListView in XML if the parent's size is also not strictly specified (for example, if the parent were ScrollView you could not specify wrap_content since it also can be any length. However, you can use wrap_content if the ExpandableListView parent has a specific size, such as 100 pixels.

That says "in XML", so I'm not sure if it means to apply to code or not. It seems to me that they'd use the same mechanism, so it might be worth looking into. I'm not sure how you'd go about setting a maximum size for the parent. You may be able to measure the size of one item, and multiply by the number of children. You'd have to take margins/separators into account, so it may not be simple.


If that doesn't work, you may need to roll your own ViewGroup directly. It shouldn't be too hard to implement it from scratch, just don't forget to try to take advantage of view recycling(which your current method doesn't do anyway).

Lynnlynna answered 24/7, 2013 at 18:27 Comment(3)
Thanks alot for your answer! I'll try what you suggested and let you if it worked.Rough
Ok, I tested what you suggested with the LinearLayout and it indeed solved my problem with the overlapped views. But now I still cant open further than the second level (Parent->Children) works as usual in an ExpandableListView but I cant open the child's childs. Do you have any idea how to solve this? Thanks in advance!Rough
Can you log to see if the click is even being registered? You may need to manually call setDescendantFocusability(FOCUS_BLOCK_DESCENDANTS) on each item to allow the click to get through. ListViews are weird about touch priority sometimes.Lynnlynna
A
2

I was have same situation where I had to use ExpandableList and at each level I needed to have groupPosition and childPosition but using multi-level ExpandableList, It was not possible to get accurate groupPosition at second level data. So that, I used another approach. I have given a demo link which I used in a project.

1) In this library, you need to bind parent child relation in advance before you bind your actual data. 2) In your Layout, top most layout must be LinearLayout. Please refer header.xml, groups.xml and childs.xml in demo link.

Demo Link: MultiLevelTreeView

Thanks.

Aland answered 25/7, 2013 at 15:6 Comment(7)
I was looking for Expandable List which has more manageable code and gives me all groupPosition and childPosition accurately when the view gets clicked. Thanks, You made my day.Lashoh
Great library. One of the first I tried that works on more than three levelsKathleenkathlene
@Abhan There is an Error Message Header cannot be resolved or is not a field in ThreeLevelAdapter Class in Method updateView.Unwarrantable
@Gödel77 For Layout, Root view must be Linear Layout. Second thing as per your requirement you need to specify layout in getNewChildView method and initialize your views in updateView. For better understanding run demo or debug.Aland
Sorry, I need a hint handle checkboxes in 3rd level. Is there a method that I must override?Desiredesirea
@SudheeshMohan Yes unfortunately whole repository removed. Sorry for the inconvenience. I am sure you will get kind of open source project from here android-arsenal.com/free.Aland
@Desiredesirea Not particular method but in adapter level wise you can manage any widget. Give a try. Check this out github.com/Polidea/tree-view-list-android.Aland

© 2022 - 2024 — McMap. All rights reserved.