Loader,SearchView概述

1.Loader:

类的继承:Object–>
Loader–>
AsyncTaskLoader—>
CursorLoader
特征:
A:它可以应用在每一个activity或者fragment中
B:主要应用于异步加载数据
C: 监视数据源,一旦数据源发生了变化会自动将最新的结果投递给适配器对象
D: 当配置发生变化后会自动重建最新数据,并且不需要用户手动重新执行查询操作.

注意:备注:Loader可以在不阻塞主线程地情况下获取并发送结果数据给接受者(异步,可在主线程直接运行)

分类:
A:CursorLoader:操作的数据源都是通过内容提供者返回的数据
B:AsyncTaskLoader:数据源可以自己定义

CursorLoader和AsyncTaskLoader的区别:
相同点:
1.它们共同的父类都是Loader
2.它们都是做异步加载数据的.
3.它们都能够监视数据源的变化并做出相应的处理
不同的:
1:CursorLoader操作的数据源都是通过内容提供者(ContentProvider)返回的数据,AsyncTaskLoader的数据源可以自己定义.
2.CursorLoader是一个普通类可以直接实例化,而AsyncTaskLoader是一个抽象类,必须继承这个抽象类实现其中的抽象方法,
只能实例化这个类的子类对象.

2.Loader的使用过程:

(通过LoaderManager管理)—>CursorLoader与AsynctaskLoader的共同使用步骤
//声明LoaderManager对象,用来管理一个或者多个Loader对象
private LoaderManager loaderManager;

A:通过调用Activity或者Fragment的getLoaderManager()得到LoaderManager对象
this.loaderManager=this.getLoaderManager();

B:调用loaderManager对象的initLoader(id,bundle,loadercallback);初始化Loader对象,指定idLoader的对象,不存在则创建,如果存在则重用
这时会提示当前类实现LoaderCallback的接口: implements LoaderCallbacks.
/**
* 参数1:初始化Loader对象的唯一标识ID,如果之前不存在则创建,如果存在则重用
* 参数2:初始化Loader时如果需要传递参数,可以以Bundle对象的形式传递传递参数,不需要传递参数可以给null
* 参数3:一个实现了LoaderCallback接口类型的对象
*/
this.loaderManager.initLoader(1,bundle,this);

C:一旦调用initLoader(1,bundle,this)会自动调用LoaderManager.LoaderCallbacks接口中的
onCreateLoader(int id, Bundle args)方法和onLoadFinished(Loader loader, Cursor data)方法。
1):onCreateLoader(int id, Bundle args)方法
说明:
在这个方法中创建Loader对象并开启子线程做耗时操作,系统执行
参数:
* id:创建loader对象的参数,是this.loadManager.initLoader(id, args, callback)中的id
* args:this.loadManager.initLoader(id, args, callback)中的args
* return:根据传过来的参数创建的新的lodar对象
注意:当创建loader对象时自动调用的方法,如果当前返回值为null,即表示没有成功创建loader对象,此时他会继续创建loader对象
如果还是失败,就停止运行,因此当为nul时 连续调用了两次onCreateLoader()方法.

2):onLoadFinished(Loader loader, Cursor data)
说明:
耗时操作完成后将调用此方法,将onCreateLoader()方法加载数据后的return值传给onLoadFinished(Loader loader, Cursor data)方法中的形参data,
在这个方法中进行置换游标操作,将最新数据赋值给适配器对象(将之前的数据源删除,将新的数据源重新赋值给适配器对象)
adapter.swapCursor(data);
参数:
* loader:就是onCreateLoader(int id, Bundle args)的返回值对象
* data:创建loader对象后完成数据加载后传递给的当前参数

D:一旦Loader中的数据不需要时可用对数据进行置换操作,一般在onLoaderReset(Loader loader)中进行置换操作,
这个方法一般在退出应用程序时自动调用.
参数:
* loader:即将被重置的loader对象
说明:当程序退出应用时,我们一般讲数据置为null
adapter.swapCursor(null);
(所谓Loader的重置,就是指Loader对象还保留,只是清除Loader中的数据,所以onLoaderReset()方法相当于Loader的销毁方法。
因此在onLoaderReset()方法中会找到即将释放的数据的引用,并移除这些引用。移除引用后,GC才可以清除这些数据。)

E:一旦有最新数据了可以通过重启Loader对象自动调用onCreateLoader()对象重用Loader并加载最新数据,之后自动调用onLoaderFinished()
方法置换最新数据到适配器对象中.

方法:调用restartLoader()方法重启Loader,会自动调用onCreateLoader方法
/**
* 参数1:id:为上面的id,如果存在就重启,不存在就创建
* 参数2:Bundle对象,通过Bundle传值
* 参数3:上下文对象
*/
loaderManager.restartLoader(1, bundle, MainActivity.this);

3.CursorLoader:加载器的基类

数据源为ContentProvider返回的数据,new的时候直接将uri域名传入,进行访问ContentProvider提供的数据
返回值类型Loader ,return到onLoadFinished(Loader loader, Cursor data),将值传给data
适配器进行游标置换将数据传入适配器,adapter.swapCursor(data);

(1)CursorLoader c = new CursorLoader(context, uri, projection, selection, selectionArgs, sortOrder)
/**
* 参数1:context :上下文对象
* 参数2:uri:指定要访问内容提供者的域名
* 参数3:projection:指定要查询的内容提供者返回的数据中返回的列名字符串数组
* 参数4:selection:where条件表达式
* 参数5:selectionArgs:where条件表达式中占位符的值对应的字符串数组
* 参数6:sortOrder:排序表达式,如果升序asc,降序desc
*/

(2)当Loader与ListView,SimpleCursorAdapter,Menu一起使用的时候:
小结:
在初始化loaderManager.initLoader(id, args, callback)的时候先将传递的参数置args为null
当调用onCreateLoader(int id, Bundle args)的时候,判断传递过来的args是否为null
为null进行实例化游标操作,说明是第一次创建的时候,自动调用
不为null的时候,是重启的时候执行的,通过.restartLoader()方法调用,之后进行操作
当调用onLoadFinished(Loader loader, Cursor data)的时候,data是onCreateLoader数据加载完成后返回的值
适配器进行游标置换,将数据data置换进入。
adapter.swapCursor(data);
当调用onLoaderReset(Loader loader) 方法时,退出应用,将游标置换为null
adapter.swapCursor(null);
当点击搜索,调用.restartLoader()方法,重启loader方法,
loaderManager.restartLoader(1, bundle, MainActivity.this);

回顾: SimpleCursorAdapter
原型:new SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to , int flags) ;
参数1:上下文对象
参数2:显示 list item 的 布局文件。这个 layout 文件中至少要包含在 “to” 参数中命名的 views
参数3:数据库的光标( Cursor )。如果 cursor 无效,则该参数可以为 null
参数4:指定 column 中的哪些列的数据将绑定(显示)到 UI 中。如果 cursor 无效, 则该参数可为 null
参数5: 指定用于显示 “from” 参数指定的数据列表的 views。 这些 views 必须都是 TextViews。 “from” 参数的前 N 个值(valus)和 “to” 参数的前 N 个 views 是一一对应的关系。
如果 cursor 无效,则该参数可为 null。
参数6:用于定义适配器行为的标志位
FLAG_AUTO_REQUERY(常量值:1 )从 API11 开始已经废弃。因为他会在应用程序的 UI 线程中执行游标查询操作,
导致响应缓慢甚至应用程序无响应(ANR)的错误
如果设置FLAG_REGISTER_CONTENT_OBSERVER(常量值:2),适配器会在Cursor上注册一个内容观测器,
当通知到达时会调用 onContentChanged() 方法

4.SearchView的使用过程:

A: 在res/menu/menu_main.xml文件中添加菜单项并做如下配置:
android6.0版本的使用与不是android6.0版本的使用有所不同

(1)android6.0版本:

<item android:id="@+id/action_search"
                    android:orderInCategory="200"
                    android:title="搜索"
                    app:actionViewClass="android.support.v7.widget.SearchView"
                    app:showAsAction="always"
                />

注意: app:actionViewClass=”android.support.v7.widget.SearchView”,命名空间前缀必须是app,因为使用的是V7包中的类.
app:showAsAction=”always”:取值一定要给always表示这个菜单项永远出现在actionBar的空间区域.它的命名空间也必须是app

(2).6.0以下的版本:

 <item 
                    android:id="@+id/seach"
                    android:orderInCategory="200"
                    android:title="搜索"
                    android:actionViewClass="android.widget.SearchView"
                    android:showAsAction="always"
                />

注意:使用的是 android.widget.SearchView 包下的SearchView。所以使用的命名空间de前缀为android

B: 在Activity的onCreateOptionsMenu(Menu menu)方法中根据菜单填充器找到菜单项,
getMenuInflater().inflate(R.menu.main, menu);
根据findItem()方法通过id得到菜单项的item,返回MenuItem(菜单项)对象
MenuItem menuSearch = menu.findItem(R.id.seach);

通过菜单项对象调用getActionView()方法得到之前配置的SearchView对象,
SearchView searchView = (SearchView) menuSearch.getActionView();

给这个对象注册监听器对象.setOnQueryTextListener(new OnQueryTextListener(){}),实现两个重写的方法:
/**
* 当用户按确认键时自动调用的方法
* query:用户输入的内容
* return:如果返回true,当前事件对象被消费掉,false表示没有消费调用
*/
onQueryTextSubmit(String query):在用户按回车键或者手机上的确认键时自动调用的方法
/**
* 当输入文本内容变化时自动调用的方法
* newText:用户输入的内容
* return:如果返回true,当前事件对象被消费掉,false表示没有消费调用
*/
onQueryTextChange(String newText):当用户在指定文本框中输入内容后内容发生了变化时自动调用的方法.
//调用.restartLoader(id, args, callback)方法重启Loader,会自动调用onCreateLoader(int id, Bundle args)方法,
并将args参数传入,通过args.getXXX()可以获得Bundle传过去的值。
Bundle bundle = new Bundle();
bundle.putString(“keyword”, newText);
loaderManager.restartLoader(1, bundle, MainActivity.this);

5.AsyncTaskLoader的使用过程:

1.编写一个静态的内部类并继承AsyncTaskLoader类提供有参构造函数,重写loadInBackground()方法
2.根据需要重写AsyncTaskLoader的onStartLoading(),如果需要做耗时操作的话,则必须在这个方法中执行
forceLoad();明确调用loadInBackground()方法,这个方法执行完毕后的返回结果传递给onLoadFinished(Loader loader, Cursor data)
方法的形参data.在这个方法中置换游标即可得到最新查询出来的数据.

注意:

1.如果看到如下异常:
java.lang.IllegalArgumentException:
Object returned from onCreateLoader must not be a non-static inner member class:
MyAsyncTaskLoader{b5fd5ec8 id=0}
说明我们要编写的内部类必须是静态内部类,如果不是静态内部类就会报上面的异常.

cursorLoader:一般为内容提供者内容
Asynctask : 自定义内容

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值