Listview没有更新(notifydatasetchanged)

时间:2013-04-23 19:37:06

标签: android android-listview

我在更改'数据集'后尝试更新我的列表视图,但它没有,除非我手动刷新视图或刷新活动。 这不起作用:

                runOnUiThread(new Runnable() {
                    public void run() {
                        entriesListAdapter.notifyDataSetChanged();
                    }  
                });

虽然这样做:

            handler.postDelayed(new Runnable() {
              @Override
              public void run() {
                  onCreate(null);
                    entriesListAdapter.notifyDataSetChanged();
              }
              }, 1000);

但这绝对不是正确的做法。我使用notifydatasetchanged错了吗?

我的整个活动:     包app.wordpress;

 import app.wordpress.service.FetcherService;
 import someontherimports

 public class EntriesListActivity extends ListActivity {
private static final int CONTEXTMENU_REFRESH_ID = 4;

private static final int CONTEXTMENU_MARKASREAD_ID = 6;

private static final int ACTIVITY_APPLICATIONPREFERENCES_ID = 1;

private static final Uri CANGELOG_URI = Uri.parse("http://wordpress.com");

private static final int CONTEXTMENU_MARKASUNREAD_ID = 7;

private static final int CONTEXTMENU_DELETE_ID = 8;

private static final int CONTEXTMENU_COPYURL = 9;

private static final int DIALOG_ABOUT = 7;

public static final String EXTRA_SHOWREAD = "show_read";

public static final String EXTRA_SHOWFEEDINFO = "show_feedinfo";

public static final String EXTRA_AUTORELOAD = "autoreload";

private static final String[] FEED_PROJECTION = {FeedData.FeedColumns.NAME,
    FeedData.FeedColumns.URL,
    FeedData.FeedColumns.ICON
};

private Uri uri;

private EntriesListAdapter entriesListAdapter;

private byte[] iconBytes;

@Override
protected void onCreate(Bundle savedInstanceState) {
    if (MainTabActivity.isLightTheme(this)) {
        setTheme(R.style.Theme_Light);
    }

    super.onCreate(savedInstanceState);

    String title = null;

    iconBytes = null;

    Intent intent = getIntent();

    long feedId = intent.getLongExtra(FeedData.FeedColumns._ID, 0);

    if (feedId > 0) {
        Cursor cursor = getContentResolver().query(FeedData.FeedColumns.CONTENT_URI(feedId), FEED_PROJECTION, null, null, null);

        if (cursor.moveToFirst()) {
            title = cursor.isNull(0) ? cursor.getString(1) : cursor.getString(0);
            iconBytes = cursor.getBlob(2);
        }
        cursor.close();
    }

    if (!MainTabActivity.POSTGINGERBREAD && iconBytes != null && iconBytes.length > 0) { // we cannot insert the icon here because it would be overwritten, but we have to reserve the icon here
        if (!requestWindowFeature(Window.FEATURE_LEFT_ICON)) {
            iconBytes = null;
        }
    }

    setContentView(R.layout.entries);

    uri = intent.getData();

    entriesListAdapter = new EntriesListAdapter(this, uri, intent.getBooleanExtra(EXTRA_SHOWFEEDINFO, false), intent.getBooleanExtra(EXTRA_AUTORELOAD, false));
    setListAdapter(entriesListAdapter);

    if (title != null) {
        setTitle(title);
    }
    if (iconBytes != null && iconBytes.length > 0) {
        int bitmapSizeInDip = (int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24f, getResources().getDisplayMetrics());
        Bitmap bitmap = BitmapFactory.decodeByteArray(iconBytes, 0, iconBytes.length);
        if (bitmap != null) {
            if (bitmap.getHeight() != bitmapSizeInDip) {
                bitmap = Bitmap.createScaledBitmap(bitmap, bitmapSizeInDip, bitmapSizeInDip, false);
            }

            if (MainTabActivity.POSTGINGERBREAD) {
                CompatibilityHelper.setActionBarDrawable(this, new BitmapDrawable(bitmap));
            } else {
                setFeatureDrawable(Window.FEATURE_LEFT_ICON, new BitmapDrawable(bitmap));
            }
        }
    }
    if (RSSOverview.notificationManager != null) {
        RSSOverview.notificationManager.cancel(0);
    }

    getListView().setOnCreateContextMenuListener(new OnCreateContextMenuListener() {
        public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
            menu.setHeaderTitle(((TextView) ((AdapterView.AdapterContextMenuInfo) menuInfo).targetView.findViewById(android.R.id.text1)).getText());
            menu.add(0, CONTEXTMENU_REFRESH_ID, Menu.NONE, R.string.contextmenu_refresh);
            menu.add(0, CONTEXTMENU_MARKASREAD_ID, Menu.NONE, R.string.contextmenu_markasread).setIcon(android.R.drawable.ic_menu_manage);
            menu.add(0, CONTEXTMENU_MARKASUNREAD_ID, Menu.NONE, R.string.contextmenu_markasunread).setIcon(android.R.drawable.ic_menu_manage);
            menu.add(0, CONTEXTMENU_DELETE_ID, Menu.NONE, R.string.contextmenu_delete).setIcon(android.R.drawable.ic_menu_delete);
            menu.add(0, CONTEXTMENU_COPYURL, Menu.NONE, R.string.contextmenu_copyurl).setIcon(android.R.drawable.ic_menu_share);
        }
    });
}

@Override
protected void onListItemClick(ListView listView, View view, int position, long id) {
    TextView textView = (TextView) view.findViewById(android.R.id.text1);

    textView.setTypeface(Typeface.DEFAULT);
    textView.setEnabled(false);
    view.findViewById(android.R.id.text2).setEnabled(false);
    entriesListAdapter.neutralizeReadState();
    startActivity(new Intent(Intent.ACTION_VIEW, ContentUris.withAppendedId(uri, id)).putExtra(EXTRA_SHOWREAD, entriesListAdapter.isShowRead()).putExtra(FeedData.FeedColumns.ICON, iconBytes));
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.entrylist, menu);
    return true;
}

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    menu.setGroupVisible(R.id.menu_group_0, entriesListAdapter.getCount() > 0);
    return true;
}

public boolean onMenuItemSelected(int featureId, MenuItem item) {
    switch (item.getItemId()) {
        case R.id.menu_markasread: {
            new Thread() { // the update process takes some time
                public void run() {
                    getContentResolver().update(uri, RSSOverview.getReadContentValues(), null, null);
                }
            }.start();
            entriesListAdapter.markAsRead();
            break;
        }
        case R.id.menu_markasunread: {
            new Thread() { // the update process takes some time
                public void run() {
                    getContentResolver().update(uri, RSSOverview.getUnreadContentValues(), null, null);
                }
            }.start();
            entriesListAdapter.markAsUnread();
            break;
        }
        case R.id.menu_hideread: {
            if (item.isChecked()) {
                item.setChecked(false).setTitle(R.string.contextmenu_hideread).setIcon(android.R.drawable.ic_menu_close_clear_cancel);
                entriesListAdapter.showRead(true);
            } else {
                item.setChecked(true).setTitle(R.string.contextmenu_showread).setIcon(android.R.drawable.ic_menu_view);
                entriesListAdapter.showRead(false);
            }
            break;
        }
        case R.id.menu_deleteread: {
            new Thread() { // the delete process takes some time
                public void run() {
                    String selection = Strings.READDATE_GREATERZERO+Strings.DB_AND+" ("+Strings.DB_EXCUDEFAVORITE+")";

                    getContentResolver().delete(uri, selection, null);
                    FeedData.deletePicturesOfFeed(EntriesListActivity.this, uri, selection);
                    runOnUiThread(new Runnable() {
                        public void run() {
                            entriesListAdapter.getCursor().requery();
                        }
                    });
                }
            }.start();
            break;
        }
        case R.id.menu_deleteallentries: {
            Builder builder = new AlertDialog.Builder(this);

            builder.setIcon(android.R.drawable.ic_dialog_alert);
            builder.setTitle(R.string.contextmenu_deleteallentries);
            builder.setMessage(R.string.question_areyousure);
            builder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    new Thread() {
                        public void run() {
                            getContentResolver().delete(uri, Strings.DB_EXCUDEFAVORITE, null);
                            runOnUiThread(new Runnable() {
                                public void run() {
                                    entriesListAdapter.getCursor().requery();
                                }
                            });
                        }
                    }.start();
                }
            });
            builder.setNegativeButton(android.R.string.no, null);
            builder.show();
            break;
        }
        case CONTEXTMENU_MARKASREAD_ID: {
            long id = ((AdapterView.AdapterContextMenuInfo) item.getMenuInfo()).id;

            getContentResolver().update(ContentUris.withAppendedId(uri, id), RSSOverview.getReadContentValues(), null, null);
            entriesListAdapter.markAsRead(id);
            break;
        }
        case CONTEXTMENU_MARKASUNREAD_ID: {
            long id = ((AdapterView.AdapterContextMenuInfo) item.getMenuInfo()).id;

            getContentResolver().update(ContentUris.withAppendedId(uri, id), RSSOverview.getUnreadContentValues(), null, null);
            entriesListAdapter.markAsUnread(id);
            break;
        }
        case CONTEXTMENU_DELETE_ID: {
            long id = ((AdapterView.AdapterContextMenuInfo) item.getMenuInfo()).id;

            getContentResolver().delete(ContentUris.withAppendedId(uri, id), null, null);
            FeedData.deletePicturesOfEntry(Long.toString(id));
            entriesListAdapter.getCursor().requery(); // he have no other choice
            break;
        }
        case CONTEXTMENU_COPYURL: {
            ((ClipboardManager) getSystemService(CLIPBOARD_SERVICE)).setText(((AdapterView.AdapterContextMenuInfo) item.getMenuInfo()).targetView.getTag().toString());
            break;
        }
        case R.id.menu_settings: {
            startActivityForResult(new Intent(this, ApplicationPreferencesActivity.class), ACTIVITY_APPLICATIONPREFERENCES_ID);
            break;
        }
        case R.id.menu_about: {
            showDialog(DIALOG_ABOUT);
            break;
        }

        case R.id.menu_refresh: {
            new Thread() {
                  public void run() {
                    sendBroadcast(new Intent(Strings.ACTION_REFRESHFEEDS).putExtra(Strings.SETTINGS_OVERRIDEWIFIONLY, PreferenceManager.getDefaultSharedPreferences(EntriesListActivity.this).getBoolean(Strings.SETTINGS_OVERRIDEWIFIONLY, false)));
                  }
                }.start();
                runOnUiThread(new Runnable() {
                    public void run() {
                        entriesListAdapter.notifyDataSetChanged();
                    }  
                });

            break;
        }

    }
    return true;
}

@Override
protected void onResume()
{
    super.onResume();
    setProgressBarIndeterminateVisibility(isCurrentlyRefreshing());
    registerReceiver(refreshReceiver, new IntentFilter("app.wordpress.REFRESH"));
}

@Override
protected void onPause()
{
    unregisterReceiver(refreshReceiver);
    super.onPause();
}


private BroadcastReceiver refreshReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        setProgressBarIndeterminateVisibility(true);
    }
};


@Override
protected Dialog onCreateDialog(int id) {
    Dialog dialog;

    switch (id) {

        case DIALOG_ABOUT: {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);

            builder.setIcon(android.R.drawable.ic_dialog_info);     
            builder.setTitle(R.string.menu_about);
            MainTabActivity.INSTANCE.setupLicenseText(builder);         
            builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });
            builder.setNeutralButton(R.string.changelog, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    startActivity(new Intent(Intent.ACTION_VIEW, CANGELOG_URI));
                }
            });
            return builder.create();
        }
        default: dialog = null;
    }
    return dialog;
}
private boolean isCurrentlyRefreshing()
{
    ActivityManager manager = (ActivityManager)getSystemService(ACTIVITY_SERVICE);
    for (RunningServiceInfo service: manager.getRunningServices(Integer.MAX_VALUE)) {
        if (FetcherService.class.getName().equals(service.service.getClassName())) {
            return true;
        }
    }
    return false;
}

}

2 个答案:

答案 0 :(得分:1)

您是指在Activity中使用此代码块吗?

    case R.id.menu_refresh: {
        new Thread() {
              public void run() {
                sendBroadcast(new Intent(Strings.ACTION_REFRESHFEEDS).putExtra(Strings.SETTINGS_OVERRIDEWIFIONLY, PreferenceManager.getDefaultSharedPreferences(EntriesListActivity.this).getBoolean(Strings.SETTINGS_OVERRIDEWIFIONLY, false)));
              }
            }.start();
            runOnUiThread(new Runnable() {
                public void run() {
                    entriesListAdapter.notifyDataSetChanged();
                }  
            });

        break;

如果是这样,问题可能是runOnUiThread()的调用实际上并不在你创建的Thread内,而是在主线程上调用。

这个代码的结构方式,在选择刷新后,创建后台线程来激发广播Intent(不必要,BTW,因为这也是一个异步进程......它立即返回)然后notifyDataSetChanged()之后会立即运行(因为runOnUiThread()从主线程调用时会立即执行Runnable

所以你发送广播并在几乎同一时间更新适配器......没有多少时间可以在那段时间内实际改变。如果您希望sendBroadcast()阻止并在某个接收方处理完之后返回,则情况并非如此。

答案 1 :(得分:0)

在你的contentProvider中,你应该调用contentResolver.notifyChange来通知适配器contentResolver提供的数据发生了变化,这将为你更新listView。