2.App Components-Activities/Loadres

1. Loaders

  loaders make it easy to asynchronously load data in an activity or fragment. Loaders have these characteristics:

    <1>They are available to every Activity and Fragment.

    <2>They provide asynchronous loading of data

    <3>They monitor the source of their data and deliver new results when the content changes

    <4>They automatically reconnect to the last loader's cursor when being recreated after a configuration change. Thus, they don't need to

      re-query their data

 

2. Using Loaders in an appliction

  An application that uses loaders typically includes the following:

    <1> An Activity or Fragment.

    <2> An instance of the LoaderManager.

    <3> A CursorLoader to load data backed by a ContentProvider.

        Alternatively, you can implement your own subclass of Loader or AsyncTaskLoader to load data from some other source.

    <4> An implementation for LoaderManager.LoaderCallbacks.

        This is where you create new loaders and manage your references to existing loaders.

    <5> A way of displaying the loader's data, such as a SimpleCursorAdapter.

    <6> A data source, such as a ContentProvider, when using a CursorLoader.

 

3. Starting a Loader

  The LoaderManager manages one or more Loader instances within an Activity or Fragment. There is only one LoaderManager per activity or fragment.

  You typically initialize a Loader within the activity's onCreate() method, or within the fragment's onActivityCreated() method. You do this as follows:

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

  

4.Restart a Loader

  When you use initLoader(), as shown above, it uses an existing loader with the specified ID if there is one. If there isn't, it creates one. But

    sometimes you want to discard your old data and start over.

  To discard your old data, you use restartLoader(). For example, this implementation of SearchView.OnQueryTextListener restarts the loader when

    the user's query changes. The loader needs to be restarted so that it can use the revised search filter to do a new query:

public boolean onQueryTextChanged(String newText) {
    // Called when the action bar search text has changed.  Update
    // the search filter, and restart the loader to do a new query
    // with this filter.
    mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
    getLoaderManager().restartLoader(0, null, this);
    return true;
}
View Code

 

5. Using the LoaderManager Callbacks

  LoaderManager.LoaderCallbacks is a callback interface that lets a client interact with the LoaderManager.

  Loaders, in particular CursorLoader, are expected to retain their data after being stopped.

    This allows applications to keep their data across the activity or fragment's onStop() and onStart() methods, so that when users return to an

    application, they don't have to wait for the data to reload. You use the LoaderManager.LoaderCallbacks methods when to know when to create

    a new loader, and to tell the application when it is time to stop using a loader's data.

  5.1 onCreateLoader

    When you attempt to access a loader (for example, through initLoader()), it checks to see whether the loader specified by the ID exists.

      If it doesn't, it triggers the LoaderManager.LoaderCallbacks method onCreateLoader(). This is where you create a new loader. Typically this

      will be a CursorLoader, but you can implement your own Loader subclass.

  5.2 onLoadFinished

    This method is called when a previously created loader has finished its load. This method is guaranteed to be called prior to the release of

      the last data that was supplied for this loader. At this point you should remove all use of the old data (since it will be released soon),

      but should not do your own release of the data since its loader owns it and will take care of that. 

  5.3 onLoaderReset

    This method is called when a previously created loader is being reset, thus making its data unavailable. This callback lets you find out

      when the data is about to be released so you can remove your reference to it.

 

6. Example 

  As an example, here is the full implementation of a Fragment that displays a ListView containing the results of a query against the contacts

    content provider. It uses a CursorLoader to manage the query on the provider.

  For an application to access a user's contacts, as shown in this example, its manifest must include the permission READ_CONTACTS.

  

//activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="mirror.android.loader_test.MainActivity" >

    <fragment  
        class="mirror.android.loader_test.CursorLoaderListFragment"
        android:id="@+id/fragment_list"  
        android:name="com.example.android.content.loadercursor.CursorLoaderListFragment"  
        android:layout_width="match_parent"  
        android:layout_height="match_parent" />  

</FrameLayout>
//MainActivity
package mirror.android.loader_test;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

  

//CursorLoaderListFragment.java
package mirror.android.loader_test;

import android.app.ListFragment;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract.Contacts;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;
import android.widget.SearchView.OnQueryTextListener;

/* 
 * 实现LoaderManager.LoaderCallbacks接口,用于与Loader的交互 
 * 官方文档: A callback interface for a client to interact with the LoaderManager. 
 * For example, you use the onCreateLoader() callback method to create a new loader. 
 */  
public class CursorLoaderListFragment extends ListFragment 
    implements OnQueryTextListener, LoaderCallbacks<Cursor>{

    // 显示联系人
    // This is the Adapter being used to display the list's data.
    SimpleCursorAdapter mAdapter;

    // 判断 手机联系人列表 是否有符合 搜索框内搜索人名字的
    // If non-null, this is the current filter the user has provided.
    String mCurFilter;

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {

        super.onActivityCreated(savedInstanceState);
        
        //当List为空时可以看到这个文字
        setEmptyText("No phone numbers");

        // We have a menu item to show in action bar.
        setHasOptionsMenu(true);

        // Create an empty adapter we will use to display the loaded data.
        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);

        // Prepare the loader.  Either re-connect with an existing one, or start a new one.
        // You typically initialize a Loader within the activity's onCreate() method, 
        //     or within the fragment's onActivityCreated() method. 
        getLoaderManager().initLoader(0, null,this);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        // TODO Auto-generated method stub
        MenuItem item = menu.add("Search");
        item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
        //A widget that provides a user interface for the user to enter a search query and submit a request
        //to a search provider. Shows a list of query suggestions or results, if available, and allows the
        //user to pick a suggestion or result to launch into.
        //加上搜索框
        SearchView sv = new SearchView(getActivity());
        //搜索框监听文字输入
        sv.setOnQueryTextListener(this);
        item.setActionView(sv);
    }

    @Override
    public boolean onQueryTextSubmit(String query) {
        return true;
    }

    @Override
    public boolean onQueryTextChange(String newText) {
        // Called when the action bar search text has changed.  Update
        // the search filter, and restart the loader to do a new query
        // with this filter.
        // 输入后List会根据输入自动匹配新的List, 所以需要restart a new Loader
        mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
        getLoaderManager().restartLoader(0, null, this);
        return true;
    }

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

    // These are the Contacts rows that we will retrieve.
    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 id, Bundle args) {
        // This is called when a new Loader needs to be created.  This
        // sample only has one Loader, so we don't care about the ID.
        // First, pick the base URI to use depending on whether we are
        // currently filtering.
        Uri baseUri;
        if (mCurFilter != null) {
            baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
                    Uri.encode(mCurFilter));
        } else {
            baseUri = Contacts.CONTENT_URI;
        }

        // Now create and return a CursorLoader that will take care of
        // creating a Cursor for the data being displayed.
        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 onLoaderReset(Loader<Cursor> loader) {
        // This is called when the last Cursor provided to onLoadFinished()
        // above is about to be closed.  We need to make sure we are no
        // longer using it.
        // Swap the new cursor in.  (The framework will take care of closing the
        // old cursor once we return.)
        mAdapter.swapCursor(null);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        mAdapter.swapCursor(data);
    }
}

 

 

  run

  

  click the icon in the Right-up decrection , will can search the Contacts

  

  Type A, it will restart loader automatically

  

  Besides, press Home_Key to add a contract in the contact list, then go back to this appliction,it will aumatically add a contract to the list

  

转载于:https://www.cnblogs.com/iMirror/p/4047722.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值