ArrayAdapter 行颜色方法更改多行

ArrayAdapter row color method changes multiple rows

我正在尝试为自定义列表视图制作 ArrayAdapter。当用户单击 listView 上的 "finish" 时,我希望该特定条目的行颜色变为红色,然后隐藏 "finish" 按钮并显示另一个名为 [=19= 的按钮].到目前为止,这很好用,但它会更改可滚动列表中更下方行的行和按钮配置。

我研究了许多不同的解决方案,并且几乎尝试了我所看到的所有建议。我一定是遗漏了什么...

public class ResultsAdapter extends BaseAdapter {
private static String LOGTAG = "Logtag: " + Thread.currentThread()
        .getStackTrace()[2].getClass().getSimpleName(); // log tag for records
Context mContext; // add context
LayoutInflater inflater; // instance of inflater
ResultDataSource resultDataSource;
// lists of result
private List<Result> mainDataList = null;
private ArrayList<Result> arraylist;

// instance constructor
public ResultsAdapter(Context context, List<Result> mainDataList,
                      ResultDataSource resultDataSource) {
    this.resultDataSource = resultDataSource;
    mContext = context;
    inflater = LayoutInflater.from(mContext);
    // create a copy of the main list so we don't end up damagaing the original list
    this.arraylist = new ArrayList<Result>();
    this.arraylist.addAll(mainDataList);

}

@Override
public int getCount() {
    return arraylist.size();
}

@Override
public Object getItem(int position) {
    return arraylist.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView( int index, View view, final ViewGroup parent) {

    if (view == null) {
        // build inflater to create a new row for each row in the Results table
        LayoutInflater inflater = LayoutInflater.from(parent.getContext());
        view = inflater.inflate(R.layout.activity_list_template_results, parent, false);
    }



    Log.i("Results Adapter ", "mainDataList is of size " + arraylist.size() + " index is " + index);
    // create an result that will hold the data for the row item.
    final Result result = arraylist.get(index);

    // instance of the finish button
    final Button btnFinish = (Button) view.findViewById(R.id.btn_boat_finished);

    // instance of the finish button
    final Button btnReset = (Button) view.findViewById(R.id.btn_boat_reset_finished);

    // wire text views and set the associated text to them.
    final TextView tv1 = (TextView) view.findViewById(R.id.txt_hd_results_ID);
    tv1.setText(result.getResultsId() + "");

    final TextView tv2 = (TextView) view.findViewById(R.id.txt_hd_results_race_id);
    tv2.setText(result.getResultsRaceId() + "");
    final TextView tv3 = (TextView) view.findViewById(R.id.txt_hd_results_boat_id);
    tv3.setText(result.getResultsBoatId() + "");
    final TextView tv4 = (TextView) view.findViewById(R.id.txt_hd_results_Visible);
    tv4.setText(result.getResultsVisible() + "");
    final TextView tv5 = (TextView) view.findViewById(R.id.txt_hd_results_Name);
    tv5.setText(result.getBoatName() + "");
    final TextView tv6 = (TextView) view.findViewById(R.id.txt_hd_results_Class);
    tv6.setText(result.getBoatClass() + "");
    final TextView tv7 = (TextView) view.findViewById(R.id.txt_hd_results_SailNum);
    tv7.setText(result.getBoatSailNum() + "");
    final TextView tv8 = (TextView) view.findViewById(R.id.txt_hd_finish_time);
    if (result.getResultsBoatFinishTime() != null) {
        tv8.setText(result.getResultsBoatFinishTime() + "");
    } else {
        tv8.setText("");
    }

    final View finalView = view;

    // add the text views the list
    final ArrayList<TextView> textViews = new ArrayList<TextView>() {{
        add(tv1);
        add(tv2);
        add(tv3);
        add(tv4);
        add(tv5);
        add(tv6);
        add(tv7);
        add(tv8);
    }};

    // programmatically change text style.
    for (TextView t : textViews) {
        t.setTextColor(Color.parseColor("#000000")); // make the text black
        t.setTypeface(Typeface.DEFAULT_BOLD); // make text bold
    }

    Result r = arraylist.get(index);

    // on refresh of list.
    // If there is a finish time present then make the row red
    if (r.getResultsBoatFinishTime() != null) {

        //hide the finish button and show the reset button instead.
        btnFinish.setVisibility(View.GONE);
        btnReset.setVisibility(View.VISIBLE);
        // set the text of the reset button. Click count to reset is 3
        btnReset.setText("Reset [3]");
        //set the row color to red
        view.setBackgroundColor(view.getResources().getColor(R.color.red06));
        //set the text of each text box white
        for (TextView t : textViews) {
            t.setTextColor(Color.parseColor("#ffffff")); // make the text white
        }
    }


        // set the function of each finish button
        btnFinish.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                LocalTime localTime = LocalTime.now();// capture the current time
                //format time as string
                String timeFormatted = GlobalContent.localTimeToString(localTime);
                //insert time into database.
                resultDataSource.updateFinishTime(result.getResultsId(), timeFormatted);
                //set the result entry's finish time to the same.
                result.setResultsBoatFinishTime(timeFormatted);
                Log.i(LOGTAG, "Finish time for " + result.getBoatName() + " is: " + localTime + " formatted: " + timeFormatted);
                //hide the finish button and show the reset button instead.
                btnFinish.setVisibility(View.GONE);
                btnReset.setVisibility(View.VISIBLE);
                // set the text of the reset button. Click count to reset is 3
                btnReset.setText("Reset [3]");
                //set the row color to red
                finalView.setBackgroundColor(v.getResources().getColor(R.color.red06));
                //set the text of each text box white
                for (TextView t : textViews) {
                    t.setTextColor(Color.parseColor("#ffffff")); // make the text white
                }
                notifyDataSetChanged();
            }
        });

    // resets the finish time to 0 after 3 clicks
    btnReset.setOnClickListener(new View.OnClickListener() {
        int counter = 3; // initial click count
        @Override
        public void onClick(View v) {
            String message; // message to pass to the user
            if (counter == 1) { // check how many clicks are left, if 1 then...
                //blank out database entry
                resultDataSource.updateFinishTime(result.getResultsId(), null);
                //blank out result object fnish time entry
                result.setResultsBoatFinishTime(null);
                //hide reset button and show finish button
                btnReset.setVisibility(View.GONE);
                btnFinish.setVisibility(View.VISIBLE);
                counter = 3; // reset counter
                //output message
                message = result.getBoatName() + "'s finish time is now RESET";
                //set the row color to transparent
                finalView.setBackgroundColor(Color.parseColor("#00000000"));
                // make each text box text black
                for (TextView t : textViews) {
                    t.setTextColor(Color.parseColor("#000000")); // make the text black

                }
                notifyDataSetChanged();
            } else {
                counter--; // decrement the click counter
                //state how many clicks are left in the toast menu
                message = "To reset, click \"Reset\" " + counter + " more times";
                //change the reset button text to indicate how many clicks are left.
                btnReset.setText("Reset [" + counter + "]");
            }
            Toast.makeText(v.getContext(), message, Toast.LENGTH_LONG).show();


        }
    });

    return view;
}

//filter results based on text entered into text box in the Results menu
public void filter(String charText) {
    charText = charText.toLowerCase(Locale.getDefault());
    mainDataList.clear();
    if (charText.length() == 0) {
        mainDataList.addAll(arraylist);
    } else {
        for (Result result : arraylist) {
            if (result.getBoatName().toLowerCase(Locale.getDefault())
                    .contains(charText)) {
                mainDataList.add(result);
            }
        }
    }
    notifyDataSetChanged();
}
}
if (r.getResultsBoatFinishTime() != null) {

    /* ... */

    //set the row color to red
    view.setBackgroundColor(view.getResources().getColor(R.color.red06));

    /* ... */
}

您忘记了 View 回收。 View 你涂成红色的也被重新用于显示其他行。由于您已将 View 的背景颜色设置为红色,因此其他行也将具有红色背景。

一个简单的解决方案是添加一个 else 分支:

} else {
    view.setBackgroundColor(view.getResources().getColor(R.color.myoriginalcolor));
}