如何强制重绘listview?

时间:2012-06-20 15:45:57

标签: android android-widget android-listview android-adapter

这个问题与其他类似名称的问题略有不同。我没有尝试更新列表中的数据,我正在尝试更新列表的外观

我的应用程序基于片段使用支持库。我有一个PreferenceActivity,我允许用户为列表中的文本设置他们想要的颜色(适配器读取首选项并设置颜色)。这在大多数情况下都按预期工作。

我遇到的问题如下。当我在屏幕上显示列表(它是一个ListFragment)并拉出菜单时,选择“首选项”并更改颜色首选项。从PreferenceActivity返回列表后,我似乎无法使用指定的新颜色重新绘制列表。

如果我离开列表然后回到它,则会使用新颜色重新生成。

我正在尝试使用onResume进行更改。我目前拥有的代码(似乎没有对列表做任何事情,但改变了标题颜色):

@Override
public void onResume() {
    super.onResume();
    header.setTextColor(MyApplication.header);
    line.setBackgroundColor(MyApplication.header_line);
    subheader.setTextColor(MyApplication.header);
    getListView().invalidateViews();
}

我尝试了invalidateViewsinvalidate。无奈之下,我尝试在适配器上调用notifyDataSetChanged,即使数据本身没有变化。似乎没什么用。

我错过了一些明显的东西,或者没有办法做到这一点?

修改

我的适配器中的'getView`方法:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null)
        convertView = View.inflate(context, layout, null);
    View row = convertView;
    c.moveToPosition(position);
    TextView first = (TextView) convertView.findViewById(R.id.ListItem1);
    TextView second = (TextView) convertView.findViewById(R.id.ListItem2);
    TextView third = (TextView) convertView.findViewById(R.id.ListItem3);
    TextView fourth = (TextView) convertView.findViewById(R.id.ListItem4);

    DecimalFormat df = new DecimalFormat("0.00");
    Double hold = Double.valueOf(c.getString(3));
    Double qty = Double.valueOf(c.getString(1));
    Double total = hold * qty;

    String color = "#FF00FF";
    first.setText(c.getString(2));
    first.setTextColor(MyApplication.shoplistitem_name);
    second.setText(c.getString(4));
    second.setTextColor(MyApplication.shoplistitem_desc);
    third.setText(c.getString(1));
    third.setTextColor(MyApplication.shoplistitem_qty);
    fourth.setText("$" + df.format(total));
    fourth.setTextColor(MyApplication.shoplistitem_desc);

    if (strikethroughState[position] == 1) {
        first.setPaintFlags(first.getPaintFlags()
                | Paint.STRIKE_THRU_TEXT_FLAG);
        second.setPaintFlags(second.getPaintFlags()
                | Paint.STRIKE_THRU_TEXT_FLAG);
        third.setPaintFlags(third.getPaintFlags()
                | Paint.STRIKE_THRU_TEXT_FLAG);
        fourth.setPaintFlags(third.getPaintFlags()
                | Paint.STRIKE_THRU_TEXT_FLAG);
        row.setBackgroundColor(MyApplication.shoplistitem_checked);
    } else {
        first.setPaintFlags(first.getPaintFlags()
                & ~Paint.STRIKE_THRU_TEXT_FLAG);
        second.setPaintFlags(second.getPaintFlags()
                & ~Paint.STRIKE_THRU_TEXT_FLAG);
        third.setPaintFlags(third.getPaintFlags()
                & ~Paint.STRIKE_THRU_TEXT_FLAG);
        fourth.setPaintFlags(third.getPaintFlags()
                & ~Paint.STRIKE_THRU_TEXT_FLAG);
        row.setBackgroundResource(R.color.black);
    }
    return (row);
}

3 个答案:

答案 0 :(得分:9)

notifyDataSetChanged()当然应该为你工作。你是如何处理偏好变化的?如果您只是将首选项提交给SharedPreferences,那么它永远不会更新静态MyApplication变量。你可以发布你用来设置偏好的代码吗?如果您没有使用它,请为颜色首选项设置onPreferenceChangedListener()以在更改时设置该静态变量。

答案 1 :(得分:2)

您应该在适配器上调用notifyDataSetChanged()

答案 2 :(得分:0)

Invalidate,invalidateviews,notifyDatasetChanged,nothin对我有用! 要更新列表视图(使用cursoradapter),我只需:

cur = db.rawQuery( "SELECT * FROM ssnt WHERE mid = 1000" ); //optional, initial query
adapter.changeCursor(cur); // or swapCursor(), cur is the initial and the only cursor 

但要拥有正确的背景颜色,可绘制的下划线文字,我只是这样做:

cur = db.rawQuery( "SELECT * FROM ssnt WHERE mid = 1000" );
adapter.changeCursor(cur);
list.setAdapter(adapter);    //just like I did oncreate

我不喜欢Barak解决方案,因为它似乎很重,并且在不需要时执行代码。