Loader以及和EditText、SerchView一起使用

1、Loader,加载器
实现异步加载数据的功能,类似于AsyncTask

 监听数据源的改变,实时刷新控件(ListView)
将耗时的操作放在子线程中,防止ANR

适应场景:
适配器需要使用CursorAdapter
数据源来源于数据库(可以是自己app下的数据库,也可以是其他app的数据库,可以通过ContentProvider向外暴露数据)

Loader必须使用在Activity或Fragment中

2、使用步骤
a:使用Activity实现接口LoaderCallbacks,并重写3个方法

b:通过上下文获得LoaderManager,通过manager启动Loader
manager。initLoader(id,args,calllback)

 

EditText的监听事件:etName.addTextChangedListener(new TextWatcher(){});

SearchView的监听事件:sv.setOnQueryTextListener(new OnQueryTextListener(){});


案例一:
public class MainActivity extends Activity implements LoaderCallbacks<Cursor> {

 private ListView lv;
 private SimpleCursorAdapter adapter;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  lv = (ListView) findViewById(R.id.listView1);

  adapter = new SimpleCursorAdapter(this, R.layout.item, null,
    new String[] { "display_name", "data1" }, new int[] {
      R.id.textView1, R.id.textView2 },
    CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);

  lv.setAdapter(adapter);

  // 通过上下文获得Loader的管理器
  LoaderManager manager = getLoaderManager();

  // id:用来唯一标示Loader
  // args:传值使用的参数,在构建时或重启时
  // callback:要实现的回调方法
  manager.initLoader(1, null, this);
 }

 // 创建Loader
 // id:Loader唯一的标示
 // args:调用者可以给Loader传递消息,接收参数
 @Override
 public Loader<Cursor> onCreateLoader(int id, Bundle args) {
  // TODO Auto-generated method stub
  return new CursorLoader(getApplicationContext(),
    ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
    new String[] { "_id", "display_name", "data1" }, null, null,
    null);
               //return后面可以替换成自定义的AsyncLoader
 }

 // onLoadFinished在onCreateLoader方法执行结束之后调用
 // loader:onCreateLoader的返回值
 // data:是Loader对象自带的Cursor
 @Override
 public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
  // TODO Auto-generated method stub
  // 当Loader数据加载完成,将数据设置给Adapter,之后在ListView中显示
  adapter.swapCursor(data);

 }

 // 当创建的Loader重置(重启)时调用该方法
 // 通常将上面查询获得Cursor设置为不可用
 @Override
 public void onLoaderReset(Loader<Cursor> loader) {
  // TODO Auto-generated method stub
           adapter.swapCursor(null);// 清除旧数据
 }

}
案例二:
// 给EditText添加文本改变的监听
  etName.addTextChangedListener(new TextWatcher() {

   @Override
   public void onTextChanged(CharSequence s, int start, int before,
     int count) {
    // TODO Auto-generated method stub
    Log.i("TAG", "--onTextChanged" + s);
   }

   @Override
   public void beforeTextChanged(CharSequence s, int start, int count,
     int after) {
    // TODO Auto-generated method stub
    Log.i("TAG", "--beforeTextChanged" + s);
   }

   @Override
   public void afterTextChanged(Editable s) {
    // TODO Auto-generated method stub
    Log.i("TAG", "--afterTextChanged" + s);
    //
    Bundle bundle = new Bundle();
    bundle.putString("key", s.toString());
    // 重启Loader并传递参数(查询条件)
    getLoaderManager().restartLoader(1, bundle, MainActivity.this);
   }
  });

案例三:自定义AsyncLoader
// AsyncTaskLoader 有一个内部类实现了AsyncTask
 // 查询并加载数据
 static class MyLoader extends AsyncTaskLoader<Cursor> {

  public MyLoader(Context context) {
   super(context);
   // TODO Auto-generated constructor stub
  }

  @Override
  protected void onStartLoading() {//这一步是自己手动写的且必须写,不然没有数据
   // TODO Auto-generated method stub
   super.onStartLoading();
   // 强制加载数据
   forceLoad();
  }

  // 在工作线程执行,查询数据,返回Cursor
  @Override
  public Cursor loadInBackground() {
   // TODO Auto-generated method stub
   Cursor cursor = resolver.query(
     ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
     new String[] { "_id", "display_name", "data1" }, null,
     null, null);
   return cursor;
  }
 }

案例四:
              // SearchView添加事件
  mSearchView.setOnQueryTextListener(new OnQueryTextListener() {

   // 键盘输入,回车开始执行,调用该方法
   @Override
   public boolean onQueryTextSubmit(String query) {
    // TODO Auto-generated method stub
    Bundle bundle = new Bundle();
    bundle.putString("key", query);

    getLoaderManager().restartLoader(1, bundle,MainActivity.this);
    return false;
   }

   // 内容改变时调用该方法
   @Override
   public boolean onQueryTextChange(String newText) {
    // TODO Auto-generated method stub
    return false;
   }
  });
          在自定义的AsyncLoader中如何处理传进来的参数
      public class MyCursorLoader extends AsyncTaskLoader<Cursor> {

 private Bundle args;

 public MyCursorLoader(Context context, Bundle args) {
  super(context);
  // TODO Auto-generated constructor stub
  this.args = args;
 }

 @Override
 protected void onStartLoading() {
  // TODO Auto-generated method stub
  super.onStartLoading();
  forceLoad();
 }

 @Override
 public Cursor loadInBackground() {
  // TODO Auto-generated method stub
  ContentResolver resolver = getContext().getContentResolver();
  if (args == null) {
   return resolver.query(
     ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
     new String[] { "_id", "display_name", "data1" }, null,
     null, null);
  } else {
   String where = "display_name like ?";
   String[] whereArgs = { "%" + args.getString("key") + "%" };
   return resolver.query(
     ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
     new String[] { "_id", "display_name", "data1" }, where,
     whereArgs, null);
  }
 }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值