I have a table:
id, code, LandName
items
----
----
----
Loading data into a ListView:
Cursor c = myDb.SelectData();
lisView1.setAdapter(new CountryAdapter(this, c));
the Query:
public Cursor SelectData() {
try {
SQLiteDatabase db;
db = this.getReadableDatabase(); // Read Data
Cursor cursor = db.query(TABLE_COUNTRY, new String[] { "ID AS _id, *" },
null, null, null, null, null);
if(cursor != null) {
return cursor;
}
else{
return null;
}
} catch (Exception e) {
return null;
}
}
the Adapter:
public class CountryAdapter extends CursorAdapter {
private LayoutInflater _inflater;
CountryHolder holder;
public CountryAdapter(Context context, Cursor crs) {
super(context, crs);
_inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View newView(Context context, Cursor crs, ViewGroup parent) {
View view = _inflater.inflate(R.layout.activit_column, parent, false);
holder = new CountryHolder();
txtID = view.findViewById(R.id.ColID);
txtCode = view.findViewById(R.id.ColCode);
txtCountry = view.findViewById(R.id.ColCountry);
view.setTag(holder);
return view;
}
@Override
public void bindView(View view, Context context, Cursor crs) {
holder = (CountryHolder) view.getTag();
// holder.text.setText(c.getString(4));
txtID.setText(crs.getString(crs.getColumnIndexOrThrow("ID")));
txtCode.setText(crs.getString(crs.getColumnIndexOrThrow("Code")));
txtCountry.setText(crs.getString(crs.getColumnIndexOrThrow("Country")));
// s = cursor.getString(cursor.getColumnIndexOrThrow("Country"));
// if(s.equals("Italy")){
// Problem !!!!!
if (txtCountry.getText().equals("Italy"))
txtCountry.setTextColor(Color.RED);
// }
}
}
public class CountryHolder {
TextView ID;
TextView Code;
TextView Country;
}
}
Now my problem:
When i add the if condition
if (txtCountry.getText().equals("Italy"))
txtCountry.setTextColor(Color.RED);
The first row and the row it affects are colored, not just the affected row(s).
What is the reason for this?
I haven't any explanation for this.
How can I fix it?
Thanks
newView() method, you're doing it like this:holder = new CountryHolder();
txtID = view.findViewById(R.id.ColID);
txtCode = view.findViewById(R.id.ColCode);
txtCountry = view.findViewById(R.id.ColCountry);
view.setTag(holder);
txtID, txtCode, and txtCountry are getting saved as fields of the Adapter, not fields of the holder. Every time a new view is inflated, those global adapter variables get overwritten, causing bindView to reference the wrong views.
Solution: To make these, the fields of the Holder:
@Override
public View newView(Context context, Cursor crs, ViewGroup parent) {
View view = _inflater.inflate(R.layout.activit_column, parent, false);
// Like this
CountryHolder holder = new CountryHolder();
holder.ID = view.findViewById(R.id.ColID);
holder.Code = view.findViewById(R.id.ColCode);
holder.Country = view.findViewById(R.id.ColCountry);
view.setTag(holder);
return view;
}
2 . You should have else block for color:
if ("Italy".equalsIgnoreCase(countryName)) {
holder.Country.setTextColor(Color.RED);
} else {
holder.Country.setTextColor(Color.BLACK); // any color you want...
}
Corrected CountryAdapter:
public class CountryAdapter extends CursorAdapter {
private LayoutInflater _inflater;
public CountryAdapter(Context context, Cursor crs) {
super(context, crs, 0);
_inflater = LayoutInflater.from(context);
}
@Override
public View newView(Context context, Cursor crs, ViewGroup parent) {
View view = _inflater.inflate(R.layout.activit_column, parent, false);
// Properly store the views inside the ViewHolder
CountryHolder holder = new CountryHolder();
holder.ID = view.findViewById(R.id.ColID);
holder.Code = view.findViewById(R.id.ColCode);
holder.Country = view.findViewById(R.id.ColCountry);
view.setTag(holder);
return view;
}
@Override
public void bindView(View view, Context context, Cursor crs) {
CountryHolder holder = (CountryHolder) view.getTag();
holder.ID.setText(crs.getString(crs.getColumnIndexOrThrow("ID")));
holder.Code.setText(crs.getString(crs.getColumnIndexOrThrow("Code")));
String countryName = crs.getString(crs.getColumnIndexOrThrow("Country"));
holder.Country.setText(countryName);
// else block when styling recycled views
if ("Italy".equalsIgnoreCase(countryName)) {
holder.Country.setTextColor(Color.RED);
} else {
holder.Country.setTextColor(Color.BLACK); // any color
}
}
static class CountryHolder {
TextView ID;
TextView Code;
TextView Country;
}
}