Android Api Demos登顶之路(四十五)Loader-->Cursor
阅读原文时间:2023年07月13日阅读:1

这个demo演示了类载入器的用法。关于类载入器的使用我们在前面的demo中已经介绍过了 在此再小小的复习一下。

类载入器的使用步骤:

* 1.获取类载入器的管理者LoaderManager manager = tent.getLoaderManager();

* 2.初始化loader

MainActivity

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        FragmentManager fm = getFragmentManager();
        // 推断一下假设activity中没有载入视图,则创建新的视图并载入
        if (fm.findFragmentById(android.R.id.content) == null) {
            CursorLoaderListFragment frg = new CursorLoaderListFragment();
            fm.beginTransaction().add(android.R.id.content, frg).commit();
        }
    }

    public class CursorLoaderListFragment extends ListFragment implements
            OnQueryTextListener, OnCloseListener {

        private SimpleCursorAdapter mAdapter;
        private MySearchView mySearchView;
        private String mCurrentFilter;

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            // 当查询结果为空,listview中无显示内容时,设置显示的提示信息
            setEmptyText("No phone numbers!");
            // 设置显示actionbar
            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);
            // 此时不显示列表。由于数据还没准备好
            setListShown(false);
            // 获取类载入器的管理者,并初始化
            getLoaderManager().initLoader(0, null, myLoader);
        }

        // 定义要查询的内容
        private final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
                Contacts._ID, Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS,
                Contacts.CONTACT_PRESENCE, Contacts.PHOTO_ID,
                Contacts.LOOKUP_KEY };

        private LoaderCallbacks<Cursor> myLoader = new LoaderCallbacks<Cursor>() {

            @Override
            public Loader<Cursor> onCreateLoader(int id, Bundle args) {
                Uri baseUri;
                if (mCurrentFilter != null) {
                    // 假设查询条件不为空,则在原来的基础上追加查询条件
                    baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
                            Uri.encode(mCurrentFilter));
                } else {
                    baseUri = Contacts.CONTENT_URI;
                }

                // 定义查询条件
                String selection = "((" + Contacts.DISPLAY_NAME
                        + " NOTNULL) AND (" + Contacts.HAS_PHONE_NUMBER
                        + "=1) AND (" + Contacts.DISPLAY_NAME + " != '' ))";
                return new CursorLoader(getActivity(), baseUri,
                        CONTACTS_SUMMARY_PROJECTION, selection, null,
                        Contacts.DISPLAY_NAME + " COLLATE LOCALIZED ASC");
            }

            @Override
            public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
                // 载入完毕交换查询结果
                mAdapter.swapCursor(cursor);
                //假设Fragment处于恢复状态中则显示载入动画,否则不显示载入动画
                //数据准备完毕,显示列表
                if(isResumed()){
                    setListShown(true);
                }else{
                    setListShownNoAnimation(true);
                }
            }

            @Override
            public void onLoaderReset(Loader<Cursor> loader) {
                //重新启动载入器时首先要确保清除旧的数据
                mAdapter.swapCursor(null);
            }

        };

        // 自己定义搜索视图
        public class MySearchView extends SearchView {

            public MySearchView(Context context) {
                super(context);
            }

            // 正常情况下serchView在收缩的时候是不会清空当中的内容的
            // 这里我们须要重写收缩时的方法,在收缩时清空内容
            @Override
            public void onActionViewCollapsed() {
                // 仅仅更新查询内容不提交查询
                setQuery("", false);
                super.onActionViewCollapsed();
            }
        }

        @Override
        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
            super.onCreateOptionsMenu(menu, inflater);
            MenuItem item = menu.add("search");
            item.setIcon(android.R.drawable.ic_menu_search);
            // 设置item的显示方式
            item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM
                    | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW);
            mySearchView = new MySearchView(getActivity());
            // 监听查询内容的变化
            mySearchView.setOnQueryTextListener(this);
            mySearchView.setOnCloseListener(this);
            //设置搜索框默认自己主动缩小为图标
            mySearchView.setIconifiedByDefault(true);
            //设置item的动作视图,按下前仅仅显示小图标。按下后展开显示
            item.setActionView(mySearchView);
        }

        @Override
        public boolean onQueryTextSubmit(String query) {
            // 不必关心是否提交。在查询内容发生变化时就已经作出了处理
            return true;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            String newFilter = !TextUtils.isEmpty(newText) ?

newText : null;
            // 当查询条件没有变化时,不做不论什么事,仅仅是返回true。

if (mCurrentFilter == null && newFilter == null) {
                return true;
            }
            if (mCurrentFilter != null && mCurrentFilter.equals(newFilter)) {
                return true;
            }
            mCurrentFilter = newFilter;
            // 重新启动载入器
            getLoaderManager().restartLoader(0, null, myLoader);
            return true;
        }

        @Override
        public boolean onClose() {
            // 将查询内容置空
            if (!TextUtils.isEmpty(mySearchView.getQuery())) {
                mySearchView.setQuery(null, true);
            }
            return true;
        }

        @Override
        public void onListItemClick(ListView l, View v, int position, long id) {
            super.onListItemClick(l, v, position, id);
            Toast.makeText(getActivity(), "Item clicked:" + id, 0).show();
        }

    }

}

配置文件里加入权限

<uses-permission android:name="android.permission.READ_CONTACTS"/>