Android加载器LoaderManager.LoaderCallbacks的使用

    xiaoxiao2021-03-25  131

    转自:http://blog.csdn.net/deng0zhaotai/article/details/22486423

    LoaderManager.LoaderCallbacks是3.0之后出现的新特性,通过LoaderManager.LoaderCallbacks接口可以很轻松的实现异步加载数据到Fragment或Activity 中,Loaders提供了回调机制onLoadFinished()通知最终的运行结果,有点类似AsyncTask类,但由于Loader对于并发可以用过Loader管理器统一管理,所以更适合批量处理多个异步任务的处理(当然内部仍然是多线程)。要使用Loader就要实现LoaderManager.LoaderCallbacks接口,并实现它的抽象方法

    下面是我加载通话记录的Demo,实现了过滤拨入、拨出、未接、所有,删除单条记录,拨号功能,实现效果图

    目录结构

    ListView中每个item的布局listview_item.xml

    [html]  view plain  copy   <?xml version="1.0" encoding="utf-8"?>   <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"       android:layout_width="match_parent"       android:layout_height="match_parent" >          <ImageView           android:id="@+id/bt_icon"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:layout_centerVertical="true"           android:layout_marginLeft="10dp"           android:background="#00000000"           android:contentDescription="@string/content_description"           android:src="@drawable/calllog_incoming" />          <TextView           android:id="@+id/tv_name"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:layout_marginLeft="10dp"           android:layout_marginTop="2dp"           android:layout_toRightOf="@id/bt_icon"           android:textSize="23sp" />          <TextView           android:id="@+id/tv_number"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:layout_alignLeft="@id/tv_name"           android:layout_below="@id/tv_name"           android:layout_marginBottom="2dp"           android:textColor="#7f7f7f"           android:textSize="16sp" />          <TextView           android:id="@+id/tv_date"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:layout_alignTop="@id/tv_number"           android:layout_marginLeft="10dp"           android:layout_toRightOf="@id/tv_number"           android:ellipsize="end"           android:textColor="#7f7f7f"           android:textSize="16sp" />          <ImageButton           android:id="@+id/btn_delete"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:layout_alignParentRight="true"           android:layout_centerVertical="true"           android:layout_marginRight="10dp"           android:background="#00000000"           android:contentDescription="@string/content_description"           android:focusableInTouchMode="false"           android:src="@drawable/cl_delete_selector" />          <ImageButton           android:id="@+id/btn_call"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:layout_centerVertical="true"           android:layout_marginRight="5dp"           android:layout_toLeftOf="@id/btn_delete"           android:background="#00000000"           android:contentDescription="@string/content_description"           android:focusableInTouchMode="false"           android:src="@drawable/cl_call_selector" />      </RelativeLayout>   整个Activity的布局文件

    [html]  view plain  copy   <RelativeLayout 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"       tools:context=".MainActivity" >          <TextView           android:id="@+id/tv_text"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:text="@string/hello_world" />          <Button           android:id="@+id/btn_all"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:layout_below="@id/tv_text"           android:text="@string/all" />          <Button           android:id="@+id/btn_incoming"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:layout_below="@id/tv_text"           android:layout_marginLeft="20dp"           android:layout_toRightOf="@id/btn_all"           android:text="@string/incoming" />          <Button           android:id="@+id/btn_outcoming"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:layout_below="@id/btn_all"           android:layout_marginTop="10dp"           android:text="@string/outcoming" />          <Button           android:id="@+id/btn_missed"           android:layout_width="wrap_content"           android:layout_height="wrap_content"           android:layout_alignLeft="@id/btn_incoming"           android:layout_below="@id/btn_all"           android:layout_marginTop="10dp"           android:layout_toRightOf="@id/btn_outcoming"           android:text="@string/missed" />          <View           android:id="@+id/line_layout"           android:layout_width="match_parent"           android:layout_height="2dp"           android:layout_below="@id/btn_missed"           android:background="#000000" >       </View>          <ListView           android:id="@+id/lv_list"           android:layout_width="match_parent"           android:layout_height="match_parent"           android:layout_below="@id/line_layout"           android:clipToPadding="false"           android:divider="#ff553311"           android:dividerHeight="2dp"           android:fadingEdge="none"           android:paddingTop="10dp" />      </RelativeLayout>   ListView对应的适配器MyCursorAdapter.java

    [java]  view plain  copy   package com.dzt.loaderdemo;      import java.text.SimpleDateFormat;   import java.util.Date;   import java.util.Locale;      import android.content.Context;   import android.content.Intent;   import android.database.Cursor;   import android.net.Uri;   import android.provider.CallLog;   import android.util.Log;   import android.view.LayoutInflater;   import android.view.View;   import android.view.ViewGroup;   import android.view.View.OnClickListener;   import android.widget.CursorAdapter;   import android.widget.ImageButton;   import android.widget.ImageView;   import android.widget.TextView;      class MyCursorAdapter extends CursorAdapter {          private static final String TAG = "dzt";       private final Context mContext;          public MyCursorAdapter(Context context, Cursor c) {           this(context, c, true);           // TODO Auto-generated constructor stub       }          public MyCursorAdapter(Context context, Cursor c, boolean autoRequery) {           super(context, c, autoRequery);           // TODO Auto-generated constructor stub           mContext = context;       }          public MyCursorAdapter(Context context, Cursor c, int flags) {           super(context, c, flags);           // TODO Auto-generated constructor stub           mContext = context;       }          @Override       public View newView(Context context, Cursor cursor, ViewGroup parent) {           // TODO Auto-generated method stub           LayoutInflater inflater = LayoutInflater.from(context);           return inflater.inflate(R.layout.listview_item, parent, false);       }          @Override       public void bindView(View view, Context context, Cursor cursor) {           // TODO Auto-generated method stub           if (cursor == null)               return;           final String id = cursor.getString(0);           String number = cursor.getString(1);           String name = cursor.getString(2);           int type = cursor.getInt(3);           String date = cursor.getString(4);           ImageView TypeView = (ImageView) view.findViewById(R.id.bt_icon);           TextView nameCtrl = (TextView) view.findViewById(R.id.tv_name);           if (name == null) {               nameCtrl.setText(mContext.getString(R.string.name_unknown));           } else {               nameCtrl.setText(name);           }           TextView numberCtrl = (TextView) view.findViewById(R.id.tv_number);           numberCtrl.setText(number);           String value = ComputeDate(date);           TextView dateCtrl = (TextView) view.findViewById(R.id.tv_date);           dateCtrl.setText(value);           switch (type) {           case CallLog.Calls.INCOMING_TYPE:               TypeView.setImageResource(R.drawable.calllog_incoming);               break;           case CallLog.Calls.OUTGOING_TYPE:               TypeView.setImageResource(R.drawable.calllog_outcoming);               break;           case CallLog.Calls.MISSED_TYPE:               TypeView.setImageResource(R.drawable.calllog_missed);               break;           case 4// CallLog.Calls.VOICEMAIL_TYPE                  break;           default:               break;           }              ImageButton dailBtn = (ImageButton) view.findViewById(R.id.btn_call);           dailBtn.setTag(number);           dailBtn.setOnClickListener(new OnClickListener() {                  @Override               public void onClick(View v) {                   // TODO Auto-generated method stub                   // Intent.ACTION_CALL_PRIVILEGED 由于Intent中隐藏了,只能用字符串代替                   Intent intent = new Intent(Intent.ACTION_CALL, Uri.fromParts(                           "tel", (String) v.getTag(), null));                   intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);                   mContext.startActivity(intent);               }           });              ImageButton deleteBtn = (ImageButton) view                   .findViewById(R.id.btn_delete);           deleteBtn.setOnClickListener(new OnClickListener() {                  @Override               public void onClick(View v) {                   // TODO Auto-generated method stub                   // 根据ID进行记录删除                   String where = CallLog.Calls._ID + "=?";                   String[] selectionArgs = new String[] { id };                   int result = mContext.getContentResolver().delete(                           CallLog.Calls.CONTENT_URI, where, selectionArgs);                   Log.d(TAG, "11result = " + result);               }           });       }          private String ComputeDate(String date) {           long callTime = Long.parseLong(date);           long newTime = new Date().getTime();           long duration = (newTime - callTime) / (1000 * 60);           String value;           // SimpleDateFormat sfd = new           // SimpleDateFormat("yyyy-MM-dd HH:mm:ss",           // Locale.getDefault());           // String time = sfd.format(callTime);           // Log.d(TAG, "[MyCursorAdapter--ComputeDate] time = " + time);           // 进行判断拨打电话的距离现在的时间,然后进行显示说明           if (duration < 60) {               value = duration + "分钟前";           } else if (duration >= 60 && duration < MainActivity.DAY) {               SimpleDateFormat sdf = new SimpleDateFormat("HH:mm",                       Locale.getDefault());               value = sdf.format(new Date(callTime));                  // value = (duration / 60) + "小时前";           } else if (duration >= MainActivity.DAY                   && duration < MainActivity.DAY * 2) {               value = "昨天";           } else if (duration >= MainActivity.DAY * 2                   && duration < MainActivity.DAY * 3) {               value = "前天";           } else if (duration >= MainActivity.DAY * 7) {               SimpleDateFormat sdf = new SimpleDateFormat("MM/dd",                       Locale.getDefault());               value = sdf.format(new Date(callTime));           } else {               value = (duration / MainActivity.DAY) + "天前";           }           return value;       }   }   加载器是放在MainActivity.java类当中

    [java]  view plain  copy   package com.dzt.loaderdemo;      import android.app.Activity;   import android.app.LoaderManager;   import android.content.CursorLoader;   import android.content.Loader;   import android.database.Cursor;   import android.os.Bundle;   import android.provider.CallLog;   import android.util.Log;   import android.view.View;   import android.view.View.OnClickListener;   import android.widget.Button;   import android.widget.ListView;      /**   * 使用加载器加载通话记录   *    * @author Administrator   *    */   public class MainActivity extends Activity {          private static final String TAG = "dzt";       // 查询指定的条目       private static final String[] CALLLOG_PROJECTION = new String[] {               CallLog.Calls._ID, CallLog.Calls.NUMBER, CallLog.Calls.CACHED_NAME,               CallLog.Calls.TYPE, CallLog.Calls.DATE };       static final int DAY = 1440// 一天的分钟值       private static final int ALL = 0// 默认显示所有       private static final int INCOMING = CallLog.Calls.INCOMING_TYPE; // 来电       private static final int OUTCOMING = CallLog.Calls.OUTGOING_TYPE; // 拔号       private static final int MISSED = CallLog.Calls.MISSED_TYPE; // 未接       private ListView mListView;       private MyLoaderListener mLoader = new MyLoaderListener();       private MyCursorAdapter mAdapter;       private int mCallLogShowType = ALL;       private boolean m_FinishLoaderFlag = false// 第一次加载完成          @Override       protected void onCreate(Bundle savedInstanceState) {           super.onCreate(savedInstanceState);           setContentView(R.layout.activity_main);           initWidgets();           initMyLoader();       }          private void initWidgets() {           mListView = (ListView) findViewById(R.id.lv_list);           Button btn = (Button) findViewById(R.id.btn_all);           btn.setOnClickListener(new buttonListener());           btn = (Button) findViewById(R.id.btn_incoming);           btn.setOnClickListener(new buttonListener());           btn = (Button) findViewById(R.id.btn_outcoming);           btn.setOnClickListener(new buttonListener());           btn = (Button) findViewById(R.id.btn_missed);           btn.setOnClickListener(new buttonListener());           mAdapter = new MyCursorAdapter(MainActivity.thisnull);           mListView.setAdapter(mAdapter);       }          private void initMyLoader() {           getLoaderManager().initLoader(0null, mLoader);       }          /**       * 实现一个加载器       *        * @author Administrator       *        */       private class MyLoaderListener implements               LoaderManager.LoaderCallbacks<Cursor> {              @Override           public Loader<Cursor> onCreateLoader(int id, Bundle args) {               // TODO Auto-generated method stub               m_FinishLoaderFlag = false;               CursorLoader cursor = new CursorLoader(MainActivity.this,                       CallLog.Calls.CONTENT_URI, CALLLOG_PROJECTION, nullnull,                       CallLog.Calls.DEFAULT_SORT_ORDER);               Log.d(TAG, "MyLoaderListener---------->onCreateLoader");               return cursor;           }              @Override           public void onLoadFinished(Loader<Cursor> loader, Cursor data) {               // TODO Auto-generated method stub               if (data == null)                   return;               Cursor tempData = data;               if (tempData.getCount() == 0) {                   Log.d(TAG,                           "MyLoaderListener---------->onLoadFinished count = 0");                   mAdapter.swapCursor(null);                   return;               }               if (m_FinishLoaderFlag) {                   tempData = null;                   String selection = null;                   String[] selectionArgs = null;                   if (mCallLogShowType == INCOMING) {                       selection = CallLog.Calls.TYPE + "=?";                       selectionArgs = new String[] { "1" };                   } else if (mCallLogShowType == OUTCOMING) {                       selection = CallLog.Calls.TYPE + "=?";                       selectionArgs = new String[] { "2" };                   } else if (mCallLogShowType == MISSED) {                       selection = CallLog.Calls.TYPE + "=?";                       selectionArgs = new String[] { "3" };                   }                   tempData = getContentResolver().query(                           CallLog.Calls.CONTENT_URI, CALLLOG_PROJECTION,                           selection, selectionArgs,                           CallLog.Calls.DEFAULT_SORT_ORDER);               }               mAdapter.swapCursor(tempData);               Log.d(TAG,                       "MyLoaderListener---------->onLoadFinished data count = "                               + data.getCount());               m_FinishLoaderFlag = true;           }              @Override           public void onLoaderReset(Loader<Cursor> loader) {               // TODO Auto-generated method stub               Log.d(TAG, "MyLoaderListener---------->onLoaderReset");               mAdapter.swapCursor(null);           }       }          private class buttonListener implements OnClickListener {              @Override           public void onClick(View v) {               // TODO Auto-generated method stub               switch (v.getId()) {               case R.id.btn_all:                   allCalllog();                   break;               case R.id.btn_incoming:                   incomingCalllog();                   break;               case R.id.btn_outcoming:                   outcomingCalllog();                   break;               case R.id.btn_missed:                   missedCalllog();                   break;               default:                   break;               }           }       }          private void allCalllog() {           mCallLogShowType = ALL;           String selection = null;           String[] selectionArgs = null;           Cursor allCursor = getContentResolver().query(                   CallLog.Calls.CONTENT_URI, CALLLOG_PROJECTION, selection,                   selectionArgs, CallLog.Calls.DEFAULT_SORT_ORDER);           mAdapter.swapCursor(allCursor);       }          private void incomingCalllog() {           mCallLogShowType = INCOMING;           String selection = CallLog.Calls.TYPE + "=?";           String[] selectionArgs = new String[] { "1" };           Cursor incomingCursor = getContentResolver().query(                   CallLog.Calls.CONTENT_URI, CALLLOG_PROJECTION, selection,                   selectionArgs, CallLog.Calls.DEFAULT_SORT_ORDER);           mAdapter.swapCursor(incomingCursor);       }          private void outcomingCalllog() {           mCallLogShowType = OUTCOMING;           String selection = CallLog.Calls.TYPE + "=?";           String[] selectionArgs = new String[] { "2" };           Cursor outcomingCursor = getContentResolver().query(                   CallLog.Calls.CONTENT_URI, CALLLOG_PROJECTION, selection,                   selectionArgs, CallLog.Calls.DEFAULT_SORT_ORDER);           mAdapter.swapCursor(outcomingCursor);       }          private void missedCalllog() {           mCallLogShowType = MISSED;           String selection = CallLog.Calls.TYPE + "=?";           String[] selectionArgs = new String[] { "3" };           Cursor missedCursor = getContentResolver().query(                   CallLog.Calls.CONTENT_URI, CALLLOG_PROJECTION, selection,                   selectionArgs, CallLog.Calls.DEFAULT_SORT_ORDER);           mAdapter.swapCursor(missedCursor);       }   }   加载器的使用就是重写三个回调函数,并在加载完时设置Adapter的Cursor,使用Loader之后,只要数据源发生变化,就会自动调用onLoadFinished(),此时listview也会自动刷新

    完整的Demo

    http://download.csdn.net/detail/deng0zhaotai/7116173

    转载请注明原文地址: https://ju.6miu.com/read-3027.html

    最新回复(0)