理解android中ListFragment和Loader

一直以来不知android中Loader怎么用,今天晚上特意花了时间来研究,算是基本上搞明白了,现在把相关的注释和代码发出来,以便笔记和给网友一个参考,错误之处还望大家给我留言,共同进步,这个例子采用的是android事例代码,在其中比较难理解的地方,给出注释,代码如下:

public class MainActivity extends FragmentActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//这是使用的android-support-v4.jar兼容包,如果网友使用的android4.0以上的版本
		//可不使用,改成相应的方法就行
		FragmentManager fm = getSupportFragmentManager();
		if (fm.findFragmentById(android.R.id.content) == null) {
            CursorLoaderListFragment list = new CursorLoaderListFragment();
            fm.beginTransaction().add(android.R.id.content, list).commit();
        }
	}
	
	public static class CursorLoaderListFragment extends ListFragment
		implements OnQueryTextListener,OnCloseListener,
		LoaderCallbacks<Cursor>{
		
		SimpleCursorAdapter mAdapter;
        SearchView mSearchView;
        String mCurFilter;
        
        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
        	// TODO Auto-generated method stub
        	super.onActivityCreated(savedInstanceState);
        	//设置没有数据显示的默认文本
        	setEmptyText("No phone numbers");
        	//设置可由fragment创建的菜单
            setHasOptionsMenu(true);
            //设置适配器
            mAdapter = new SimpleCursorAdapter(getActivity(),
                    android.R.layout.simple_list_item_2, null,
                    new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS },
                    new int[] { android.R.id.text1, android.R.id.text2 }, 0);
            setListAdapter(mAdapter);
            //设置不显示ListView,等待加载完成以后显示
            setListShown(false);
            //初始化加载器
            getLoaderManager().initLoader(0, null, this);
        }
        
        public static class MySearchView extends SearchView {
            public MySearchView(Context context) {
                super(context);
            }

            //正常的SearchView不会清楚搜索文本当SearchView关闭是,所以我们要重写
            @Override
            public void onActionViewCollapsed() {
            	//一当关闭就设置查询文本为空
                setQuery("", false);
                super.onActionViewCollapsed();
            }
        }

        @Override
        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        	// TODO Auto-generated method stub
        	//将搜索框加入ActionBar
        	MenuItem item = menu.add("Search");
        	//设置SearchView的图标
            item.setIcon(android.R.drawable.ic_menu_search);
            //设置ActionItem的显示方式
            item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM
                    | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
            //使用自定义的SearchView以便更好的控制
            mSearchView = new MySearchView(getActivity());
            //设置文本改变的监听器
            mSearchView.setOnQueryTextListener(this);
            //设置可删除文本的监听器
            mSearchView.setOnCloseListener(this);
            //设置图标是否显示在文本的旁边,还是作为背景
            mSearchView.setIconifiedByDefault(true);
            //将SearchView作为ActionItem的选项
            item.setActionView(mSearchView); 
        }

        @Override
        public void onListItemClick(ListView l, View v, int position, long id) {
        	// TODO Auto-generated method stub
        	super.onListItemClick(l, v, position, id);
        	Log.i("FragmentComplexList", "Item clicked: " + id);
        }
        
        static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
            Contacts._ID,
            Contacts.DISPLAY_NAME,
            Contacts.CONTACT_STATUS,
            Contacts.CONTACT_PRESENCE,
            Contacts.PHOTO_ID,
            Contacts.LOOKUP_KEY,
        };
        
		@Override
		public Loader<Cursor> onCreateLoader(
				int arg0, Bundle arg1) {
			// TODO Auto-generated method stub
			Uri baseUri;
            if (mCurFilter != null) {
                baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
                        Uri.encode(mCurFilter));
            } else {
                baseUri = Contacts.CONTENT_URI;
            }
            String select = "((" + Contacts.DISPLAY_NAME + " NOTNULL) AND ("
                    + Contacts.HAS_PHONE_NUMBER + "=1) AND ("
                    + Contacts.DISPLAY_NAME + " != '' ))";
            //创建一个新的装载器
            return new CursorLoader(getActivity(), baseUri,
                    CONTACTS_SUMMARY_PROJECTION, select, null,
                    Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
		}

		@Override
		public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {
			// TODO Auto-generated method stub
			//以前一直不明白这句话的意思,只知道是交换一个新的Cursor,返回一个旧的Cursor,
		    //现在大概明白了,在这里将新的Cursor交给mAdapter,以便ListView能够显示,
			//细心的朋友可能会发现,在创建mAdapter的时候传入的Cursor为空,其实是没有数据
			//的,在这里加载好了,就把这个新的Curosr对象传进去,让ListView
			//显示,这个地方很多网友搞不明白,这里多解释一下
			mAdapter.swapCursor(arg1);

			//现在显示ListView
            if (isResumed()) {
                setListShown(true);
            } else {
                setListShownNoAnimation(true);
            }
		}

		@Override
		public void onLoaderReset(Loader<Cursor> arg0) {
			// TODO Auto-generated method stub
			//当这个Loader被重置时,也就是调用了restartLoader方法是,使以前的数据无效
			mAdapter.swapCursor(null);
		}

		@Override
		public boolean onClose() {
			// TODO Auto-generated method stub
			if (!TextUtils.isEmpty(mSearchView.getQuery())) {
                mSearchView.setQuery(null, true);
            }
            return true;
		}

		@Override
		public boolean onQueryTextChange(String newText) {
			String newFilter = !TextUtils.isEmpty(newText) ? newText : null;
            if (mCurFilter == null && newFilter == null) {
                return true;
            }
            if (mCurFilter != null && mCurFilter.equals(newFilter)) {
                return true;
            }
            mCurFilter = newFilter;
            getLoaderManager().restartLoader(0, null, this);
            return true;
		}

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



你可能感兴趣的:(android,loader,listfragment)