Android - 列表视图,其中视图更改了所选行的背景

时间:2015-03-06 22:25:23

标签: android android-listview row android-viewholder

我一直在查找本网站和其他人的帖子,但是找不到我需要的工作代码。我目前有一个自定义行的列表视图,我按颜色交替(灰色和透明)。我试图让所选行变为蓝色(并在按下另一行时返回原始颜色),并且即使我滚动它也保持选中状态。

编辑:这是完整的列表适配器,减去如何填充几个图标:

public class MultiActivateAdapter  extends ArrayAdapter<Model> {

private final List<Model> list;
private final List<Model> listInfo;
private final List<Model> listAlert;
private final List<Model> listSecondAlert;

private int _index = -1;

ArrayList<String> selectedStrings = new ArrayList<String>();

private final Activity context;
boolean checkAll_flag = false;
boolean checkItem_flag = false;

public MultiRenewAdapter2(Activity context, List<Model> list, List<Model> listInfo, List<Model> listAlert, List<Model> listSecondAlert) {
    super(context, R.layout.multirenewrow2, list);
    this.context = context;
    this.list = list;
    this.listInfo = listInfo;
    this.listAlert = listAlert;
    this.listSecondAlert = listSecondAlert;
}

static class ViewHolder {
    protected TextView text;
    protected ImageView alert;
    protected CheckBox checkbox;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    LayoutInflater inflator = context.getLayoutInflater();

    ViewHolder viewHolder;

    if (convertView == null) {
        convertView = inflator.inflate(R.layout.multiactivaterow, null);

        viewHolder = new ViewHolder();
        viewHolder.alert = (ImageView) convertView.findViewById(R.id.alert);
        viewHolder.text = (TextView) convertView.findViewById(R.id.label);
        viewHolder.checkbox = (CheckBox) convertView.findViewById(R.id.check);

        convertView.setTag(viewHolder);
        convertView.setTag(R.id.label, viewHolder.text);
        convertView.setTag(R.id.check, viewHolder.checkbox);

    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }
        viewHolder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                int getPosition = (Integer) buttonView.getTag();  // Here we get the position that we have set for the checkbox using setTag.
                list.get(getPosition).setSelected(buttonView.isChecked()); // Set the value of checkbox to maintain its state.

            }
        });


    if (position == _index)
    {
        convertView.setBackgroundColor(context.getResources().getColor(R.color.DeepSkyBlue));
    }
    else
    {
        convertView.setBackgroundColor(context.getResources().getColor(R.color.transparent));
        if (position % 2 == 0)
        {
            convertView.setBackgroundColor(Color.TRANSPARENT);
        }
        else
        {
            convertView.setBackgroundColor(Color.LTGRAY);
        }
    }


        viewHolder.checkbox.setTag(position); // This line is important.

    //some code removed to show icon population

    viewHolder.text.setText(list.get(position).getName());
    viewHolder.checkbox.setChecked(list.get(position).isSelected());

    return convertView;
}

public void setClicked(int index)
{
    _index = index;
    this.notifyDataSetChanged();
}
}

来自适配器曾经属于旧活动的代码:

listView.setOnItemClickListener(new AdapterView.OnItemClickListener()
    {
        @Override
        public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {

                try {
                    adapt.setClicked(position);

                } catch (Exception e)  {
                    System.out.println(e);
                }
                adapt.notifyDataSetChanged();
....

此代码曾用于我的所有其他listViews,但由于它使用/依赖于不同的数组和其他东西,我不得不改变一些东西,这使得我可以保存显示的所选复选框。

3 个答案:

答案 0 :(得分:1)

现在您的代码开始变得更加清晰,即使它可以通过删除旧的或部分/重复的代码来使用清理作业。我的代码建议如下。基本上你应该在convertView == null的if / else块之外设置Checkbox监听器。这两个条件都需要Checkbox事件。

if (convertView == null) {
    convertView = inflator.inflate(R.layout.multiselectrow, null);

    viewHolder = new ViewHolder();
    viewHolder.alert = (ImageView) convertView.findViewById(R.id.alert);
    viewHolder.text = (TextView) convertView.findViewById(R.id.label);
    viewHolder.checkbox = (CheckBox) convertView.findViewById(R.id.check);
    convertView.setTag(viewHolder);
    convertView.setTag(R.id.label, viewHolder.text);
    convertView.setTag(R.id.check, viewHolder.checkbox);

} else {
    viewHolder = (ViewHolder) convertView.getTag();
}
viewHolder.checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {

@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    int getPosition = (Integer) buttonView.getTag();  // Here we get the position that we have set for the checkbox using setTag.
    list.get(getPosition).setSelected(buttonView.isChecked()); // Set the value of checkbox to maintain its state.

    setClicked(getPosition);     // NEW
    }
});
if (position == _index) {
...

一个主要问题是我没有清楚地看到你在哪里设置_index。我注意到它是在你的笔记中的setClicked事件中,但是相对于你的其他代码在哪里呢?清晰度可能更好。

无论如何,使用事件监听器设置_index并在getView中检查变量的设计在同步中存在问题。可以单击事件或按钮,但这不一定会触发getView方法进行刷新。首先尝试一下你的教育,看看你的设计是否可行,但对不起我有疑问。

答案 1 :(得分:0)

我通常在某个UI元素(如TextView)上设置属性,而不是convertView。在你的布局中试试这个:

android:focusable="true"
android:focusableInTouchMode="true"

一旦选中,这可以在视图上突出显示。我通常将它们设置为 false ,因为我不需要突出显示行项目。

答案 2 :(得分:0)

我认为你的方法并不完全正确,你的大多数代码都不应该在块if(convertView == null)内。因为如果convertView不为null,你仍然必须设置像setBackgroundResource这样的属性,有意义吗?

我没有像你说的那样看到ListView的任何代码引用。这是一个很好的最佳教程,可以为您提供良好的开端,因为您有很多工作要做。 链接@ Android ListView Checkbox Example。让我们发布... Tommy Kwee