Once upon a time I wrote a nice little post about checkbox focus problems. The guy who originally asked the question was satisfied and went away. While I was looking the other way, a heated discussion started in the comments because the example program had an annoying property: it did not preserve the state of the check boxes when the groups were opened/collapsed but reordered the check marks randomly. Eventually I got a mail whether I could put my example program right.
Click here to download the example program.
So I did. The cause of the trouble was the adapter backing the expandable list view. It was a SimpleExpandableListAdapter which, as its name implies, is simple. In particular, it is not able to feed data to check boxes because they require boolean state while SimpleExpandableListAdapter supports only Strings (here is a posts that explains the relationship between views and adapters). The solution was to write a custom ExpandableListAdapter and the random check mark reordering disappeared.
Subscribe to:
Post Comments (Atom)
69 comments:
could you please please upload the correct code using the custom ExpandableAdapter? I keep on getting error trying to do it myself and don't understand what's causing the problem. It would be a great help if you could provide a solution code for the above example.
Anonymous, please download the example program from the link in the post. It says: "Click here to download the example program."
I have just checked, the example program can be downloaded and executes correctly on the emulator.
This code still does not work. Tried the following. Loaded in the emulator. Expanded the first two groups. Selected one child of the second group. Un-expanded, then re-expanded the first group. Notice the second group's children check boxes change.
Appreciate the effort though! This has been the best resource for this stuff out there.
Anonymous, the example program does exactly it is supposed to do. It demonstrates, how the expandable list can be backed by an expandable list adapter.
What the example program does not do is the update of the adapter's data based on user's interaction. Whatever you do, if you collapse and then reopen a group, you get back the original checkbox state. Implement a logic that updates the adapter's data in the main activity's onChildClick, it is easy to do.
Hi, Could some one please assist, how to create an expandable list for sub items, Lets take the same example which is explained. In that under the "grey" , each sub-item like "lightgrey", "dimgrey".. should expand and close, and if we close the top item "grey", all the sub-items should be closed in case if it is expanded.
Thanks in Advance.
Senthil, ExpandableList is hardcoded to handle only 2 levels therefore you cannot implement multi-level expandable list with manipulating the adapter.
Thanks for your reply, I have a specific requirement which has to be implemented in that way.
Is there any other way to acheive that.?
Any suggestions would be really helpful
Senthil, get ExpandableListView.java from the Android source tree and enhance it to support your requirement (you have to move it to your own package, out of android.widget).
Using a third-party component would be easier but I am not aware of any.
Thanks for your suggestion, Keep updating if you come across any such.
Thx alot...exactly what i was looking 4.. :)
Hi Gabor, I have tried multiple ways, but couldn't acheive the multi level expandable list.
Can you please provide any thrid party solution if you have, or can you give some detail insight.
Thanks in Advance.
What if you added another expandable list as a child row?
It looks like the server is down and I can not download the code :(
Can we place a check box in group row?
the code is working but i m unable to set the indicator(grey lefthand side).....what i supposed to do????
Anonymous, what do you mean by "setting the indicator"? Do you want to have a custom collapse indicator?
Hi, i have the same question with @bharath, i've tried that but, the group can not be clicked, except the Button or CheckBox it's self,
you have an idea ?
thank you very much, you save my day :D
Hi,
Thanks for the article.
Can you please show or guide me how to use more than 1 expandable lists on the activity.
Thanks in advance.
Amit, you can just put more than one ExpandableListView into the Activity's layout. Also, don't extend ExpandableListActivity, extend simple Activity and register the listeners directly on the ExpandableListView instances.
I'm having trouble with the code as well.
For some reason, I'm getting errors in ColorAdapter. On the line that says "color.setText( c.getColor() );" i get the error: "the method getColor is undefined for type Color". I get the same error for the lines "rgb.setText( c.getRgb() );" with getRgb and "cb.setChecked( c.getState() );" with getState().
Likewise, I'm getting an error in the ExpListActivity on all the lines that say "color.add( new Color( "...","...", false ) );"....The error says "The constructor (String, String, bollean) is undefined"
What's up with all this? It seems like Color isn't working right?
Anonymous, did you insert the code into some other program? Then there is a chance that some other Color from a different package messes up with our Color. You can rename the Color class to something else and see if the problem persists.
Never mind. I figured out the problem. I had copied and pasted your code for the activity before I ever created the Color class, so Eclipse was giving me an error and asking me if I want to import the Color class (a different Color class), which I stupidly said "ok" to. Then it was doing the import, and when I created the Color class, my created class wasn't being used.
Thanks for your response!
I have been working with the expandableList and cannot find a way to delete/add groups on the fly. Could you give me some advice and direction please? Thanks
You can use long click to activate context menu.
Thanks for the code! I'm using it in my program. Everything works OK, but I add several columns to the list. All columns doesn't fit the screen. How can I use horizontal scroll or some of the trick?
This doesn't works perfecty becouse when you click on checkbox,activity onChildClick method isn't called.
Use a ImaView instead and set imgaseresource like this
*** ColorAdapter method
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
View v = null;
if( convertView != null )
v = convertView;
else
v = inflater.inflate(R.layout.child_row, parent, false);
ColorBean colorBean = (ColorBean)getChild( groupPosition, childPosition );
ImageView check = (ImageView)v.findViewById( R.id.imageView1 );
if(colorBean.getState()==true)
check.setImageResource(android.R.drawable.checkbox_on_background);
else
check.setImageResource(android.R.drawable.checkbox_off_background);
TextView colorText = (TextView)v.findViewById( R.id.childname );
if( colorText != null )
colorText.setText( colorBean.getColor() );
TextView rgbText = (TextView)v.findViewById( R.id.rgb );
if( rgbText != null )
{
rgbText.setText( colorBean.getRgb() );
rgbText.setBackgroundColor(colorBean.getState()?Color.parseColor(colorBean.getRgb()):Color.TRANSPARENT);
}
return v;
}
*** ExpandableListActivity
public boolean onChildClick(
ExpandableListView parent,
View v,
int groupPosition,
int childPosition,
long id) {
Log.d( LOG_TAG, "onChildClick: "+childPosition );
ColorBean color = (ColorBean) expListAdapter.getChild( groupPosition, childPosition );
color.setState(!color.getState());
expListAdapter.notifyDataSetChanged();
TextView rgbText = (TextView)v.findViewById( R.id.rgb );
rgbText.setBackgroundColor(Color.TRANSPARENT);
return super.onChildClick(parent, v, groupPosition, childPosition, id);
}
Hi ,
I need a sticky header to be created inside Expandablelistview.
Any suggestions on it.
Its basically like a separated list view,when each item is expanded
Anonymnous, your solution is perfetc. Thanks!
Muito obrigado
Hi guys,
how can i save and load the state of checkbox when i pass from an activity to another one?
Thanks
Thanks for the tutorial. I was able to learn a lot and change it around for a program that I am writing. I am having trouble figuring out how to keep the state change of the checkbox. I am thinking have a method at the bottom of ElistCBox when the checkbox is clicked that uses getState and then add a method changeState. The problem I am having is when I declare Color c at the method I added in ElistCBox, I need to assign it a position, but cannot figure out how to assign it a position. Am I on the right track and if I am how would I find the position.
I figured out the problem I was having in my last post. I don't know if it is because I changed around the code or it is an error in the program, but if you click on the test instead of the checkbox, the checkbox changes state and it holds when you expand and shrink the parent. Now I have to figure out how to have that work when the checkbox is clicked
I figure out how to get the onChildClick to respond when clicked. In the XML you need to enter for the checkbox android:clickable="false"
PLS GUYS!!!
HELP ME HERE:
http://stackoverflow.com/questions/9361600/android-custom-expandeble-list-and-checkbox-issue-why-is-chechbox-state-random
i cant implement a custom expandable list. I solved checkbox state problem, but now when i click on a parent node and child is shown, parent nodes swith their position. When all node are expanded, each node is in the right position. ITS INCREDIBLE !!! WHYYY
hheeeelppppp
kinghomer, you don't seem to set the checkbox state in getGroupView() method. If you don't set any field in a row, view recycling may set it up with random value.
Could you revisit page?
When I try to import this project in Eclipse I got a message like this: No projects are found to import.
Can you help me with this problem, please?
andreea, this project is not an eclipse project but a plain Android SDK project. In order to make an Eclipse project based on it, click New/Android project then choose the "Create project from existing source" option.
Your solution was good, but now I have an other error: AndroidManifest.xml file missing!
:(
andreea, I imported the project and there was no error. Did you select the top directory of the project in the "Location" input field of the import dialog? You should find an AndroidManifest.xml file in that directory.
Finally I succeed to import the project. Thank you so much for your help and for the project.
I have been looking through the code. I cannot tell what piece of code executes when you click on the button by grey, blue, etc. What piece of code expands the menu?
Aaron, that code is inside the ExpandableListView class.
Gabor, thanks. I needed to find a way to control when the group was clicked on. Looked up the ExpandableListView on the android site and figured it out.
Thanks for posting this code! I am using it successfully. I am new to Android programming and was wondering how to have the checkboxes be checked, based on database content. Currently, I update the arrays when the chekboxes are checked or unchecked and then re-bind the adapter. I need a way to have the values be check if there is data in the database. Any ideas how to check the checkboxes once they have been rendered? Thanks again. Almost there!
Thanks for this solution ,i have implemented based on your solution i got everything.now i have to implement mutipleselction thing .and how can i searchbox can be implement in expandible can you please elaborate how to do this.
Hi Gabor,
Thanks a lot...
hello,
you have given very good example but can you tell me how can i maintain checkbox selection ! because when i uncheck/check and then select another parent item, my selection reset at starting bind items. :(
i change your 'cb.toggle();' to below but not working !!
if( cb != null ){
if(cb.isChecked()){
cb.setChecked(false);
}else
{
cb.setChecked(true);
}
}
Please solve it.!
This post is very instructive, thanks!!!
thank you for this great post :)
i have a problem here : i understand now how you can save the original states of the checkboxes but how can i maintain checkbox selection ! what should i do in onChildClick() method? i think that i must rebind the adapter ...but i can't find a way to do it!
please give me what should i do
Hi, Seyfeddine,
The example program takes the description of the list elements from a two-level list structure.
ArrayList> colors = new ArrayList>();
Second-level lists store Color instances that have a field variable called "state". That field is used to initialize the checkbox states.
Now this example program does not feed back checkbox state changes into this structure. So what you should do in onChildClick is to update the "state" field of the appropriate instance. When the Activity dies, save the state list in onSaveInstanceState. Restore this state into that list in onCreate if that method is called with a non-null Bundle parameter (that Bundle will give you back the state you saved in onSaveInstanceState).
Hi Gabor,
thank you for your answer, but i'm not talking about the states after the activity die but about saving the states after unexpanding the parentrow ... i added a method called setState in Color.java class and i added this code in onChildClick() method:
public boolean onChildClick(
ExpandableListView parent,
View v,
int groupPosition,
int childPosition,
long id) {
Log.d( LOG_TAG, "onChildClick: "+childPosition );
CheckBox cb = (CheckBox)v.findViewById( R.id.check1 );
Color c = (Color)getChild( groupPosition, childPosition );
if( cb != null ){
if (c.state==true){
cb.setChecked(false);
c.setState(false);
}
else
{
cb.setChecked(true);
c.setState(true);
}
}
but nothing is changing ! help :/
Hey Man!
i found a solution you must make difference between clicking on checkbox and clicking on the childrow ! so let's make it editable just from the onChildClick() method just by editing the child_row.xml file :
thank you man ;)
Hi,
I customized your code and add to checkbox feature, but there is a problem and i'm going to be crazy to solve it.
I want to check all checkbox from the parent root group but it does check one.
Could you help me on this issue?
Thank you so much.
The Customize Android project link : https://mega.co.nz/#!tw8gjJ5Y!XDYFvTYBObRJUVa2dLAGxTMtXBcwYpOvY4nfejt7U40
Bhai Na avadtu hoy to blog na lakhaso pan ramado nahi please yaar time waste thay chhe !!!!
When i am clicking on child class it is setting the checkboxes. can you help me to work on checkboxes. I want if i will click on checkbox it will show the group position as well as child position.
Jayashree Behera, please check the comments, particularly the ones from Seyfeddine Aloui.
Gabor Paller ... thanx for considering my comments. Actally i want to click on checkboxes not in child position.
Jayashree Behera, so where are those check boxes? In group level position or outside the expandable list?
Gober Paller thanx for responding my comment... my check box is in child class.
Gober Paller Please help me it's very urgent i want to click on checkbox of child class.
Gober Paller Please help me it's very urgent i want to click on checkbox of child class.
Gober Paller Please help me it's very urgent i want to click on checkbox of child class.
This is not working well if you select few checkboxes and scroll the list. If you scroll back again the list shows the older state. It does not persist new selections. Any suggestion on that?
Can you comment or advice to decide my problem. Similar to your post funcionality. My problem in this link: http://stackoverflow.com/questions/37100732/expandablelistview-with-checkboxes-display-in-dialog .
ANYONE KNOWS HOW TO LIMIT THE TEXT BOX SELECTION IN EXPANDABLE LIST VIEW ?
FOR EG:-
ONE 2 BOXES OUT OF FIVE SHOULD BE SELECTED FROM THE PARENT CELLS AND IF WE CLICK ON THE THIRD IT SHOULD DISPLAY TOAST OR SOMETHING SAYING LIMIT REACHED ONLY 2 CAN BE SELECTED ..
PLZZ HELP ....
Post a Comment