I'm a little new to android and am trying to figure out these custom list adapter. So I have an activity that extends BaseListActivity and a function like:
public void inflate(){
ArrayList<String> words = new ArrayList<String>();
orders.add("hello");
orders.add("world");
wordsList = (ListView) findViewById(R.id.list);
WordsAdapter adapter = new WordsAdapter(this, R.layout.single_word_container_item,words);
wordsList.setAdapter(adapter);
And then I implement my custom WordsAdapter as follows:
public class WordsAdapter extends ArrayAdapter<String>{
public Context context;
public ArrayList<String> _words;
//not sure the purpose of 'a' here
public WordsAdapter(Context context, int a, ArrayList<String> words) {
super(context, a, words);
_words = words;
this.context = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.single_word_container_item, null);
TextView wordName = (TextView) findViewById(R.id.wordName);
if(!_words.isEmpty()){
wordName.setText(_word.remove(0));
}
return v;
}
}
From what I can tell from the logs is that getView is never being called. 'single_word_container_item' is simply an xml file with a layout that I want to inflate multiple times. I'm not sure about the entire process - I figured you set an adapter on your listview and then in that adapter you take care of displaying what will actually show up each time, so what am I doing wrong here? Currently I'm getting a null pointer exception where I set my adapter but earlier it just would not show anything. The logs show that it is getting into the WordsAdapter constructor but then dying. Thanks in advance for any advice.
EDIT: So it appears to be something wrong with identifying the listview in my xml.
If you use:
ListView
android:id="@+id/android:list" OR android:id="@id/android:list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
ListView
the error is a null pointer exception when you use it
but if you define it as:
ListView
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
ListView
you get the error: 07-15 19:18:50.240: E/AndroidRuntime(29842): Caused by: java.lang.RuntimeException: Your content must have a ListView whose id attribute is 'android.R.id.list'
EDIT: So apparently you can't extend listactivity and call setcontentview(). Since I need a view on top of the listview I don't want to extend list activity but rather call setcontentview and just refer to the list by its id.
Now my error is:
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread.
I tried calling adapter.notifyDataSetChanged() after my setAdapter() but that didn't seem to work. Am I supposed to call it somewhere else?
You have an error in your getView() method:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v;
if (convertView == null) {
v = inflater.inflate(R.layout.single_word_container_item, null);
} else {
v = convertView;
}
TextView wordName = (TextView) v.findViewById(R.id.wordName);
// questionable logic
if(!_words.isEmpty()){
wordName.setText(_word.remove(0));
}
return v;
}
findViewById() must be called on the row's view.
Also look at the questionable logic above, what are you trying to do? This won't work too well if you are removing the listview objects directly from the adapter.