I have a custom alert dialog with this code adapter
adapter_nomi = new ArrayAdapter<nomi>(context, R.layout.dialog_lista_nomi, R.id.r_dialog_nomi, list_nomi){
#Override
public View getView(int position, View convertView,ViewGroup parent) {
ViewHolder holder = null;
final String indirizzo;
if(convertView==null){
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.row_dialog_nomi, null);
holder = new ViewHolder();
holder.nome = (TextView)convertView.findViewById(R.id.r_dialog_nomi);
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}
nomi item = getItem(position);
holder.nome.setText(item.get("nominativo"));
return convertView;
}
};
but when list_nomi change and I call showDialog it's not refresh. I have also put into onPrepareDialog the code adapter_nomi.notifyDataSetChange(); but it don't work.....why ?
Related
I'm new to android, I've tried many solutions but nothing works!
Can you please see what's wrong with my code:
I get NullPointerException in holder.CardContent.setText(card.getString("content"));
I've tried to change layoutInflater from null to parent, false
The ids are not the false one!
CardAdapter.java
public class CardAdapter extends ArrayAdapter<ParseObject> {
protected Context mContext;
protected List<ParseObject> mCards;
public CardAdapter(Context context, List<ParseObject> cards) {
super(context, R.layout.card_item, cards);
mContext = context;
mCards = cards;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.card_item, null);
holder = new ViewHolder();
holder.CardContent = (TextView) convertView.findViewById(R.id.cardText);
} else{
holder = (ViewHolder) convertView.getTag();
}
ParseObject card = mCards.get(position);
holder.CardContent.setText(card.getString("content")); // <-- NPE here.
return convertView;
}
private static class ViewHolder{
TextView CardContent;
}
}
Logcat:
at com.kardapps.lifehacks.activities.CardAdapter.getView(CardAdapter.java:64)
at android.widget.AbsListView.obtainView(AbsListView.java:2255)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1263)
at android.widget.ListView.onMeasure(ListView.java:1175)
.......
The problem is that holder is null at least for the beginning.
card could be null too but its not clear at the moment.
Although the adapter recycling logic is right you have forgotten to setTag to the View.
The logic of the recycling is that the way you scroll you save (using setTag) the already read/seen data to the view (here convertView).
Then each time you pass the same position you use setTag to retrieve them instead of recreating them (LayoutInflater.from...)
#Override
public View getView(int position, #Nullable View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
// This is not an error but using parent you avoid Lint warnings
convertView = LayoutInflater.from(mContext).inflate(R.layout.card_item, parent);
holder = new ViewHolder();
holder.CardContent = (TextView) convertView.findViewById(R.id.cardText);
convertView.setTag(holder); // <-- As suggested for improvement
} else {
holder = (ViewHolder) convertView.getTag();
}
ParseObject card = mCards.get(position);
holder.CardContent.setText(card.getString("content")); // <-- NPE here.
// convertView.setTag(holder); // <-- This line is missing
return convertView;
}
You need to set convertView's tag to the holder in your if-block.
if (convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.card_item, null);
holder = new ViewHolder();
holder.CardContent = (TextView) convertView.findViewById(R.id.cardText);
// Add this line
convertView.setTag(holder);
}
You can see that in the else-block, you're retrieving the tag and casting it to ViewHolder. If you haven't set the tag, getTag() returns null, causing the Exception.
See this code:
if(convertView == null){
convertView = LayoutInflater.from(mContext).inflate(R.layout.card_item, null);
holder = new ViewHolder();
holder.CardContent = (TextView) convertView.findViewById(R.id.cardText);
}
else{
holder = (ViewHolder) convertView.getTag();
}
ParseObject card = mCards.get(position);
holder.CardContent.setText(card.getString("content"));
Two possibilities:
if convertView is not null, you are just initialising holder object and not cardContent.
mCards.get(position); returns null
I've searched for this question already, and I couldn't find it anywhere, and I'm not even sure how to exactly word it.
I have a listview with images, text, buttons, etc. for each item. I also have an edittext for the items, but I only want the edittext to be visible for the current user. The same way you're only able to edit your own post on Facebook, not every other one as well.
Here's what I've tried:
holder.editcaption = (EditText) itemView.findViewById(R.id.editText1);
(...)
if(mCurrentUser.getUsername()!=currentItem.getSender())
holder.editcaption.setVisibility(View.INVISIBLE);
This is in the getView() of the adapter. The problem is that either all of the edittexts become invisible or visible when I only need every edittext except for the current user's to be invisible. I only need the edittext view of the current item to change.
Any help is very much appreciated.
private class MyListAdapter extends ArrayAdapter<GalleryItem>{
public MyListAdapter(){
super(getActivity(), R.layout.item_view, thelist);
}
#Override
public int getViewTypeCount() {
return 2;
}
#Override
public int getItemViewType(int position) {
if(items.get(position).getUsername()!=mCurrentUser.getUsername())
return 2;
else return 0;
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
currentItem = adapter.getItem(position);
int type = getItemViewType(position);
ViewHolder holder;
View itemView = null;
if(convertView == null){
LayoutInflater inflater = (LayoutInflater) getListView().getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
if(type==0)
itemView = inflater.inflate(R.layout.item_view, parent, false);
else
itemView = inflater.inflate(R.layout.currentuser_item_view, parent, false);
holder = new ViewHolder();
holder.image = (ImageView)itemView.findViewById(R.id.imgAvatar);
holder.text = (TextView) itemView.findViewById(R.id.newtext);
holder.profilepicture = (ProfilePictureView) itemView.findViewById(R.id.profilePicture);
holder.timelabel = (TextView) itemView.findViewById(R.id.timeposted);
holder.post_caption = (TextView) itemView.findViewById(R.id.caption);
holder.editcaption = (EditText) itemView.findViewById(R.id.editText1);
itemView.setTag(holder);
}
else{
itemView = convertView;
holder = (ViewHolder) itemView.getTag();
}
I am getting following warning in eclipse:
Unconditional layout inflation from view adapter: Should use View Holder pattern (use recycled view passed into this method as the second parameter) for smoother scrolling.
on:
convertView = vi.inflate(R.layout.activity_friend_list_row, parent, false);
I have a base adapter with a CheckBox implemented and I have added a tag to make the CheckBox work.
Here is the code:
public View getView(final int position, View convertView, ViewGroup parent)
{
ViewHolder mViewHolder;
mViewHolder = new ViewHolder();
LayoutInflater vi = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.activity_friend_list_row, parent, false);
mViewHolder.cb = (CheckBox) convertView.findViewById(R.id.checkBox);
convertView.setTag(mViewHolder);
if (InviteFriends.isChecked[position] == true)
{
mViewHolder.cb.setChecked(true);
}
else
{
mViewHolder.cb.setChecked(false);
}
mViewHolder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener()
{
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean ischecked)
{
if (buttonView.isChecked())
{
InviteFriends.isChecked[position] = true;
}
else
{
InviteFriends.isChecked[position] = false;
}
}
});
TextView friendsname = (TextView) convertView.findViewById(R.id.friendsName); // title
ImageView thumb_image = (ImageView) convertView.findViewById(R.id.list_image); // thumb image
HashMap<String, String> song = new HashMap<String, String>();
song = data.get(position);
// Setting all values in listview
friendsname.setText(song.get(InviteFriends.KEY_DISPLAY_NAME));
imageLoader.DisplayImage(song.get(InviteFriends.KEY_IMAGEPROFILE_URL), thumb_image);
return convertView;
}
The results are coming up properly. How do I fix this warning? I am not able to get a solution for this yet?
Thanks!
Try this
static class ViewHolder {
private TextView friendsname;
private ImageView thumb_image;
private CheckBox cb;
}
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder mViewHolder = null;
HashMap<String, String> song = null;
if (convertView == null) {
song = new HashMap <String, String>();
mViewHolder = new ViewHolder();
LayoutInflater vi = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.activity_friend_list_row, parent, false);
mViewHolder.friendsname = (TextView) convertView.findViewById(R.id.friendsName); // title
mViewHolder.thumb_image = (ImageView) convertView.findViewById(R.id.list_image); // thumb image
mViewHolder.cb = (CheckBox) convertView.findViewById(R.id.checkBox);
convertView.setTag(mViewHolder);
mViewHolder.cb.setTag(data.get(position));
mViewHolder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean ischecked) {
InviteFriends.isChecked[position] = buttonView.isChecked();
}
});
} else {
mViewHolder = (ViewHolder) convertView.getTag();
}
song = mViewHolder.cb.getTag();
mViewHolder.friendsname.setText(song.get(InviteFriends.KEY_DISPLAY_NAME));
mViewHolder.imageLoader.DisplayImage(song.get(InviteFriends.KEY_IMAGEPROFILE_URL), thumb_image);
mViewHolder.cb.setChecked(InviteFriends.isChecked[position]);
return convertView;
}
you should init the convert view only if it is null
these lines
LayoutInflater vi = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.activity_friend_list_row, parent, false);
// [...] the rest of initialization part
// [...] some changes that must be done at refresh
return convertView;
should look like this:
if (convertView == null) {
LayoutInflater vi = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.activity_friend_list_row, parent, false);
// [...] the rest of initialization part
}
// [...] some changes that must be done at refresh
return convertView;
the goal is to recycle the already existing view in that list, not to init it each time you display it when scrolling the list for example.
Unconditional layout inflation from view adapter: Should use View Holder pattern (use recycled view passed into this method as the second parameter) for smoother scrolling.
It means that you need to use View Holder pattern in your Adapter. The point of using View Holder is to reusing the views because inflating and using findViewById are slow.
When you're using the following code:
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder mViewHolder;
mViewHolder = new ViewHolder();
LayoutInflater vi = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = vi.inflate(R.layout.activity_friend_list_row, parent, false);
mViewHolder.cb = (CheckBox) convertView.findViewById(R.id.checkBox);
convertView.setTag(mViewHolder);
...
return convertView;
}
you're not reusing the views but instead you always create new views.
You need to change your code to something like this (please check the comment):
// class for holding the cached view
static class ViewHolder {
TextView tvFriendsName;
ImageView imvThumbImage;
CheckBox cbInviteFriend;
}
public View getView(final int position, View convertView, ViewGroup parent) {
// holder of the views to be reused.
ViewHolder viewHolder;
// get data based on the position
HashMap<String, String> song = data.get(position);
// if no previous views found
if (convertView == null) {
// create the container ViewHolder
viewHolder = new ViewHolder();
// inflate the views from layout for the new row
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
convertView = inflater.inflate(R.layout.rowlayout, parent, false);
// set the view to the ViewHolder.
viewHolder.cbInviteFriend = convertView.findViewById(R.id.checkBox);
viewHolder.tvFriendsName = convertView.findViewById(R.id.friendsName);
viewHolder.imvThumbImage = convertView.findViewById(R.id.list_image);
// save the viewHolder to be reused later.
convertView.setTag(viewHolder);
} else {
// there is already ViewHolder, reuse it.
viewHolder = (ViewHolder) convertView.getTag();
}
// now we can set populate the data via the ViewHolder into views
viewHolder.tvFriendsName.setText(song.get(InviteFriends.KEY_DISPLAY_NAME));
imageLoader.DisplayImage(song.get(InviteFriends.KEY_IMAGEPROFILE_URL), viewHolder.imvThumbImage);
viewHolder.cbInviteFriend.isChecked(InviteFriends.isChecked[position]);
return convertView;
}
My suggestion is try to use convertView = vi.inflate(R.layout.activity_friend_list_row, null); insted of convertView = vi.inflate(R.layout.activity_friend_list_row, parent, false); this may help you.
:-
okey.. insted of accessing like this TextView friendsname = (TextView) convertView.findViewById(R.id.friendsName); // title
ImageView thumb_image = (ImageView) convertView.findViewById(R.id.list_image); // thumb image
you have to use viewholder class in your adapter
for example
static class ViewHolder {
public TextView text;
public ImageView image;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
// reuse views
if (rowView == null) {
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.rowlayout, null);
// configure view holder
ViewHolder viewHolder = new ViewHolder();
viewHolder.text = (TextView) rowView.findViewById(R.id.TextView01);
viewHolder.image = (ImageView) rowView
.findViewById(R.id.ImageView01);
rowView.setTag(viewHolder);
}
// fill data
ViewHolder holder = (ViewHolder) rowView.getTag();
String s = names[position];
holder.text.setText(s);
if (s.startsWith("Windows7") || s.startsWith("iPhone")
|| s.startsWith("Solaris")) {
holder.image.setImageResource(R.drawable.no);
} else {
holder.image.setImageResource(R.drawable.ok);
}
return rowView;
}
What i have done is created a BaseSpinnerAdapter class and reusing it if needed
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.BaseAdapter
import androidx.annotation.LayoutRes
/**
* #param T Model class
* #param VH ViewHolder class, which holds the view to reuse it
* */
abstract class BaseSpinnerAdapter<T, VH>(context: Context?, private val items: ArrayList<T>) :
BaseAdapter() {
private var inflater: LayoutInflater = LayoutInflater.from(context)
/** use viewHolder pattern to reusing the views
* #param p0 current view position
* #param p1
* #param viewGroup
* */
override fun getView(p0: Int, p1: View?, viewGroup: ViewGroup?): View {
var pClone = p1
val viewHolder: VH
if (pClone == null) {
pClone = inflater.inflate(setSpinnerItemLayout(), viewGroup, false)
viewHolder = createViewHolder(pClone)
pClone?.tag = viewHolder
} else {
viewHolder = pClone.tag as VH
}
getView(viewHolder, p0)
return pClone!!
}
override fun getItem(p0: Int): T {
return items[p0]
}
override fun getItemId(p0: Int): Long {
return p0.toLong()
}
override fun getCount(): Int {
return items.size
}
#LayoutRes
abstract fun setSpinnerItemLayout(): Int
abstract fun getView(viewHolder: VH, position: Int)
abstract fun createViewHolder(view: View?): VH
}
Here is an example How you can use BaseSpinnerAdapter in your implementation. I believe that there is no need to detail out the code description.
class SpinnerImplAdapter(context: Context?, private val items: ArrayList<AnyModelClass>) : BaseSpinnerAdapter<AnyModelClass, SpinnerImplAdapter.ViewHolderImp>(context, items) {
override fun setSpinnerItemLayout(): Int {
return R.layout.spinner_item
}
override fun createViewHolder(view: View?): ViewHolderImp {
return ViewHolderImp(view)
}
override fun getView(viewHolder: ViewHolderImp, position: Int) {
val model = items[position]
viewHolder.textView?.text = "" // model.etc get anything you want
}
/**
* I have used kotlin extension to get the viewId,
* if you are not using then simply call the view.findViewById(R.id.yourView)
* */
class ViewHolderImp(view: View?) {
val textView: TextView? = view?.textView
}
}
Is it possible to get an item view based on its position in the adapter and not in the visible views in the ListView?
I am aware of functions like getChildAt() and getItemIdAtPosition() however they provide information based on the visible views inside ListView. I am also aware that Android recycles views which means that I can only work with the visible views in the ListView.
My objective is to have a universal identifier for each item since I am using CursorAdapter so I don't have to calculate the item's position relative to the visible items.
Here's how I accomplished this. Within my (custom) adapter class:
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if (convertView == null) {
LayoutInflater inflater = context.getLayoutInflater();
view = inflater.inflate(textViewResourceId, parent, false);
final ViewHolder viewHolder = new ViewHolder();
viewHolder.name = (TextView) view.findViewById(R.id.name);
viewHolder.button = (ImageButton) view.findViewById(R.id.button);
viewHolder.button.setOnClickListener
(new View.OnClickListener() {
#Override
public void onClick(View view) {
int position = (int) viewHolder.button.getTag();
Log.d(TAG, "Position is: " +position);
}
});
view.setTag(viewHolder);
viewHolder.button.setTag(items.get(position));
} else {
view = convertView;
((ViewHolder) view.getTag()).button.setTag(items.get(position));
}
ViewHolder holder = (ViewHolder) view.getTag();
return view;
}
Essentially the trick is to set and retrieve the position index via the setTag and getTag methods. The items variable refers to the ArrayList containing my custom (adapter) objects.
Also see this tutorial for in-depth examples. Let me know if you need me to clarify anything.
See below code:
public static class ViewHolder
{
public TextView nm;
public TextView tnm;
public TextView tr;
public TextView re;
public TextView membercount;
public TextView membernm;
public TextView email;
public TextView phone;
public ImageView ii;
}
class ImageAdapter extends ArrayAdapter<CoordinatorData>
{
private ArrayList<CoordinatorData> items;
public FoodDriveImageLoader imageLoader;
public ImageAdapter(Context context, int textViewResourceId,ArrayList<CoordinatorData> items)
{
super(context, textViewResourceId, items);
this.items = items;
}
public View getView(int position, View convertView, ViewGroup parent)
{
View v = convertView;
ViewHolder holder = null;
if (v == null)
{
try
{
holder=new ViewHolder();
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
imageLoader = new FoodDriveImageLoader(FoodDriveModule.this);
v = vi.inflate(R.layout.virtual_food_drive_row, null);
//System.out.println("layout is null.......");
holder.nm = (TextView) v.findViewById(R.id.name);
holder.tnm = (TextView) v.findViewById(R.id.teamname);
holder.tr = (TextView) v.findViewById(R.id.target);
holder.re = (TextView) v.findViewById(R.id.received);
holder.membercount = new TextView(FoodDriveModule.this);
holder.membernm = new TextView(FoodDriveModule.this);
holder.email = new TextView(FoodDriveModule.this);
holder.phone = new TextView(FoodDriveModule.this);
holder.ii = (ImageView) v.findViewById(R.id.icon);
v.setTag(holder);
}
catch(Exception e)
{
System.out.println("Excption Caught"+e);
}
}
else
{
holder=(ViewHolder)v.getTag();
}
CoordinatorData co = items.get(position);
holder.nm.setText(co.getName());
holder.tnm.setText(co.getTeamName());
holder.tr.setText(co.getTarget());
holder.re.setText(co.getReceived());
holder.ii.setTag(co.getImage());
imageLoader.DisplayImage(co.getImage(), FoodDriveModule.this , holder.ii);
if (co != null)
{
}
return v;
}
}
A better option is to identify using the data returned by the CursorAdapter rather than visible views.
For example if your data is in a Array , each data item has a unique index.
Here, Its very short described code, you can simple re-use viewholder pattern to increase listview performance
Write below code in your getview() method
ViewHolder holder = new ViewHolder();
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.skateparklist, null);
holder = new ViewHolder();
holder.headlineView = (TextView) convertView
.findViewById(R.id.textView1);
holder.DistanceView = (TextView) convertView
.findViewById(R.id.textView2);
holder.imgview = (NetworkImageView) convertView
.findViewById(R.id.imgSkatepark);
convertView.setTag(holder); //PLEASE PASS HOLDER AS OBJECT PARAM , CAUSE YOU CAN NOY PASS POSITION IT WILL BE CONFLICT Holder and Integer can not cast
//BECAUSE WE NEED TO REUSE CREATED HOLDER
} else {
holder = (ViewHolder) convertView.getTag();
}
// your controls/UI setup
holder.DistanceView.setText(strDistance);
......
return convertview
Listview lv = (ListView) findViewById(R.id.previewlist);
final BaseAdapter adapter = new PreviewAdapter(this, name, age);
confirm.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
View view = null;
String value;
for (int i = 0; i < adapter.getCount(); i++) {
view = adapter.getView(i, view, lv);
Textview et = (TextView) view.findViewById(R.id.passfare);
value=et.getText().toString();
Toast.makeText(getApplicationContext(), value,
Toast.LENGTH_SHORT).show();
}
}
});
I have created a custom cursor adapter which fetches the value from the database and displays it in my defined view.
I have one textview and imageview.
Depends on the text in the database image changes accordingly.
I have defined MyArrayAdapter as follows, but it gives an error.
public class MyArrayAdapter extends SimpleCursorAdapter {
private final Context context;
private final Cursor cursor;
private final String[] from;
static class ViewHolder {
public ImageView imageView;
public TextView textView;
}
public MyArrayAdapter(Context context, int layout, Cursor c, String[] from,
int[] to) {
super(context, layout, c, from, to);
this.context = context;
this.cursor = c;
this.from = from;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
ViewHolder holder;
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.todo_row,null,true);
holder = new ViewHolder();
holder.textView = (TextView) rowView.findViewById(R.id.todo_edit_summary);
holder.imageView = (ImageView) rowView.findViewById(R.id.icon);
rowView.setTag(holder);
}else{
holder = (ViewHolder) rowView.getTag();
}
String s = cursor.getString(cursor.getColumnIndex(from[0]));
holder.textView.setText(s);
if (cursor.getString(cursor.getColumnIndex("category")) == "Urgent"){
holder.imageView.setImageResource(R.drawable.urgent);
}else{
holder.imageView.setImageResource(R.drawable.reminder);
}
return rowView;
}
}
(Update from deleted answer)
The following code is working fine, but they are showing the same value in each and every entry in the ListView. I have extended SimpleCursorAdapter. Am I making any mistakes with managing the cursor?
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
ViewHolder holder;
if (rowView == null) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.todo_row,null,true);
holder = new ViewHolder();
holder.textView = (TextView) rowView.findViewById(R.id.label);
holder.imageView = (ImageView) rowView.findViewById(R.id.icon);
rowView.setTag(holder);
}else{
holder = (ViewHolder) rowView.getTag();
}
String s = cursor.getString(cursor.getColumnIndex(from[0]));
holder.textView.setText(s);
if ((cursor.getString(cursor.getColumnIndex("category"))).equals("Urgent")){
holder.imageView.setImageResource(R.drawable.reminder);
}else{
holder.imageView.setImageResource(R.drawable.urgent);
}
return rowView;
}
As far as I can tell the only part of SimpleCursorAdapter you are using is the from parameter which you can easily substitute with a literal string since you are extending it. While I'm not familiar with the "guts" of the code it's pretty safe to assume that since getView is not mentioned in SimpleCursorAdapter documentation that it's not meant to be overridden lightly since doing so can break it like in your example.
Based on what you have, I've adapted it to extend CursorAdapter instead and by splitting the code you had in getView into newView and bindView, both of which are defined as abstract methods in CursorAdapter.
public class MyCursorAdapter extends CursorAdapter {
static class ViewHolder {
public ImageView imageView;
public TextView textView;
}
public MyArrayAdapter(Context context, Cursor c) {
super(context, c);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.todo_row,null,true);
ViewHolder holder = new ViewHolder();
holder.textView = (TextView) rowView.findViewById(R.id.todo_edit_summary);
holder.imageView = (ImageView) rowView.findViewById(R.id.icon);
rowView.setTag(holder);
return rowView;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder = (ViewHolder) view.getTag();
String s = cursor.getString(cursor.getColumnIndex("whatever from[] represented"));
holder.textView.setText(s);
if (cursor.getString(cursor.getColumnIndex("category")) == "Urgent"){
holder.imageView.setImageResource(R.drawable.urgent);
}else{
holder.imageView.setImageResource(R.drawable.reminder);
}
}
}
To compare between value of two strings use equals() of String class. Donot use == operator in this case
So use the following code
if ((cursor.getString(cursor.getColumnIndex("category"))).equals("Urgent")){
holder.imageView.setImageResource(R.drawable.urgent);
}else{
holder.imageView.setImageResource(R.drawable.reminder);
}