导航抽屉SimpleCursorAdapter刷新

时间:2013-11-30 14:03:45

标签: android simplecursoradapter navigation-drawer

我正在开发一个带有导航抽屉的应用程序,该抽屉显示从SQLite表中获取的选项列表,我正在使用SimpleCursorAdapter,如下所示:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
  mDrawerListView = (ListView) inflater.inflate(R.layout.fragment_navigation_drawer, container, false);

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

  mCursorAdapter = getList();
  mDrawerListView.setAdapter(mCursorAdapter);
  mDrawerListView.setItemChecked(mCurrentSelectedPosition, true);
  return mDrawerListView;
}

getList()返回SimpleCursorAdapter,如下所示:

private SimpleCursorAdapter getList()
{
  Uri uri = Uri.parse("content://" + MyContentProvider.AUTHORITY + "/searches");
  Cursor cursor = getActivity().getContentResolver().query(uri,
  new String[]
  {
    SearchTable.COLUMN_ID,
    SearchTable.COLUMN_SEARCH_ID,
    SearchTable.COLUMN_FULL,
    SearchTable.COLUMN_TYPE,
    SearchTable.COLUMN_TEXT
  },
  null, null, null);

  if (cursor == null)
  {
    Log.i(TAG, "FRC! Cursor is null in NavigationDrawerFragment!");
    Toast.makeText(getActivity(), getString(R.string.database_error), Toast.LENGTH_SHORT).show();
  }
      // Defines a list of columns to retrieve from the Cursor and load into an output row
  String[] mWordListColumns =
  {
    SearchTable.COLUMN_TEXT,
    SearchTable.COLUMN_TYPE
  };

  // Defines a list of View IDs that will receive the Cursor columns for each row
  int[] mWordListItems = { R.id.search_full, R.id.search_type};

  // layout for each of the articles in the sidebar
  int layout = R.layout.search_title;

  // Creates a new SimpleCursorAdapter to bind to the navigation drawer
  mCursorAdapter = new SimpleCursorAdapter(
      getActivity(),
      layout,
      cursor,
      mWordListColumns,
      mWordListItems,
      0);
return mCursorAdapter;

}

不幸的是,当用户刷新搜索列表时,导航抽屉中显示的内容没有任何变化,除非应用程序已关闭,从任务切换器上滑开并重新启动。我的内容提供商正在通知应用程序表中的更改,我正在关注它们,如下所示:

class MyObserver extends ContentObserver
{
  public MyObserver(Handler handler)
  {
    super(handler);
  }

  @Override
  public void onChange(boolean selfChange)
  {
    this.onChange(selfChange, null);
  }

  @Override
  public void onChange(boolean selfChange, Uri uri)
  {
    mCursorAdapter.notifyDataSetChanged();
    mDrawerListView.invalidate();
    Log.i(TAG,"Cursor dataset changed!");
  }
}

我看到更改数据集的日志消息,因此实际上正在调用代码。片段的onCreate方法包含:

  Uri searchUri = Uri.parse("content://" + MyContentProvider.AUTHORITY + "/searches");
  observer = new MyObserver(new Handler());
  getActivity().getContentResolver().registerContentObserver(searchUri, true, observer);

我在这里缺少什么?或者,我是否误解了notifyDataSetChanged()应该如何运作?作为一种解决方法,我正在考虑销毁和重新创建片段,但由于onChange()被多次调用多次插入/删除,因此这可能是一个浪费的黑客。

感谢您的任何建议。

1 个答案:

答案 0 :(得分:0)

最终我设法找到了一种方法来做到这一点,我认为这种做法并不是很好,但目前它似乎运作良好。每次其他尝试使视图无效或通知已更改的数据集都没有效果。

@Override
public void onPrepareOptionsMenu(Menu menu) // called when drawer opens
{
  if (mDrawerLayout != null && isDrawerOpen())
  {
    mCursorAdapter = getList(); // create a new cursor with the latest data (see above)
    mCursorAdapter.notifyDataSetChanged();  // do I even need this?
    ListView listView = (ListView) getActivity().findViewById(R.id.navigation_drawer);  // bind the new cursor to the listview
    listView.setAdapter(mCursorAdapter);
    listView.invalidateViews();
    ...
  }
}

如果你能想到更好的方法,请告诉我!