NullPointer when findViewById () in SimpleCursorAdapter

I used a SimpleCursorAdapter with an XML file with the views defined in it:

<LinearLayout ...> <ImageView android:id="@+id/listIcon" /> <TextView android:id="@+id/listText" /> </LinearLayout> 

My goal was to programmatically adjust the text color of the TextView and the background color of the LinearLayout (that is, each row in the ListView); color is returned from the database.

I got NPE when trying to manipulate a TextView, for example, after finding it without complaint:

 TextView tv = (TextView) findViewById(R.id.listText); tv.setTextColor(color); // NPE on this line 

This is true; if there are several entries in the list, it is reasonable to assume that "R.id.listText" will not work. Therefore, I expanded the SimpleCursor adapter:

 public View getView(int position, View convertView, ViewGroup parent) { View row = super.getView(position, convertView, parent); TextView text = (TextView) row.findViewById(R.id.listText); // ImageView icon = (ImageView) row.findViewById(R.id.listIcon); // If there an icon defined if (mIcon_id != 0) { // icon.setImageResource(mIcon_id); } // If text color defined if (mTextColor != 0) { text.setTextColor(mTextColor); } // If background color set if (mBackgroundColor != 0) { row.setBackgroundColor(mBackgroundColor); } return(row); } 

And I get two different errors:

  • Similar NPE "Text.setTextColor (mTextColor)"
  • If the rows with ImageView are unhurt, I get a "ClassCastException: android.widget.TextView" where I am calling "Row.findViewById (R.id.listIcon)"

For reference, I tried to use the Commonsware sample code, applying it to my situation. link (pdf)


Modified by:

 public View getView(int position, View convertView, ViewGroup parent) { convertView = super.getView(position, convertView, parent); if (convertView == null) convertView = View.inflate(mContext, R.layout.theme_item, null); TextView text = (TextView) convertView.findViewById(R.id.listText_tv); ImageView icon = (ImageView) convertView.findViewById(R.id.listIcon_iv); // If there an icon defined if (mIcon_id != 0) { icon.setImageResource(mIcon_id); } // If text color defined if (mTextColor != 0) { text.setTextColor(mTextColor); } // If background color set if (mBackgroundColor != 0) { convertView.setBackgroundColor(mBackgroundColor); } bindView(convertView, mContext, mCursor); return(convertView); } 

Now I get a ClassCastException in the next action (when I click on a list item). Nothing was changed in the next action; it worked when using the SimpleListAdapter for the list in which there were entries (after which clicking will result in Activity2), so I think that this is still something that I am doing wrong in this extended class.

+4
source share
4 answers

It is not true that convertView will always be an existing instance; you must check if it is null and then instantiate it. If not, you can change it just like you.

It should be like:

 public View getView(int position, View convertView, ViewGroup parent) { if(convertView == null) convertView = //inflate your row here View row = convertView; //Manipulate the row here return(row); } 
+5
source

I would change the getView method:

 public View getView(int position, View convertView, ViewGroup parent) { convertView = View.inflate(getContext(), R.layout.myLayout, null); TextView text = (TextView) convertView.findViewById(R.id.listText); ImageView icon = (ImageView) convertView.findViewById(R.id.listIcon); // If there an icon defined if (mIcon_id != 0) { icon.setImageResource(mIcon_id); } // If text color defined if (mTextColor != 0) { text.setTextColor(mTextColor); } // If background color set if (mBackgroundColor != 0) { convertView.setBackgroundColor(mBackgroundColor); } return convertView; } 
+1
source

I think you get NPE because you are trying to create a text view and an image in a view where they are not there.

If you want to inflate a ListView with records from a database, in your activity you define main.xml with a ListView:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ListView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/listView1"> </ListView> 

and in the onCreate method you set the view for this xml using setContentView(R.layout.main); . Then you create your cursor in your database and custom adapter:

  MySimpleCursorAdapter adapter = new MySimpleCursorAdapter(this, R.layout.entry, names, new String[] {Phones.NAME, Phones.NUMBER}, new int[] { R.id.listIcon, R.id.listText}); startManagingCursor(cursor); ListView listView = (ListView) findViewById(R.id.listView1); listView.setAdapter(adapter); 

and you define entry.xml with your listIcon and listText where the adapter points. In my example, I am requesting names and numbers from a contact list.

In your user adapter, you can easily access the text view and image view inside getView or bindView.

Here you have an example to get all contacts from your contact list with its image, name and number, but using ListActivity instead of activity and only one xml with two text representations and an image representation. If you use ListActivity, you do not need to use ListView, and you do not need to set the presentation of the content in the activity.

Hope this helps!

0
source

Remember to put: layout_width and layout_heigth for each of your views.

-2
source

Source: https://habr.com/ru/post/1343679/


All Articles