[android-developers] Re: ListView setAdapter in onCreate, getChildCount is zero in onStart?
Here is what I ended up with. Do you guys care to grade this on an A to F scale. I'm all of a sudden wondering when the startManagingCursor (c); is going to slam my cursor shut, rendering this code broken. I guess I could always read the Cursor into an Array and use that for my adapter. When does the crazy *stop*? private void preCheck(ListView list) { // if an entry is in the database, check it SimpleCursorAdapter adapter = (SimpleCursorAdapter) list.getAdapter (); int rows = adapter.getCount(); for (int i = 0; i < rows; i++) { adapter.getCursor().moveToPosition(i); String clickedPK = adapter.getCursor().getString(0); Log.d("preCheck()", clickedPK); if (keyInStupidExtraDataBase()) { list.setItemChecked(2, true); } } } On Oct 27, 5:00 pm, stanlick wrote: > Thanks brothers -- > > I like the idea of the selected state of the data being in the > adapter, however, I'm not too excited about all the custom code for > such an obvious requirement! I am using a ListActivity subclass > configured as follows: > > setListAdapter(buildNameAdapter()); > ListView list = getListView(); > list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); > list.setOnItemClickListener(this); > preCheck(list); > > The adapter is a SimpleCursorAdapter instantiated as follows > > private ListAdapter buildNameAdapter() { > String[] PROJECTION = new String[] { Contacts.People._ID, > Contacts.PeopleColumns.NAME }; > Cursor c = managedQuery(Contacts.People.CONTENT_URI, > PROJECTION, > null, > null, Contacts.People.DEFAULT_SORT_ORDER); > > startManagingCursor(c); > adapter = new SimpleCursorAdapter(this, > > android.R.layout.simple_list_item_multiple_choice, c, > new String[] { Contacts.PeopleColumns.NAME }, > new int[] { android.R.id.text1 }); > return adapter; > } > > Where I stuck the adapter in the list and thought life would be good. > Now I am sitting here with my cursor blinking in the preCheck(...) > method wondering what the hell to do to have an entry(s) pre-checked! > It appears I can either loop through the adapter/list and manipulate > the list view (as per Mark) or muck around with the Cursor in order to > add a SelectableString custom type to the adapter *and* override > callback methods to check the entries which have their > (selectableString.isSelected()==true values. The basic idea of > wanting a list of items either checked/unchecked seems like one where > none of this hand-coding should be necessary. This all started when I > was looking for a way to add *one* extra checkbox to the basic contact > info! Now I'm writing myself a small mountain of code because > associating a single "extra" element with a contact is harder than > pulling teeth. > > Does it sound like I am disappointed? Didn't we put a man on the > moon? > > P.S. Thanks for the help you guys. Rolling up my sleeves now and > cracking open a cold brew. Perhaps I'll flip a coin on this one. > > Peace, > Scott > > On Oct 27, 10:57 am, Streets Of Boston > wrote: > > > Put the data whether a checkbox of a list-item is selected inside the > > *adapter's* data, like my example i gave you in an earlier post > > (selectableString.isSelected). > > > If you want to pre-select a check-box of a list-item, set its > > corresponding element in the adapter (SelectableString) as selected > > (selectableString.isSelected = true). Then, if you want to show this > > on the screen, call notifyDatasetChanged() on your adatper. > > > If you implemented your adapter's getView correctly, you'd see the > > checkbox becoming checked. > > Example code (won't compile): > > > public MyAdapter extends BaseAdapter { > > private List mData = new > > ArrayList(); > > ... > > > // example methods. > > public void selectSoundTableItem(int position, boolean select) { > > mData.get(position).isSelected = select; > > notifyDatasetChanged(); > > } > > > public void setSoundData(Map soundTable) { > > mData.clear(); > > for (String soundName : soundTable.keySet()) { > > SelectableString ss = new SelectableString(); > > ss.soundTableName = soundName; > > ss.soundId = soundTable.get(soundName); > > mData.add(ss); > > } > > notifyDatasetChanged(); > > } > > > public void preselectSoundData(SharedPreferences prefs) { > > String[] selectedSoundsArray = > > prefs.getString("selectedSounds",
[android-developers] Re: ListView setAdapter in onCreate, getChildCount is zero in onStart?
Thanks brothers -- I like the idea of the selected state of the data being in the adapter, however, I'm not too excited about all the custom code for such an obvious requirement! I am using a ListActivity subclass configured as follows: setListAdapter(buildNameAdapter()); ListView list = getListView(); list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); list.setOnItemClickListener(this); preCheck(list); The adapter is a SimpleCursorAdapter instantiated as follows private ListAdapter buildNameAdapter() { String[] PROJECTION = new String[] { Contacts.People._ID, Contacts.PeopleColumns.NAME }; Cursor c = managedQuery(Contacts.People.CONTENT_URI, PROJECTION, null, null, Contacts.People.DEFAULT_SORT_ORDER); startManagingCursor(c); adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_multiple_choice, c, new String[] { Contacts.PeopleColumns.NAME }, new int[] { android.R.id.text1 }); return adapter; } Where I stuck the adapter in the list and thought life would be good. Now I am sitting here with my cursor blinking in the preCheck(...) method wondering what the hell to do to have an entry(s) pre-checked! It appears I can either loop through the adapter/list and manipulate the list view (as per Mark) or muck around with the Cursor in order to add a SelectableString custom type to the adapter *and* override callback methods to check the entries which have their (selectableString.isSelected()==true values. The basic idea of wanting a list of items either checked/unchecked seems like one where none of this hand-coding should be necessary. This all started when I was looking for a way to add *one* extra checkbox to the basic contact info! Now I'm writing myself a small mountain of code because associating a single "extra" element with a contact is harder than pulling teeth. Does it sound like I am disappointed? Didn't we put a man on the moon? P.S. Thanks for the help you guys. Rolling up my sleeves now and cracking open a cold brew. Perhaps I'll flip a coin on this one. Peace, Scott On Oct 27, 10:57 am, Streets Of Boston wrote: > Put the data whether a checkbox of a list-item is selected inside the > *adapter's* data, like my example i gave you in an earlier post > (selectableString.isSelected). > > If you want to pre-select a check-box of a list-item, set its > corresponding element in the adapter (SelectableString) as selected > (selectableString.isSelected = true). Then, if you want to show this > on the screen, call notifyDatasetChanged() on your adatper. > > If you implemented your adapter's getView correctly, you'd see the > checkbox becoming checked. > Example code (won't compile): > > public MyAdapter extends BaseAdapter { > private List mData = new > ArrayList(); > ... > > // example methods. > public void selectSoundTableItem(int position, boolean select) { > mData.get(position).isSelected = select; > notifyDatasetChanged(); > } > > public void setSoundData(Map soundTable) { > mData.clear(); > for (String soundName : soundTable.keySet()) { > SelectableString ss = new SelectableString(); > ss.soundTableName = soundName; > ss.soundId = soundTable.get(soundName); > mData.add(ss); > } > notifyDatasetChanged(); > } > > public void preselectSoundData(SharedPreferences prefs) { > String[] selectedSoundsArray = > prefs.getString("selectedSounds", "").split(","); > > for (SelectableString ss : mData) { > ss.isSelected = false; > } > > for (int selI = 0; selI < selectedSoundsArray.length; selI++) { > SelectableString ss = findItem(mData,selectedSoundsArray > [selI]); > ss.isSelected = true; > } > notifyDatasetChanged(); > } > > // below are the methods from BaseAdapter you need to implement: > // getCount(), getItem(int position), etc. > ... > public Object getItem(int position) { > return mData.get(position); > } > ... > ... > > // Called by your attached ListView when it's about to create/re- > use a visible item. > // The ListView calls this method. Your code should not call it. > public View getView(int position, View convertView, ViewGroup > parent) { > ... // use convertView or create/inflate a new one when it's > null. // > ... > > SelectableString ss = (SelectableString)getItem(position); > > // may help you find back the soundTableItem in onClick methods > by calling 'getTag()' > convertView.setTag(new Integer(ss.soundId)); > > String soundName = ss.soundName; > TextView
[android-developers] Re: ListView setAdapter in onCreate, getChildCount is zero in onStart?
Thanks brothers -- I like the idea of the selected state of the data being in the adapter, however, I'm not too excited about all the custom code for such an obvious requirement! I am using a ListActivity subclass configured as follows: setListAdapter(buildNameAdapter()); ListView list = getListView(); list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); list.setOnItemClickListener(this); preCheck(list); The adapter is a SimpleCursorAdapter instantiated as follows private ListAdapter buildNameAdapter() { String[] PROJECTION = new String[] { Contacts.People._ID, Contacts.PeopleColumns.NAME }; Cursor c = managedQuery(Contacts.People.CONTENT_URI, PROJECTION, null, null, Contacts.People.DEFAULT_SORT_ORDER); startManagingCursor(c); adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_multiple_choice, c, new String[] { Contacts.PeopleColumns.NAME }, new int[] { android.R.id.text1 }); return adapter; } Where I stuck the adapter in the list and thought life would be good. Now I am sitting here with my cursor blinking in the preCheck(...) method wondering what the hell to do to have an entry(s) pre-checked! It appears I can either loop through the adapter/list and manipulate the list view (as per Mark) or muck around with the Cursor in order to add a SelectableString custom type to the adapter *and* override callback methods to check the entries which have their (selectableString.isSelected()==true values. The basic idea of wanting a list of items either checked/unchecked seems like one where none of this hand-coding should be necessary. This all started when I was looking for a way to add *one* extra checkbox to the basic contact info! Now I'm writing myself a small mountain of code because associating a single "extra" element with a contact is harder than pulling teeth. Does it sound like I am disappointed? Didn't we put a man on the moon? P.S. Thanks for the help you guys. Rolling up my sleeves now and cracking open a cold brew. Perhaps I'll flip a coin on this one. Peace, Scott On Oct 27, 10:57 am, Streets Of Boston wrote: > Put the data whether a checkbox of a list-item is selected inside the > *adapter's* data, like my example i gave you in an earlier post > (selectableString.isSelected). > > If you want to pre-select a check-box of a list-item, set its > corresponding element in the adapter (SelectableString) as selected > (selectableString.isSelected = true). Then, if you want to show this > on the screen, call notifyDatasetChanged() on your adatper. > > If you implemented your adapter's getView correctly, you'd see the > checkbox becoming checked. > Example code (won't compile): > > public MyAdapter extends BaseAdapter { > private List mData = new > ArrayList(); > ... > > // example methods. > public void selectSoundTableItem(int position, boolean select) { > mData.get(position).isSelected = select; > notifyDatasetChanged(); > } > > public void setSoundData(Map soundTable) { > mData.clear(); > for (String soundName : soundTable.keySet()) { > SelectableString ss = new SelectableString(); > ss.soundTableName = soundName; > ss.soundId = soundTable.get(soundName); > mData.add(ss); > } > notifyDatasetChanged(); > } > > public void preselectSoundData(SharedPreferences prefs) { > String[] selectedSoundsArray = > prefs.getString("selectedSounds", "").split(","); > > for (SelectableString ss : mData) { > ss.isSelected = false; > } > > for (int selI = 0; selI < selectedSoundsArray.length; selI++) { > SelectableString ss = findItem(mData,selectedSoundsArray > [selI]); > ss.isSelected = true; > } > notifyDatasetChanged(); > } > > // below are the methods from BaseAdapter you need to implement: > // getCount(), getItem(int position), etc. > ... > public Object getItem(int position) { > return mData.get(position); > } > ... > ... > > // Called by your attached ListView when it's about to create/re- > use a visible item. > // The ListView calls this method. Your code should not call it. > public View getView(int position, View convertView, ViewGroup > parent) { > ... // use convertView or create/inflate a new one when it's > null. // > ... > > SelectableString ss = (SelectableString)getItem(position); > > // may help you find back the soundTableItem in onClick methods > by calling 'getTag()' > convertView.setTag(new Integer(ss.soundId)); > > String soundName = ss.soundName; > TextView
[android-developers] Re: ListView setAdapter in onCreate, getChildCount is zero in onStart?
Put the data whether a checkbox of a list-item is selected inside the *adapter's* data, like my example i gave you in an earlier post (selectableString.isSelected). If you want to pre-select a check-box of a list-item, set its corresponding element in the adapter (SelectableString) as selected (selectableString.isSelected = true). Then, if you want to show this on the screen, call notifyDatasetChanged() on your adatper. If you implemented your adapter's getView correctly, you'd see the checkbox becoming checked. Example code (won't compile): public MyAdapter extends BaseAdapter { private List mData = new ArrayList(); ... // example methods. public void selectSoundTableItem(int position, boolean select) { mData.get(position).isSelected = select; notifyDatasetChanged(); } public void setSoundData(Map soundTable) { mData.clear(); for (String soundName : soundTable.keySet()) { SelectableString ss = new SelectableString(); ss.soundTableName = soundName; ss.soundId= soundTable.get(soundName); mData.add(ss); } notifyDatasetChanged(); } public void preselectSoundData(SharedPreferences prefs) { String[] selectedSoundsArray = prefs.getString("selectedSounds", "").split(","); for (SelectableString ss : mData) { ss.isSelected = false; } for (int selI = 0; selI < selectedSoundsArray.length; selI++) { SelectableString ss = findItem(mData,selectedSoundsArray [selI]); ss.isSelected = true; } notifyDatasetChanged(); } // below are the methods from BaseAdapter you need to implement: // getCount(), getItem(int position), etc. ... public Object getItem(int position) { return mData.get(position); } ... ... // Called by your attached ListView when it's about to create/re- use a visible item. // The ListView calls this method. Your code should not call it. public View getView(int position, View convertView, ViewGroup parent) { ... // use convertView or create/inflate a new one when it's null. // ... SelectableString ss = (SelectableString)getItem(position); // may help you find back the soundTableItem in onClick methods by calling 'getTag()' convertView.setTag(new Integer(ss.soundId)); String soundName = ss.soundName; TextView tv = (TextView)convertView.findViewById(R.id.textview); tv.setText(soundName); boolean isSelected = ss.isSelected; CheckBox cb = (CheckBox)convertView.findViewById(R.id.checkbox); cb.setChecked(isSelected); ... ... return convertView; } ... } On Oct 26, 9:38 pm, stanlick wrote: > Thanks Mark -- > > Doesn't this sort of violate the MVC pattern? Moreover, does it seem > odd to you that both the adapter and ListView have methods to cough up > a view? Pre-selecting check boxes is sure becoming a difficult-to-do > process! > > I am in the debugger and experimenting with how I might get the view > from the list as you suggested. > > I have tried > > list.getChildAt(0); which returned null > list.getItemAtPosition(0) which returned > android.content.contentresolver$cursorwrapperin...@4375e088 > list.getRootView() which returned > com.android.internal.policy.impl.phonewindow$decorv...@4375ac38 > > Can you throw me another clue? > > Scott > > On Oct 25, 4:02 pm, "Mark Murphy" wrote: > > > > > > I am using a SimpleCursorAdapter and having a similar problem with pre- > > > checking certain entries. This is my experimental code that I am > > > trying immediately following the instantiation of the adapter: > > > > adapter = new SimpleCursorAdapter(this, > > > > > > android.R.layout.simple_list_item_multiple_choice, c, > > > new String[] { Contacts.PeopleColumns.NAME }, > > > new int[] { android.R.id.text1 }); > > > > // TODO TEST CODE > > > CheckedTextView cb = (CheckedTextView) adapter.getView(0, null, > > > null); > > > cb.setChecked(true); > > > > The list appears and the first entry is *not* checked. Any ideas? > > > The View you got from your getView() call is being discarded. > > > Remember, *ListView* does the caching of rows. Since your requested a row > > outside of ListView, ListView doesn't know about it or use it. > > > Add your SimpleCursorAdapter to your ListView, then call setItemChecked() > > on the ListView to check your desired row, and see if that works. > > > -- > > Mark Murphy (a Commons Guy)http://commonsware.com > > Android App Developer Books:http://commonsware.com/books.html- Hide quoted > > text - > > - Show quoted text - --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to android-developer
[android-developers] Re: ListView setAdapter in onCreate, getChildCount is zero in onStart?
> list.getChildAt(0); which returned null That will be true until the ListView starts getting rows from your Adapter. > list.getItemAtPosition(0) which returned > android.content.contentresolver$cursorwrapperin...@4375e088 That is a Cursor pointing at the 0th item in the Adapter's data. > list.getRootView() which returned > com.android.internal.policy.impl.phonewindow$decorv...@4375ac38 That is the top-most View in your view hierarchy. It manages the title bar and your application. You can see this via hierarchyviewer. > Can you throw me another clue? I suggested that you add your SimpleCursorAdapter to your ListView, then call setItemChecked() on the ListView to check your desired row. You have not indicated where this advice went wrong. -- Mark Murphy (a Commons Guy) http://commonsware.com Android App Developer Books: http://commonsware.com/books.html --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~--~~~~--~~--~--~---
[android-developers] Re: ListView setAdapter in onCreate, getChildCount is zero in onStart?
Thanks Mark -- Doesn't this sort of violate the MVC pattern? Moreover, does it seem odd to you that both the adapter and ListView have methods to cough up a view? Pre-selecting check boxes is sure becoming a difficult-to-do process! I am in the debugger and experimenting with how I might get the view from the list as you suggested. I have tried list.getChildAt(0); which returned null list.getItemAtPosition(0) which returned android.content.contentresolver$cursorwrapperin...@4375e088 list.getRootView() which returned com.android.internal.policy.impl.phonewindow$decorv...@4375ac38 Can you throw me another clue? Scott On Oct 25, 4:02 pm, "Mark Murphy" wrote: > > I am using a SimpleCursorAdapter and having a similar problem with pre- > > checking certain entries. This is my experimental code that I am > > trying immediately following the instantiation of the adapter: > > > adapter = new SimpleCursorAdapter(this, > > > > android.R.layout.simple_list_item_multiple_choice, c, > > new String[] { Contacts.PeopleColumns.NAME }, > > new int[] { android.R.id.text1 }); > > > // TODO TEST CODE > > CheckedTextView cb = (CheckedTextView) adapter.getView(0, null, > > null); > > cb.setChecked(true); > > > The list appears and the first entry is *not* checked. Any ideas? > > The View you got from your getView() call is being discarded. > > Remember, *ListView* does the caching of rows. Since your requested a row > outside of ListView, ListView doesn't know about it or use it. > > Add your SimpleCursorAdapter to your ListView, then call setItemChecked() > on the ListView to check your desired row, and see if that works. > > -- > Mark Murphy (a Commons Guy)http://commonsware.com > Android App Developer Books:http://commonsware.com/books.html --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~--~~~~--~~--~--~---
[android-developers] Re: ListView setAdapter in onCreate, getChildCount is zero in onStart?
> I am using a SimpleCursorAdapter and having a similar problem with pre- > checking certain entries. This is my experimental code that I am > trying immediately following the instantiation of the adapter: > > adapter = new SimpleCursorAdapter(this, > > android.R.layout.simple_list_item_multiple_choice, c, > new String[] { Contacts.PeopleColumns.NAME }, > new int[] { android.R.id.text1 }); > > // TODO TEST CODE > CheckedTextView cb = (CheckedTextView) adapter.getView(0, null, > null); > cb.setChecked(true); > > The list appears and the first entry is *not* checked. Any ideas? The View you got from your getView() call is being discarded. Remember, *ListView* does the caching of rows. Since your requested a row outside of ListView, ListView doesn't know about it or use it. Add your SimpleCursorAdapter to your ListView, then call setItemChecked() on the ListView to check your desired row, and see if that works. -- Mark Murphy (a Commons Guy) http://commonsware.com Android App Developer Books: http://commonsware.com/books.html --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Android Developers" group. To post to this group, send email to android-developers@googlegroups.com To unsubscribe from this group, send email to android-developers+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/android-developers?hl=en -~--~~~~--~~--~--~---
[android-developers] Re: ListView setAdapter in onCreate, getChildCount is zero in onStart?
I am using a SimpleCursorAdapter and having a similar problem with pre- checking certain entries. This is my experimental code that I am trying immediately following the instantiation of the adapter: adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_multiple_choice, c, new String[] { Contacts.PeopleColumns.NAME }, new int[] { android.R.id.text1 }); // TODO TEST CODE CheckedTextView cb = (CheckedTextView) adapter.getView(0, null, null); cb.setChecked(true); The list appears and the first entry is *not* checked. Any ideas? Thanks, Scott On Oct 8, 4:16 pm, Streets Of Boston wrote: > YourListViewis only for display. > Your ListAdapter (in your case ArrayAdapter) is for getting and > manipulating the actual data. Only it's 'getView' method provides a > bridge between the data and the display-view... > > Iterate over the elements in your ArrayAdapter to determine if one > item is selected or not. (Do not iterate over the elements (child- > views) of theListView.) > > Each element in your ArrayAdapter should have a way to tell you if it > is selected or not. > > Currently you use this ArrayAdapter. This () is not > enough. You need to know if a particular String in this adapter has > been selected or not at some point: > > public class SelectableString { > public String soundTableName; > public boolean isSelected; > > // Add this method, to avoid overriding getView in your > ArrayAdapter. > public String toString() { > return soundTableName; > } > > } > > and then have a ArrayAdapter instead. > > Then register an OnItemSelectedListener (or something similar) and > implement this one to get the proper SelectableString from your > ArrayAdapter and set the SelectableString's 'isSelected' element to > true or false. > > Then, at other points in your code, you can just iterate over your > ArrayAdapter and query each SelectableString's 'isSelected' member to > check if it has been selected or not. > > On Oct 7, 11:02 pm, KhanAzul wrote: > > > Thank you for your response, and I can understand your confusion. > > Yes, when I run this activity, my screen displays the title text, two > > items in myListView(0 = "Big Sound", 1 = "Little Sound"), and the > > footer text. I can select either or both items, and when I press > > Back, I can step through my onPause (you are correct here, pardon my > > bad form) and watch the selection indices get saved to > > "selectedSounds" preference. > > > From what I've observed through careful debugging, I'm not having any > > issues saving the selections. Nor am I having issues retrieving these > > selections from preferences, or setting the ArrayAdapter to my > >ListView. The breakdown occurs when I try to set these items as > > checked in theListViewwhen the activity starts back up. > > > > Don't use 'getChildCount' and 'getChildAt' method to check your > > > preference-settings. > > > What is the proper method? I think this is the crux of my question. > > > Again, I appreciate the help. I think some further guidance is > > needed. > > > On Oct 7, 3:30 pm, Streets Of Boston wrote: > > > > Your activity (and your list-view) is not yet visible in the onStart. > > > > Don't use 'getChildCount' and 'getChildAt' method to check your > > > preference-settings. > > > > BTW: If your activity is not yet visible, how can a user make a > > > selection? > > > Shouldn't you query in the onPause, for example. > > > And also, the positions returned by the method getCheckedItemPositions > > > () are the positions in your adapter (ArrayAdapter in your case). Your > > > list-*view* positions (used in getChildAt) are not the same. You list- > > > view will never have more children than the ones you can see. And the > > > child-at postion 0 is the one on the top of the list-view. > > > > On Oct 7, 2:37 pm, KhanAzul wrote: > > > > > I want to display aListViewwith checkboxes, and I want some of the > > > > checkboxes pre-selected. TheListViewhas setAdapter called during > > > > onCreate, and the list information appears when the screen is drawn. > > > > However, when I attempt to set certain list items as checked, my > > > >ListViewreports getChildCount() = 0. > > > > > My SharedPreferences contains a list of sounds that have been > > > > previously selected, as a comma delimited string of list indices. > > > > Because the list appears to have no children in onStart, my attempts > > > > to set items as checked fails. > > > > > On the good side, once the list is rendered, I can select entries and > > > > hit Back, and my selection is stored to SharedPreferences correctly. > > > > > How can I load my previous selection into the list? Should I be using > > > > something else here? > > > > > In the spirit of open source, here's my code, free to you :) > > > > > ==
[android-developers] Re: ListView setAdapter in onCreate, getChildCount is zero in onStart?
Your ListView is only for display. Your ListAdapter (in your case ArrayAdapter) is for getting and manipulating the actual data. Only it's 'getView' method provides a bridge between the data and the display-view... Iterate over the elements in your ArrayAdapter to determine if one item is selected or not. (Do not iterate over the elements (child- views) of the ListView.) Each element in your ArrayAdapter should have a way to tell you if it is selected or not. Currently you use this ArrayAdapter. This () is not enough. You need to know if a particular String in this adapter has been selected or not at some point: public class SelectableString { public String soundTableName; public boolean isSelected; // Add this method, to avoid overriding getView in your ArrayAdapter. public String toString() { return soundTableName; } } and then have a ArrayAdapter instead. Then register an OnItemSelectedListener (or something similar) and implement this one to get the proper SelectableString from your ArrayAdapter and set the SelectableString's 'isSelected' element to true or false. Then, at other points in your code, you can just iterate over your ArrayAdapter and query each SelectableString's 'isSelected' member to check if it has been selected or not. On Oct 7, 11:02 pm, KhanAzul wrote: > Thank you for your response, and I can understand your confusion. > Yes, when I run this activity, my screen displays the title text, two > items in my ListView (0 = "Big Sound", 1 = "Little Sound"), and the > footer text. I can select either or both items, and when I press > Back, I can step through my onPause (you are correct here, pardon my > bad form) and watch the selection indices get saved to > "selectedSounds" preference. > > From what I've observed through careful debugging, I'm not having any > issues saving the selections. Nor am I having issues retrieving these > selections from preferences, or setting the ArrayAdapter to my > ListView. The breakdown occurs when I try to set these items as > checked in the ListView when the activity starts back up. > > > Don't use 'getChildCount' and 'getChildAt' method to check your > > preference-settings. > > What is the proper method? I think this is the crux of my question. > > Again, I appreciate the help. I think some further guidance is > needed. > > On Oct 7, 3:30 pm, Streets Of Boston wrote: > > > > > Your activity (and your list-view) is not yet visible in the onStart. > > > Don't use 'getChildCount' and 'getChildAt' method to check your > > preference-settings. > > > BTW: If your activity is not yet visible, how can a user make a > > selection? > > Shouldn't you query in the onPause, for example. > > And also, the positions returned by the method getCheckedItemPositions > > () are the positions in your adapter (ArrayAdapter in your case). Your > > list-*view* positions (used in getChildAt) are not the same. You list- > > view will never have more children than the ones you can see. And the > > child-at postion 0 is the one on the top of the list-view. > > > On Oct 7, 2:37 pm, KhanAzul wrote: > > > > I want to display a ListView with checkboxes, and I want some of the > > > checkboxes pre-selected. The ListView has setAdapter called during > > > onCreate, and the list information appears when the screen is drawn. > > > However, when I attempt to set certain list items as checked, my > > > ListView reports getChildCount() = 0. > > > > My SharedPreferences contains a list of sounds that have been > > > previously selected, as a comma delimited string of list indices. > > > Because the list appears to have no children in onStart, my attempts > > > to set items as checked fails. > > > > On the good side, once the list is rendered, I can select entries and > > > hit Back, and my selection is stored to SharedPreferences correctly. > > > > How can I load my previous selection into the list? Should I be using > > > something else here? > > > > In the spirit of open source, here's my code, free to you :) > > > > > > > SoundLibrary.Java > > > > > > > import java.util.Hashtable; > > > > import android.app.Activity; > > > import android.content.Context; > > > import android.content.SharedPreferences; > > > import android.content.res.Resources; > > > import android.media.MediaPlayer; > > > import android.os.Bundle; > > > import android.util.SparseBooleanArray; > > > import android.view.View; > > > import android.view.View.OnLongClickListener; > > > import android.widget.ArrayAdapter; > > > import android.widget.ListView; > > > > public class SoundLibrary extends Activity{ > > > ListView lstSounds; > > > Hashtable soundTable; > > > CharSequence[] soundNames; > > > CharSequence[] soundLocations; > > > OnLongClickListener previewListener; > > > static Context myContext; > > > static MediaPlaye
[android-developers] Re: ListView setAdapter in onCreate, getChildCount is zero in onStart?
Thank you for your response, and I can understand your confusion. Yes, when I run this activity, my screen displays the title text, two items in my ListView (0 = "Big Sound", 1 = "Little Sound"), and the footer text. I can select either or both items, and when I press Back, I can step through my onPause (you are correct here, pardon my bad form) and watch the selection indices get saved to "selectedSounds" preference. >From what I've observed through careful debugging, I'm not having any issues saving the selections. Nor am I having issues retrieving these selections from preferences, or setting the ArrayAdapter to my ListView. The breakdown occurs when I try to set these items as checked in the ListView when the activity starts back up. > Don't use 'getChildCount' and 'getChildAt' method to check your > preference-settings. What is the proper method? I think this is the crux of my question. Again, I appreciate the help. I think some further guidance is needed. On Oct 7, 3:30 pm, Streets Of Boston wrote: > Your activity (and your list-view) is not yet visible in the onStart. > > Don't use 'getChildCount' and 'getChildAt' method to check your > preference-settings. > > BTW: If your activity is not yet visible, how can a user make a > selection? > Shouldn't you query in the onPause, for example. > And also, the positions returned by the method getCheckedItemPositions > () are the positions in your adapter (ArrayAdapter in your case). Your > list-*view* positions (used in getChildAt) are not the same. You list- > view will never have more children than the ones you can see. And the > child-at postion 0 is the one on the top of the list-view. > > On Oct 7, 2:37 pm, KhanAzul wrote: > > > I want to display a ListView with checkboxes, and I want some of the > > checkboxes pre-selected. The ListView has setAdapter called during > > onCreate, and the list information appears when the screen is drawn. > > However, when I attempt to set certain list items as checked, my > > ListView reports getChildCount() = 0. > > > My SharedPreferences contains a list of sounds that have been > > previously selected, as a comma delimited string of list indices. > > Because the list appears to have no children in onStart, my attempts > > to set items as checked fails. > > > On the good side, once the list is rendered, I can select entries and > > hit Back, and my selection is stored to SharedPreferences correctly. > > > How can I load my previous selection into the list? Should I be using > > something else here? > > > In the spirit of open source, here's my code, free to you :) > > > > > SoundLibrary.Java > > > > > import java.util.Hashtable; > > > import android.app.Activity; > > import android.content.Context; > > import android.content.SharedPreferences; > > import android.content.res.Resources; > > import android.media.MediaPlayer; > > import android.os.Bundle; > > import android.util.SparseBooleanArray; > > import android.view.View; > > import android.view.View.OnLongClickListener; > > import android.widget.ArrayAdapter; > > import android.widget.ListView; > > > public class SoundLibrary extends Activity{ > > ListView lstSounds; > > Hashtable soundTable; > > CharSequence[] soundNames; > > CharSequence[] soundLocations; > > OnLongClickListener previewListener; > > static Context myContext; > > static MediaPlayer player; > > SharedPreferences prefs; > > > @Override > > public void onCreate(Bundle savedInstanceState) { > > super.onCreate(savedInstanceState); > > setContentView(R.layout.soundlibrary); > > myContext = this.getApplicationContext(); > > prefs = getSharedPreferences("myAppData", 0); > > > soundTable = new Hashtable(); > > LoadSoundTable(); > > lstSounds = (ListView)findViewById(R.id.lstSounds); > > PopulateSoundList(); > > lstSounds.setOnLongClickListener(new PreviewListener()); > > } > > > @Override > > public void onStart() { > > super.onStart(); > > String[] selectedSoundsArray = > > prefs.getString("selectedSounds", "").split(","); > > for (int selI = 0; selI < selectedSoundsArray.length; > > selI++) { > > if (lstSounds.getChildCount() <= selI) { > > break; > > } > > try { > > > > lstSounds.getChildAt(Integer.parseInt(selectedSoundsArray > > [selI])).setSelected(true); > > } catch (NumberFormatException e) { } > > } > > } > > > @Override > > public void onPause() { > > super.onPause(); > > StringBuffer sb = new StringBuffer
[android-developers] Re: ListView setAdapter in onCreate, getChildCount is zero in onStart?
Your activity (and your list-view) is not yet visible in the onStart. Don't use 'getChildCount' and 'getChildAt' method to check your preference-settings. BTW: If your activity is not yet visible, how can a user make a selection? Shouldn't you query in the onPause, for example. And also, the positions returned by the method getCheckedItemPositions () are the positions in your adapter (ArrayAdapter in your case). Your list-*view* positions (used in getChildAt) are not the same. You list- view will never have more children than the ones you can see. And the child-at postion 0 is the one on the top of the list-view. On Oct 7, 2:37 pm, KhanAzul wrote: > I want to display a ListView with checkboxes, and I want some of the > checkboxes pre-selected. The ListView has setAdapter called during > onCreate, and the list information appears when the screen is drawn. > However, when I attempt to set certain list items as checked, my > ListView reports getChildCount() = 0. > > My SharedPreferences contains a list of sounds that have been > previously selected, as a comma delimited string of list indices. > Because the list appears to have no children in onStart, my attempts > to set items as checked fails. > > On the good side, once the list is rendered, I can select entries and > hit Back, and my selection is stored to SharedPreferences correctly. > > How can I load my previous selection into the list? Should I be using > something else here? > > In the spirit of open source, here's my code, free to you :) > > > SoundLibrary.Java > > > import java.util.Hashtable; > > import android.app.Activity; > import android.content.Context; > import android.content.SharedPreferences; > import android.content.res.Resources; > import android.media.MediaPlayer; > import android.os.Bundle; > import android.util.SparseBooleanArray; > import android.view.View; > import android.view.View.OnLongClickListener; > import android.widget.ArrayAdapter; > import android.widget.ListView; > > public class SoundLibrary extends Activity{ > ListView lstSounds; > Hashtable soundTable; > CharSequence[] soundNames; > CharSequence[] soundLocations; > OnLongClickListener previewListener; > static Context myContext; > static MediaPlayer player; > SharedPreferences prefs; > > @Override > public void onCreate(Bundle savedInstanceState) { > super.onCreate(savedInstanceState); > setContentView(R.layout.soundlibrary); > myContext = this.getApplicationContext(); > prefs = getSharedPreferences("myAppData", 0); > > soundTable = new Hashtable(); > LoadSoundTable(); > lstSounds = (ListView)findViewById(R.id.lstSounds); > PopulateSoundList(); > lstSounds.setOnLongClickListener(new PreviewListener()); > } > > @Override > public void onStart() { > super.onStart(); > String[] selectedSoundsArray = > prefs.getString("selectedSounds", "").split(","); > for (int selI = 0; selI < selectedSoundsArray.length; selI++) > { > if (lstSounds.getChildCount() <= selI) { > break; > } > try { > > lstSounds.getChildAt(Integer.parseInt(selectedSoundsArray > [selI])).setSelected(true); > } catch (NumberFormatException e) { } > } > } > > @Override > public void onPause() { > super.onPause(); > StringBuffer sb = new StringBuffer(); > SparseBooleanArray sbaSelectedSounds = > lstSounds.getCheckedItemPositions(); > for (int sbaKey = 0; sbaKey < sbaSelectedSounds.size(); > sbaKey++) > { > if (sbaSelectedSounds.get(sbaKey, false)) > { > sb.append(String.valueOf(sbaKey)); > sb.append(','); > } > } > prefs.edit().putString("selectedSounds", > sb.toString()).commit(); > } > > private void LoadSoundTable() > { > Resources res = getResources(); > CharSequence[] soundNames = > res.getTextArray(R.array.sound_name); > CharSequence[] soundLocations = > res.getTextArray(R.array.sound_location); > > for (int i = 0; i < soundNames.length; i++) { > soundTable.put(soundNames[i].toString(), > > res.getIdentifier(soundLocations[i].toString(), "raw", > this.getPackageName())); > } > } > >