zoukankan      html  css  js  c++  java
  • Loader监听数据源的变化

    步骤:

    1.新建一个继承SQLiteOpenHelper的帮助类

    2.在MainActivity中定义LoaderManager和SimpleCursorAdapter

    3.按顺序重写如下方法:initLoader来启动

    onCreateLoader->onStartLoading(forceLoad启动时强制加载)->loadInBackground->onLoadFinished(adapter.swapCursor(data))->onLoaderReset(adapter.swapCursor(null))

    *manager.restartLoader()数据改变时立刻加载

    public class DBHelper extends SQLiteOpenHelper {
        public static final String USERTABLE = "usertable";
        private static final String DBNAME = "QF.DB";
        private static final int CURRENTVERSION = 1;
    
        public DBHelper(Context context) {
            super(context, DBNAME, null, CURRENTVERSION);
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL("CREATE TABLE IF NOT EXISTS " + USERTABLE + "(_id INTEGER PRIMARY KEY AUTOINCREMENT" +
                    ",USERNAME,NICKNAME);");
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    
        }
    }
    /**
     * Loader:自动监听数据源是否发生变化
     */
    public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {
    
        private static SQLiteDatabase db;
        private DBHelper dbHelper;
        private SimpleCursorAdapter adapter;
        private LoaderManager manager;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            dbHelper = new DBHelper(this);
            db = dbHelper.getReadableDatabase();
            ListView listView = (ListView) findViewById(R.id.lv);
            // 1.获得一个Loader管理器
            manager = getSupportLoaderManager();
            //2.初始化Loader
            //1.Loader的唯一标识符
            //2.初始化Loader时传递的参数
            //3.Loader的回调
            manager.initLoader(1, null, this);
            //最后一个参数表示当数据源发生改变时,Cursor能够立马感知到数据源发生变化
            adapter = new SimpleCursorAdapter(this,
                    R.layout.listview_item, null, new String[]{"USERNAME"}, new int[]{R.id.username},
                    CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
            listView.setAdapter(adapter);
        }
    
        //当Loader创建时回调
        //1.Loader的id
        //2.初始化Loader的参数
        @Override
        public Loader<Cursor> onCreateLoader(int id, Bundle args) {
            Log.d("lenve", "onCreateLoader: " + Thread.currentThread());
            return new MyLoader(this);
        }
    
        //当异步加载完成时调用该方法
        @Override
        public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
            Log.d("lenve", "onLoadFinished: " + Thread.currentThread());
            //交换Cursor
            adapter.swapCursor(data);
        }
    
        //当由于Loader重置导致Cursor失效时,调用该方法
        @Override
        public void onLoaderReset(Loader<Cursor> loader) {
            Log.d("lenve", "onLoaderReset: " + Thread.currentThread());
            adapter.swapCursor(null);
        }
    
        public void addData(View view) {
            ContentValues values = new ContentValues();
            values.put("USERNAME", "李四i");
            db.insert(DBHelper.USERTABLE, null, values);
            //重启Loader
            manager.restartLoader(1, null, this);
        }
    
        static class MyLoader extends AsyncTaskLoader<Cursor> {
    
            public MyLoader(Context context) {
                super(context);
            }
    
            //在后台线程执行
            @Override
            public Cursor loadInBackground() {
                Log.d("lenve", "loadInBackground: " + Thread.currentThread());
                Cursor cursor = db.rawQuery("SELECT * FROM " + DBHelper.USERTABLE, null);
                //在这里放回一个Cursor,该Cursor最终被onLoadFinished()方法接收到
                return cursor;
            }
    
            //开始加载时调用
            @Override
            protected void onStartLoading() {
                super.onStartLoading();
                Log.d("lenve", "onStartLoading: " + Thread.currentThread());
                //第一次需要强制加载
                forceLoad();
            }
        }
    }

     其中,适配器可以定义一个继承CursorAdapter的类,和baseAdapter的道理类似;且cursorAdapter的两个方法newView和bindView相当于BaseAdapter的getView方法的拆分

    /**
     * newView和bindView相当于BaseAdapter中的getView()方法
     */
    public class MyAdapter extends CursorAdapter {
        private LayoutInflater inflater;
    
        public MyAdapter(Context context, Cursor c, int flags) {
            super(context, c, flags);
            inflater = LayoutInflater.from(context);
        }
    
        //初始化View
        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            View view = inflater.inflate(R.layout.listview_item, null);
            ViewHolder holder = new ViewHolder();
            holder.username = (TextView) view.findViewById(R.id.username);
            view.setTag(holder);
            return view;
        }
    
        //给View上的控件绑定事件
        //cursor.getColumnIndex("USERNAME")获取USERNAME字段的下标
        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            ViewHolder holder = (ViewHolder) view.getTag();
            holder.username.setText(cursor.getString(cursor.getColumnIndex("USERNAME")));
        }
    
        class ViewHolder {
            TextView username;
        }
    }
  • 相关阅读:
    20172327 2018-2019-1 《程序设计与数据结构》实验三:查找与排序
    团队作业第二周
    需求规格说明书
    广度优先遍历
    团队作业第一周
    20172327 2018-2019-1 《程序设计与数据结构》第九周学习总结
    20172327 2018-2019-1 《程序设计与数据结构》实验二:树实验报告
    20172327 2018-2019-1 《程序设计与数据结构》第八周学习总结
    20172327 2018-2019-1 《程序设计与数据结构》第七周学习总结
    20172327 2018-2019-1 《程序设计与数据结构》第六周学习总结
  • 原文地址:https://www.cnblogs.com/anni-qianqian/p/5445258.html
Copyright © 2011-2022 走看看