简体   繁体   English

如何强制重绘listview?

[英]How to force redraw of listview?

This question is a little different from others of a similar title. 这个问题与其他类似标题略有不同。 I am not trying to update the data in the list, I am trying to update the look of the list. 我不是要更新列表中的数据,我正在尝试更新列表的外观

My app is fragment based using the support library. 我的应用程序基于片段使用支持库。 I have a PreferenceActivity where I allow the user to set the colors they would like for the text in a list (the adapter reads the preference and sets the colors). 我有一个PreferenceActivity,我允许用户为列表中的文本设置他们想要的颜色(适配器读取首选项并设置颜色)。 This is working as expected for the most part. 这在大多数情况下都按预期工作。

The issue I'm having is as follows. 我遇到的问题如下。 When I have the list on the screen (it is a ListFragment) and pull up the menu, choose Preferences and make a change to the color preference. 当我在屏幕上显示列表(它是一个ListFragment)并拉出菜单时,选择“首选项”并更改颜色首选项。 Upon return to the list from the PreferenceActivity, I cannot seem to get the list to redraw itself with the new color specified. 从PreferenceActivity返回列表后,我似乎无法使用指定的新颜色重新绘制列表。

If I navigate away from the list and come back to it, it is regenerated with the new color. 如果我离开列表并返回它,它将使用新颜色重新生成。

I am trying to use onResume to make the change. 我正在尝试使用onResume进行更改。 The code I currently have (that doesn't appear to do anything to the list, but changes the header color as it should): 我目前拥有的代码(似乎没有对列表执行任何操作,但会更改标题颜色):

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

I have tried invalidateViews and invalidate . 我尝试过invalidateViewsinvalidate In desperation I tried calling notifyDataSetChanged on the adapter even though there was no change to the data itself. 无奈notifyDataSetChanged ,我尝试在适配器上调用notifyDataSetChanged ,即使数据本身没有变化。 Nothing seems to work. 似乎没什么用。

Am I missing something obvious, or is there no way to do this? 我错过了一些明显的东西,还是没有办法做到这一点?

EDIT 编辑

The 'getView` method from my adapter: 我的适配器的'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);
}

notifyDataSetChanged() should certainly be working for you. notifyDataSetChanged()当然应该为你工作。 How are you handling the preference change? 你是如何处理偏好变化的? If you're just committing the preference to the SharedPreferences then it's never updating the static MyApplication variable. 如果您只是将首选项提交给SharedPreferences,那么它永远不会更新静态MyApplication变量。 Can you post the code you're using to set the preference? 你可以发布你用来设置偏好的代码吗? If you're not using it, set an onPreferenceChangedListener() for the color preference to set that static variable when it is changed. 如果您没有使用它,请为颜色首选项设置onPreferenceChangedListener()以在更改时设置该静态变量。

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

Invalidate, invalidateviews, notifyDatasetChanged, nothin worked for me! Invalidate,invalidateviews,notifyDatasetChanged,nothin对我有用! To just update the listview (with cursoradapter) I just do: 要更新列表视图(使用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 

But to have the correct backgrounds color, drawable, underline text, I just do: 但要拥有正确的背景颜色,可绘制,下划线文字,我只是这样做:

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

I dont like Barak solution cos it seems heavy weight, and executes code when not needed. 我不喜欢Barak解决方案因为它似乎很重,并且在不需要时执行代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM