在listview中更新视图的值时,适配器不会更新

时间:2015-03-21 13:43:51

标签: android listview android-listview android-arrayadapter android-viewholder

我正在使用ListView来显示我需要计算的一些元素的列表。我的列表视图看起来像这样

enter image description here

当我点击加号和减号按钮或重置按钮时,值“3”会更新。这就是我在CustomListViewAdapter

中实现这一点的方法
holder.plusButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            ViewGroup parent = (ViewGroup) v.getParent();
            TextView tv = (TextView) parent.findViewById(R.id.count);

            int count = Integer.parseInt((String) tv.getText());
            count++;
            tv.setText(String.valueOf(count));
            int currentVal = Integer.parseInt(totalCount.getText().toString());
            totalCount.setText(String.valueOf(currentVal + 1));
        }
    });

我正在使用ViewHolder模式。

现在问题是,在更新值之后,它没有在适配器中更新。即当我尝试循环适配器时,我仍然得到我最初设置的值3而不是更新值。我做得对吗还是有更好的方法。如何确保适配器具有更新的值。

第二个问题:由于适配器没有得到更新,当我试图从列表中检索值以将其发送到某处时,我在执行此操作时会得到nullpointer

view = listView.getChildAt(i).findViewById(R.id.count);

列表中的视图在屏幕上不可见。即如果我有10个这样的行,屏幕上只能看到5行,当我尝试访问第6行时,我会得到上面代码块的空指针。那我该如何访问listview值?

编辑:我的getView方法源代码是

public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder = null;
    Counter rowItem = getItem(position);

    LayoutInflater mInflater = (LayoutInflater) context
            .getSystemService(Activity.LAYOUT_INFLATER_SERVICE);

    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.counter_list, null);
        holder = new ViewHolder();

        convertView.findViewById(R.id.parentLayoutRow).setBackgroundColor(Color.parseColor(rowItem.getPrimaryColor()));

        holder.resetButton = (Button) convertView.findViewById(R.id.buttonReset);
        holder.counterName = (TextView) convertView.findViewById(R.id.counterName);
        holder.counterDesc = (TextView) convertView.findViewById(R.id.counterDesc);
        holder.count = (TextView) convertView.findViewById(R.id.count);
        holder.minusButton = (Button) convertView.findViewById(R.id.buttonMinus);
        holder.plusButton = (Button) convertView.findViewById(R.id.buttonPlus);

        convertView.setTag(holder);
    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    holder.resetButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            ViewGroup parent = (ViewGroup) v.getParent();
            TextView tv = (TextView) parent.findViewById(R.id.count);

            int currentVal = Integer.parseInt(totalCount.getText().toString());
            totalCount.setText(String.valueOf(currentVal - Integer.parseInt(tv.getText().toString())));

            tv.setText(String.valueOf(0));
        }
    });
    holder.counterName.setText(rowItem.getName());
    holder.counterDesc.setText(rowItem.getDesc());
    holder.count.setText(String.valueOf(rowItem.getCount()));
    holder.resetButton.setBackgroundColor(Color.parseColor(rowItem.getButtonColor()));
    holder.minusButton.setBackgroundColor(Color.parseColor(rowItem.getButtonColor()));
    holder.minusButton.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            ViewGroup parent = (ViewGroup) v.getParent();
            TextView tv = (TextView) parent.findViewById(R.id.count);

            int count = Integer.parseInt((String) tv.getText());

            if (count > 0) {
                count--;
                tv.setText(String.valueOf(count));
                int currentVal = Integer.parseInt(totalCount.getText().toString());
                totalCount.setText(String.valueOf(currentVal - 1));
            } 
        }
    });
    holder.plusButton.setBackgroundColor(Color.parseColor(rowItem.getButtonColor()));
    holder.plusButton.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            ViewGroup parent = (ViewGroup) v.getParent();
            TextView tv = (TextView) parent.findViewById(R.id.count);

            int count = Integer.parseInt((String) tv.getText());
            count++;
            tv.setText(String.valueOf(count));
            int currentVal = Integer.parseInt(totalCount.getText().toString());
            totalCount.setText(String.valueOf(currentVal + 1));
        }
    });

    return convertView;
}

现在如何在此函数holder.minusButton.setOnClickListener(new OnClickListener()

中更新适配器值

2 个答案:

答案 0 :(得分:3)

ListView中的视图不保留其状态。正如ViewHolder向您展示的那样,当他们离开屏幕并稍后重建时,他们会被抛弃:他们总是被适配器中的值驱动。

所以你要做的是找到支持列表的Adapter中的条目并更新THAT,然后让ListView重绘自己。看看ListView.getAdapter(),然后看看Adapter.getItem()。您会注意到没有Adapter.setItem(),并且您无法更改现有String或Integer的值(它们是不可变的),因此您的列表项必须是包装该值的Object。或者您可以使用具有增量方法的AtomicInteger。 然后,您需要调用ListView.notifyDataSetChanged(),因为它不会在包装器对象内部进行检查。

答案 1 :(得分:1)

您所做的只是更改textview文本,而不是更改您使用适配器创建的数据。如果您需要描述的行为,则需要更改适配器的数据,然后在适配器上调用notifyDataSetChanged方法。