迁移到CursorLoader&带有SQLiteDatabase的AutoCompleteTextView的LoaderManager [英] Migrating to CursorLoader & LoaderManager for AutoCompleteTextView with SQLiteDatabase

查看:114
本文介绍了迁移到CursorLoader&带有SQLiteDatabase的AutoCompleteTextView的LoaderManager的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 AutoCompleteTextView ,它显示了从 SQLiteDatabase 查询中获取的建议的下拉列表。目前它使用 SimpleCursorAdapter ,但是它有几个问题(我对此有单独的疑问: SimpleCursorAdapter问题- java.lang.IllegalStateException:尝试重新查询已经关闭的游标。)。

I have an AutoCompleteTextView, which shows dropdown list of suggestions taken from a SQLiteDatabase query. At the moment it uses SimpleCursorAdapter, however there are several problems with it (I have a separate question about the issue here: SimpleCursorAdapter issue - "java.lang.IllegalStateException: trying to requery an already closed cursor").

不过,我还是建议我朝 CursorLoader LoaderManager code>,并且我已经尝试过了,但是无法正常运行。如果有人能指导/推荐/展示将我的代码正确移植到CursorLoader / LoaderManager概念的正确方法,我将不胜感激。任何帮助都非常感谢!

Nevertheless, I was advised to look in the direction of CursorLoader and LoaderManager, and I've tried it, yet couldn't make it work. I'd be grateful if someone would guide/recommend/show the right way of migrating my code below to CursorLoader/LoaderManager concept. Any kind of help very appreciated!

mAdapter = new SimpleCursorAdapter(this,
                R.layout.dropdown_text,
                null,
                new String[]{CITY_COUNTRY_NAME},
                new int[]{R.id.text}, 0);
        mAutoCompleteTextView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> listView, View view, int position, long id) {
                Cursor cursor = (Cursor) listView.getItemAtPosition(position);
                cityCountryName = cursor.getString(cursor.getColumnIndexOrThrow(CITY_COUNTRY_NAME));
                mAutoCompleteTextView.setText(cityCountryName);
                JSONWeatherTask task = new JSONWeatherTask();
                task.execute(new String[]{cityCountryName});
            }
        });
        mAdapter.setFilterQueryProvider(new FilterQueryProvider() {
            public Cursor runQuery(CharSequence sequence) {
                String constraint = sequence.toString();
                String queryString = "SELECT " + ID + ", " + CITY_ID + ", " + CITY_COUNTRY_NAME + " FROM " + TABLE_1;
                constraint = constraint.trim() + "%";
                queryString += " WHERE " + CITY_COUNTRY_NAME + " LIKE ?";
                String params[] = {constraint};
                try {
                    Cursor cursor = database.rawQuery(queryString, params);
                    if (cursor != null) {
                        startManagingCursor(cursor);
                        cursor.moveToFirst();
                        return cursor;
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                return null;
            }
        });
        mAutoCompleteTextView.setAdapter(mAdapter);

这里是供参考的整个项目(您可以在此处提出拉取请求) :开放天气应用

Here is the whole project for the reference (you can make a pull request there, if you wish): Open Weather App

推荐答案

很遗憾,此处没有人提出解决方案,但是一位同事(他没有SO帐户)提出了带有迁移修复程序的请求请求。

Unfortunately, here on SO nobody came up with a solution, yet a colleague (he doesn't have an SO account) made a pull request with the migration fixes. It works perfectly, and I decided to post the correct answer here as well.

如果您对这些改进在实际代码中的外观感兴趣,欢迎您。访问GitHub上原始的开源项目页面: Open Weather App

If you're interested in how these improvements look inside the actual code, you're welcome to visit the original open source project page on GitHub: Open Weather App

这是新的适配器:

mAdapter = new SimpleCursorAdapter(this,
                R.layout.dropdown_text,
                null,
                new String[]{CITY_COUNTRY_NAME},
                new int[]{R.id.text},0);
        mAdapter.setFilterQueryProvider(new FilterQueryProvider() {
            @Override
            public Cursor runQuery(CharSequence constraint) {
                if (constraint != null) {
                    if (constraint.length() >= 3 && !TextUtils.isEmpty(constraint)) {
                        Bundle bundle = new Bundle();
                        String query = charArrayUpperCaser(constraint);
                        bundle.putString(CITY_ARGS, query);
                        getLoaderManager().restartLoader(0, bundle, MainActivity.this).forceLoad();
                    }
                }
                return null;
            }
        });

这是 onCreateLoader()回调:

@Override
public android.content.Loader<Cursor> onCreateLoader(int id, Bundle args) {
    String s = args.getString(CITY_ARGS);
    WeatherCursorLoader loader = null;
    if (s != null && !TextUtils.isEmpty(s)) {
        loader = new WeatherCursorLoader(this, database, s);
    }
    return loader;
}

自定义 CursorLoader 本身:

private static class WeatherCursorLoader extends CursorLoader {

    private SQLiteDatabase mSQLiteDatabase;
    private String mQuery;

    WeatherCursorLoader(Context context, SQLiteDatabase cDatabase, String s) {
        super(context);
        mSQLiteDatabase = cDatabase;
        mQuery = s + "%";
        Log.d(TAG, "WeatherCursorLoader: " + mQuery);
    }


    @Override
    public Cursor loadInBackground() {
        return mSQLiteDatabase.query(TABLE_1, mProjection,
                CITY_COUNTRY_NAME + " like ?", new String[] {mQuery},
                null, null, null, "50");
    }
} 

这篇关于迁移到CursorLoader&amp;带有SQLiteDatabase的AutoCompleteTextView的LoaderManager的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆