Loaders 的使用,结合Fragments

Loader的特点和使用场所

 

  1.  Loader 可以在Activity 和Fragments 的界面下运行(本篇将结合上篇文章的Fragments的DEMO进行讲述如何在Fragments 下使用Loaders)。
  2. 它可以提供类似于AysncTask一样的异步请求数据加载的功能,实际上它就是来源于AysncTask 的扩展并增加了很多人性化的功能,例如加载进度框、更好的控制API等。
  3. 它拥有一个类似于Windows Phone 开发的MVVM一样的数据改变通知机制,当数据源做出改变时会及时通知。
  4. 当Cursor 发生变化时,会自动加载数据,因此并不需要再重新进行数据查询。

Loader API 使用参考

 

  1. LoaderManager
    每一个Activity 和 Fragments 只能存在一个LoaderManager,负责管理界面中的Loader。
  2. LoaderManager.LoaderCallbacks
    位于LoaderManager的子接口,提供众多的回调接口操作Loader ,如初始化、创建、重新启动、销毁、结束等一系列实用接口。
  3. Loader
    与Fragments相似,是一个基础类,可以由用户自行扩展适合自己的类
  4. AsyncTaskLoader
    提供了一个基于AsyncTask 工作机制的Loader,查看源码可以看到其继承于Loader,并且子类LoadTask 继承于AsyncTask<Void, Void, D>,并且实现了Runable 接口,功能十分强大。本DEMO就是基于AsyncTaskLoader篇写。
  5. CursorLoader
    提供了一个基于AsyncTaskLoader工作机制的Loader,查看源码可以看到其继承于AsyncTaskLoader,一般继承OnQueryTextListener,可用于查询、更改数据源作用。

Loader 详细使用DEMO

基于上篇的Fragments 代码,添加Loaders功能,实现加载应用程序数据到界面上,DEMO的运行效果如下:

 

 

 核心代码为

 应用程序的数据对象类:

public  static  class AppEntry {
         private  final AppListLoader mLoader;
         private  final ApplicationInfo mInfo;
         private  final File mApkFile;
         private String mLable;
         private Drawable mIcon;
         private  boolean mMounted;

         public AppEntry(AppListLoader loader, ApplicationInfo info) {
            mLoader = loader;
            mInfo = info;
            mApkFile =  new File(info.sourceDir);
        }

         public ApplicationInfo getApplicationInfo() {
             return mInfo;
        }

         public String getLable() {
             return mLable;
        }

         public Drawable getIcon() {
             if (mIcon ==  null) {
                 if (mApkFile.exists()) {
                    mIcon = mInfo.loadIcon(mLoader.mPm);
                     return mIcon;
                }  else {
                    mMounted =  false;
                }
            }  else  if (!mMounted) {
                 if (mApkFile.exists()) {
                    mMounted =  true;
                    mIcon = mInfo.loadIcon(mLoader.mPm);
                     return mIcon;
                }
            }  else {
                 return mIcon;
            }
             return mLoader.getContext().getResources().getDrawable(
                    android.R.drawable.sym_def_app_icon);
        }

        @Override
         public String toString() {
             //  TODO Auto-generated method stub
             return mLable.toString();
        }

         void loadLable(Context mContext) {
             if (mLable ==  null || !mMounted) {
                 if (!mApkFile.exists()) {
                    mMounted =  false;
                    mLable = mInfo.packageName;
                }  else {
                    mMounted =  true;
                    CharSequence lable = mInfo.loadLabel(mContext
                            .getPackageManager());
                    mLable = lable !=  null ? lable.toString()
                            : mInfo.packageName;
                }
            }
        }

    }

 

实现AsyncTaskLoader 加载数据

public  static  class AppListLoader  extends AsyncTaskLoader<List<AppEntry>> {

         final InterestingConfigChanges mLastConfig =  new InterestingConfigChanges();
         final PackageManager mPm;

        List<AppEntry> mApps;
        packageIntentReceiver mPackageObserver;

         public AppListLoader(Context context) {
             super(context);
             //  TODO Auto-generated constructor stub
            mPm = getContext().getPackageManager();
        }

        @Override
         public List<AppEntry> loadInBackground() {
             //  TODO Auto-generated method stub
            List<ApplicationInfo> apps = mPm
                    .getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES
                            | PackageManager.GET_DISABLED_COMPONENTS);
             if (apps ==  null)
                apps =  new ArrayList<ApplicationInfo>();
             final Context mContext = getContext();
            List<AppEntry> entries =  new ArrayList<AppEntry>(apps.size());
             for (ApplicationInfo info : apps) {
                AppEntry entry =  new AppEntry( this, info);
                entry.loadLable(mContext);
                entries.add(entry);
            }
            Collections.sort(entries, ALPHA_COMPARATOR);
             return entries;
        }

        @Override
         public  void deliverResult(
                List<com.xuzhi.fragment.FragmentDemoActivity.AppEntry> data) {
             //  TODO Auto-generated method stub
             if (isReset()) {
                 if (data !=  null) {
                     // 释放资源处理
                }
            }
            
            List<AppEntry> oladApps=data;
            mApps=data;
             if(isStarted()){
                 super.deliverResult(data);
            }
            
            
             if(oladApps!= null){
                 // 释放资源
            }
        }
        
        
         protected  void onStartLoading() {
             if(mApps!= null)
                deliverResult(mApps);
            
             if(mPackageObserver== null)
                mPackageObserver= new packageIntentReceiver( this);
            
             boolean configChange=mLastConfig.applyNewConfig(getContext().getResources());
            
             if(takeContentChanged()|| mApps==  null || configChange){
                forceLoad();
            }
        };
        
        @Override
         public  void onCanceled(
                List<com.xuzhi.fragment.FragmentDemoActivity.AppEntry> data) {
             //  TODO Auto-generated method stub
             super.onCanceled(data);
            cancelLoad();
        }
        
        @Override
         protected  void onReset() {
             //  TODO Auto-generated method stub
             super.onReset();
            onStopLoading();
            
             if(mApps!= null){
                 // 释放资源
                mApps= null;
            }
            
             if(mPackageObserver!= null){
                getContext().unregisterReceiver(mPackageObserver);
                mPackageObserver= null;
            }
        }

    }

 

实现数据源:

public  static  class AppListAdapter  extends ArrayAdapter<AppEntry>{

        
         private LayoutInflater mInflater;
         public AppListAdapter(Context context) { 
             //  TODO Auto-generated constructor stub
             super(context, android.R.layout.simple_list_item_2);
            mInflater=(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            
        }
        
        
         public  void setData(List<AppEntry> data){
            clear();
             if(data!= null){
                addAll(data);
            }
        }
        
        @Override
         public View getView( int position, View convertView, ViewGroup parent) {
             //  TODO Auto-generated method stub
            View view;
             if(convertView== null){
                view=mInflater.inflate(R.layout.list_item_icon_text, parent, false);
            } else{
                view=convertView;
            }
            
            AppEntry item=getItem(position);
            ((ImageView)view.findViewById(R.id.icon)).setImageDrawable(item.getIcon());
            ((TextView)view.findViewById(R.id.text)).setText(item.getLable());
             return view;
        }
        

    }

 

在Activity 或者Fragments 里面实现接口:
public static class DetailsFragment extends ListFragment implements OnQueryTextListener,LoaderCallbacks<List<AppEntry>>

实现接口里面的函数:

public  boolean onQueryTextChange(String newText) {
             //  TODO Auto-generated method stub
             return  false;
        }

         public  boolean onQueryTextSubmit(String query) {
             //  TODO Auto-generated method stub
             return  false;
        }

         
         public Loader<List<com.xuzhi.fragment.FragmentDemoActivity.AppEntry>> onCreateLoader(
                 int id, Bundle args) {
             //  TODO Auto-generated method stub
             return  new AppListLoader(getActivity());
        }

         /**
         * Load 完成后
         
*/
         public  void onLoadFinished(
                Loader<List<com.xuzhi.fragment.FragmentDemoActivity.AppEntry>> arg0,
                List<com.xuzhi.fragment.FragmentDemoActivity.AppEntry> arg1) {
             //  TODO Auto-generated method stub
            mAdapter.setData(arg1);
               if (isResumed()) {
                    setListShown( true);
                }  else {
                    setListShownNoAnimation( true);
                }
        }

         /**
         * Loader 重置时
         
*/
         public  void onLoaderReset(
                Loader<List<com.xuzhi.fragment.FragmentDemoActivity.AppEntry>> arg0) {
             //  TODO Auto-generated method stub
             mAdapter.setData( null);

        } 

得到LoaderManager初始化Loader,启动加载在Fragment 的onActivityCreated回调方法上添加,本DEMO的DetailsFragment类添加:

@Override
         public  void onActivityCreated(Bundle savedInstanceState) {
             //  TODO Auto-generated method stub
             super.onActivityCreated(savedInstanceState);
            mAdapter =  new AppListAdapter(getActivity());
            setListAdapter(mAdapter);
            
             //  Start out with a progress indicator.
            setListShown( false);

             //  Prepare the loader.  Either re-connect with an existing one,
            
//  or start a new one.
            getLoaderManager().initLoader(0,  nullthis);

        } 

 

总结

Loader的使用分为以下几个步骤:

  1.  实现自己的异步Loader ,如本篇的AsyncTaskLoader或者CursorLoader或者自己继承Loader,第二步需要用到这个Loader
  2. 创建数据源->public static class AppListAdapter extends ArrayAdapter<AppEntry>
  3. 在Activity 或者Fragments 上实现OnQueryTextListener,LoaderManager.LoaderCallbacks接口
  4. 在onCreateLoader里面返回Loader,在onLoadfinished里面做清除动作,在onQueryTextChange或者onQueryTextSubmit改变数据源,在onCreate里面让Loader去执行请求数据getLoaderManager().initLoader(0, null, this);

 

源码下载:/Files/TerryBlog/FragmentLoader.zip

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值