自定义列表适配器未显示正确的背景

Custom List Adaper not displaying correct background

我有一个 android 应用程序,它用行填充屏幕,并且根据是否单击它们,背景应该是红色还是绿色。

如果您单击行,背景将变为相反的颜色。我一直遇到的问题是,如果我单击一行并向下滚动然后向上滚动,通常该行不再设置为正确的颜色。

向下滚动一次

第二次向下滚动

当我滚动时,这些行看似任意改变背景。

我认为问题出在自定义列表适配器上。这是代码:

public class MyCustomListAdapter extends ArrayAdapter<Coin> {

private ArrayList<Coin> yourArray;

public MyCustomListAdapter(Context ctx, ArrayList<Coin> yourArray){
    super(ctx, R.layout.my_custom_list_item, yourArray);
    this.yourArray = yourArray;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    //Re-use rows to save battery
    View row;
    if (convertView == null) {
        //We inflate our custom view for the ListView item
        LayoutInflater inflater = LayoutInflater.from(getContext());
        row = inflater.inflate(
                R.layout.my_custom_list_item, null);
    } else {
        row = convertView;
    }
    Coin coin = yourArray.get(position);
   // String[] name= yourArray.get(position);
    String year = coin.getYear();//name[0];
    String specialty = coin.getSpecialty();//name[2];
    String mintage = coin.getMintage();//name[1];
    String mint = coin.getMint();
    int have = coin.getHave();

    TextView tvListItem1 = (TextView) row.findViewById(R.id.textView_year_tag);
    TextView tvListItem2 = (TextView) row.findViewById(R.id.textView_mint_tag);
    TextView tvListItem3 = (TextView) row.findViewById(R.id.textView_specialty_tag);
    TextView tvListItem4 = (TextView) row.findViewById(R.id.textView_mintage_tag);

    tvListItem1.setText(year);
    tvListItem2.setText(mint);
    tvListItem3.setText(specialty);
    tvListItem4.setText(mintage);

    if(have == 1) {
        row.setBackgroundResource(R.color.have);
    }
    else {
        row.setBackgroundResource(R.color.need);
    }
    return row;
}

如果我删除

 if(have == 1) {
        row.setBackgroundResource(R.color.have);
    }
    else {
        row.setBackgroundResource(R.color.need);
    }

没有这个问题(但创建时行没有​​颜色)

我在 MainActivity

中更改 onItemClick 行的颜色
public class MainActivity extends ListActivity implements AdapterView.OnItemClickListener {

private CoinsDataSource datasource = new CoinsDataSource(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    addValues();
    setUpComponents();
}

private void setUpComponents(){
    ArrayList<Coin> myValuesToDisplay = getDatabaseContent();
    MyCustomListAdapter adapter = new MyCustomListAdapter(this, myValuesToDisplay);
    setListAdapter(adapter);
    getListView().setOnItemClickListener(this);
}
private ArrayList<Coin> getDatabaseContent(){
    datasource.open();
    ArrayList<Coin> coins_list = datasource.getAllCoins(MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    return coins_list;
}

public void addValues()
{
    //datasource = new CoinsDataSource(this);
    datasource.open();

    datasource.createCoin("1856", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1857", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1858", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1859", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1860", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1861", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1862", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1863", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1864", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1865", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1866", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1867", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1868", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1869", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1870", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1871", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1872", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1873", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1874", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1875", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1876", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1877", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1878", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1879", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1880", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1881", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1882", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1883", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1884", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1885", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);


    datasource.close();
}

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    String year_text = ((TextView)view.findViewById(R.id.textView_year_tag)).getText().toString();
    String mint_text = ((TextView)view.findViewById(R.id.textView_mint_tag)).getText().toString();
    String speciality_text = ((TextView)view.findViewById(R.id.textView_specialty_tag)).getText().toString();
    datasource.open();
    int x = datasource.adjust_db(MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE, year_text, mint_text, speciality_text);
    if(x == 0)
    {
        TableRow row1 = (TableRow) view.findViewById(R.id.tableRow);
        row1.setBackgroundResource(R.color.have);
    }
    else
    {
        TableRow row1 = (TableRow) view.findViewById(R.id.tableRow);
        row1.setBackgroundResource(R.color.need);
    }
    datasource.close();
}

知道为什么当我向下滚动时这些更改没有保留吗?

你试过在给它上色时在 if (have = 1) 后面插入一个 break color.have 吗?看起来那段代码没有执行。您需要在 onClick 中找到被点击的硬币并将其 have 值更新为 1,反之在 deselecting 时更新为 0。

目前,您只在 select 时才为该行着色。 当该行从屏幕上移除然后再次显示时,它将从适配器获取颜色,适配器根据硬币的价值决定其颜色。

这是你应该做的:

首先我们要定义这个适配器:

public class MyCustomListAdapter extends ArrayAdapter<Coin> {

private ArrayList<Coin> yourArray;
private LayoutInflater mInflater;

// This will hold the View Contents
public class RowContent{
       TextView tvListItem1;
       TextView tvListItem2;
       TextView tvListItem3;
       TextView tvListItem4;
}

public MyCustomListAdapter(Context ctx, ArrayList<Coin> yourArray){
    super(ctx, R.layout.my_custom_list_item, yourArray);
    this.yourArray = yourArray;
    mInflater = LayoutInflater.from(ctx);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
//Re-use rows to save battery
RowContent theRow;
if (convertView == null) {
    theRow = new RowContent();
    //We inflate our custom view for the ListView item & set it to convertView
    convertView = mInflater.inflate(R.layout.my_custom_list_item, null);

    // Reference the UI Elements
    theRow.tvListItem1 = (TextView) convertView.findViewById(R.id.textView_year_tag);
    theRow.tvListItem2 = (TextView) convertView.findViewById(R.id.textView_mint_tag);
    theRow.tvListItem3 = (TextView) convertView.findViewById(R.id.textView_specialty_tag);
    theRow.tvListItem4 = (TextView) convertView.findViewById(R.id.textView_mintage_tag);

      // set the Row Content as the Tag for the View
      convertView.setTag(theRow);
     } else {

    // the row will be recycled
    theRow = (RowContent) convertView.getTag();
    }

    Coin coin = yourArray.get(position);
    // String[] name= yourArray.get(position);
    String year = coin.getYear();//name[0];
    String specialty = coin.getSpecialty();//name[2];
    String mintage = coin.getMintage();//name[1];
    String mint = coin.getMint();
    int have = coin.getHave();

    theRow.tvListItem1.setText(year);
    theRow.tvListItem2.setText(mint);
    theRow.tvListItem3.setText(specialty);
    theRow.tvListItem4.setText(mintage);

    if(have == 1) {
         convertView.setBackgroundResource(R.color.have);
    }else {
         convertView.setBackgroundResource(R.color.need);
    }
    return convertView;
}

这是回收物品的正确方法...

然后您想这样做而不是手动更改 table 行。

 public class MainActivity extends ListActivity implements AdapterView.OnItemClickListener {

 private CoinsDataSource datasource = new CoinsDataSource(this);
 // Have your MyCustomListAdapter be a class member
 private MyCustomListAdapter adapter;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    addValues();
    setUpComponents();
 }

private void setUpComponents(){
    ArrayList<Coin> myValuesToDisplay = getDatabaseContent();
    // Build the adapter and set it to the member variable
    adapter = new MyCustomListAdapter(this, myValuesToDisplay);
    setListAdapter(adapter);
    getListView().setOnItemClickListener(this);
}

private ArrayList<Coin> getDatabaseContent(){
    datasource.open();
    ArrayList<Coin> coins_list =          datasource.getAllCoins(MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
   return coins_list;
}

public void addValues()
 {
    //datasource = new CoinsDataSource(this);
    datasource.open();

    datasource.createCoin("1856", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1857", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1858", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1859", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1860", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1861", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1862", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1863", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1864", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1865", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1866", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1867", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1868", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1869", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1870", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1871", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1872", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1873", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1874", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1875", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1876", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1877", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1878", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1879", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1880", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1881", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1882", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1883", "D", "NEW TEXT", "2000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1884", "P", "MORE TEXT", "17,450,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);
    datasource.createCoin("1885", "D", "Not NULL", "24,600,000", 0, MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE);


    datasource.close();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    // Update your data in the database
    String year_text = ((TextView)view.findViewById(R.id.textView_year_tag)).getText().toString();
    String mint_text = ((TextView)view.findViewById(R.id.textView_mint_tag)).getText().toString();
    String speciality_text = ((TextView)view.findViewById(R.id.textView_specialty_tag)).getText().toString();
    datasource.open();
    int x = datasource.adjust_db(MySQLiteHelper.TABLE_PENNY_FLYING_EAGLE, year_text, mint_text, speciality_text);
   datasource.close();

    // Get this coin from the adapter, and update the coin data object
    Coin coin = (Coin) adapter.getItem(position)
    coin.setHave(x);

    // Tell your adapter its data has changed (this is what i was referring to)
    adapter.notifyDataSetChanged();

    }
}