如何将listview custom cursoradapter转换为Android 3.0及更高版本?

时间:2012-06-09 00:56:43

标签: android android-cursorloader android-cursoradapter

相当noobish和我在这里的第一篇文章。我有一个在2.3.3中使用自定义baseadapter填充列表视图的应用程序正常工作。问题是我正在使用在Android 3/4中弃用的startManagingCursor和requery。

我正在使用sqlite和一个数据库适配器来保存我的所有查询和一个私有方法来传递活动中的参数。您可以通过长按项目或单击某个项目以在新活动中打开它以及成功返回列表更新来更新列表。

我知道我们不应该在主UI上运行这些类型的操作,但是我在找出游标加载器时遇到了麻烦,我甚至需要它吗?我应该使用像asynctask这样的东西在不同的线程上运行。我只是不明白这一切是如何融合在一起的,任何正确方向的帮助都会受到赞赏。感谢。

以下是我认为最相关的代码来自MyActivity的小样本

public class MyActivity extends ListActivity {

private MyDBAdapter dbAdapter;
private MyCursorAdapter mCursorAdapter;

@Override
    public void onCreate(Bundle savedInstanceState) {          

        super.onCreate(savedInstanceState); 
        setContentView(R.layout.mylayout);

    this.dbAdapter = new MyDBAdapter(this);
        this.dbAdapter.open();

    queryParams = getQueryParams();
    queryDB(queryParams);
}

private void queryDB(String qParams) {
    Cursor c = this.dbAdapter.fetchQuery(qParams);
    startManagingCursor(c);
        this.mCursorAdapter = new MyCursorAdapter(this, c);
        setListAdapter(this.mCursorAdapter);
        this.mCursorAdapter.changeCursor(c);
    }

public void updateStatus(long paramLong, int paramInt) {
    Cursor c = this.dbAdapter.updateDBStatus(paramLong, paramInt);
    startManagingCursor(c);
    this.mCursorAdapter.changeCursor(c);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    if (this.dbAdapter != null) {
    this.dbAdapter.close();
    }
}
}

和CursorAdapter

public class MyCursorAdapter extends CursorAdapter {

public MyCursorAdapter(Context cxt, Cursor cur, int flags) {
        super(cxt, cur);
        mContext = cxt;
        mLayoutInflater = LayoutInflater.from(cxt); 
    }

    @Override
    public View newView(Context cxt, Cursor cur, ViewGroup parent) {
        View vw = mLayoutInflater.inflate(LAYOUT_ID, parent, false);
        return vw;
    }

    @Override
    public void bindView(View vw, Context cxt, Cursor cur) {

        int id = cur.getInt(cur.getColumnIndexOrThrow("_id"));
        String name = cur.getString(cur.getColumnIndexOrThrow("name"));
    int completed = cur.getInt(cur.getColumnIndexOrThrow("completed"));

    TextView tv = (TextView) vw.findViewById(R.id.name);

    if(completed == 1) {
        tv.setTextColor(0x7fffffff);
        } else {
        tv.setTextColor(0xffffffff);
        }
    }
}

================编辑==================

我最终删除了startManagingCursor()和requery(),并从兼容包中添加了import android.support.v4.widget.CursorAdapter。由于我有来自不同位置的多个调用,我创建了一个私有的Cursor mCursor并使用this.mCursorAdapter.changeCursor(mCursor)来更新它。

现在除了:

之外,它几乎可行
  1. 你真的不应该这样做,因为它仍然在主UI上运行
  2. 关闭光标取决于应用的设置方式
  3. 在我的情况下,我无法关闭光标,否则我的listview将为空。无法保证在onDestroy()中关闭它,并且在onBackPressed()中关闭它不起作用,因为您可以单击使用新游标打开新活动的列表项。当有人点击列表项然后单击后退按钮时,列表应该在同一位置,因此关闭onStop()(并在onStart()中打开)也不是答案。我也尝试过所有活动的公共静态游标,但也存在问题。我没有尝试的另一件事是立即将光标信息加载到内存中,然后立即关闭它,但这似乎不太理想。

    我非常喜欢CursorLoader的想法,只是它只接受一个URI,你需要一个内容提供者,它不接受rawQuery()。我的数据库中有数以千计的项目,并且使用我的数据库适配器进行了一百种不同类型的查询调用,所有这一切都变得非常痛苦。我认为CursorLoader是最好的方法,但我对android实现它的方式感到失望。

    我还看到有人编写的CursorLoader usage without ContentProvider使用了AsyncTaskLoader,因此您不需要ContentProvider。这可能是我现在最好的选择,但是其他人指出没有机制可以刷新数据更改。我将不得不调查并看到。

0 个答案:

没有答案