因为用于展示短信记录的是一个ListView,但是为了方便,可以直接继承自ListFragment,就可以免去写ListView对应的布局了,只需要写其item对应的布局即可。

item_sended_msg.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@drawable/sms_item"android:padding="16dp"><TextViewandroid:id="@+id/id_tv_sended_content"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="8dp"/><com.example.just.festival_sms.view.FlowLayoutandroid:id="@+id/id_fl_sended_contacts"android:layout_width="match_parent"android:layout_height="match_parent"></com.example.just.festival_sms.view.FlowLayout><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="right"android:orientation="horizontal"><TextViewandroid:id="@+id/id_tv_fes"android:background="@drawable/tag_bg"android:layout_marginRight="8dp"android:layout_width="wrap_content"android:layout_height="wrap_content" /><TextViewandroid:id="@+id/id_tv_date"android:layout_width="wrap_content"android:layout_height="wrap_content" /></LinearLayout></LinearLayout>

还有tag.xml,显示联系人的layout

<TextView xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="#0ffcdd"android:background="@drawable/tag_bg"android:layout_margin="4dp"></TextView>

以及tag_bg.xml,用于显示联系人和节日的TextView的background 

<shape xmlns:android="http://schemas.android.com/apk/res/android"><solid android:color="#ffffff"></solid><stroke android:width="2dp" android:color="#0ffcdd"></stroke><corners android:radius="8dp"></corners><padding android:left="8dp" android:right="8dp" android:top="2dp" android:bottom="2dp"></padding>
</shape>

关于shape中的属性: 
http://www.oschina.net/question/166763_34833?fromerr=FBMFjTg7


SmsHistoryFragment.Java

需要注意,某些导入的包可能有多种选择,应该都是v4下的

public class SmsHistoryFragment extends ListFragment {private static final int LOADER_ID =1;private LayoutInflater mInflater;private CursorAdapter mCursorAdapter;@Overridepublic void onViewCreated(View view, Bundle savedInstanceState) {super.onViewCreated(view, savedInstanceState);mInflater=LayoutInflater.from(getActivity());initLoader();setupListAdapter();}private void setupListAdapter() {mCursorAdapter=new CursorAdapter(getActivity(),null,false) {//并不是每次都被调用的,它只在实例化view的时候调用,数据增加的时候也会调用//但是在重绘(比如修改条目里的TextView的内容)的时候不会被调用
            @Overridepublic View newView(Context context, Cursor cursor, ViewGroup parent) {View view=mInflater.inflate(R.layout.item_sended_msg,parent,false);//注意是"包名.R"return view;}//在绘制Item之前一定会调用bindView方法,它在重绘的时候也同样被调用
            @Overridepublic void bindView(View view, Context context, Cursor cursor) {TextView tvContent= (TextView) view.findViewById(R.id.id_tv_sended_content);FlowLayout flContacts= (FlowLayout) view.findViewById(R.id.id_fl_sended_contacts);TextView tvFes= (TextView) view.findViewById(R.id.id_tv_fes);TextView tvDate= (TextView) view.findViewById(R.id.id_tv_date);tvContent.setText(cursor.getString(cursor.getColumnIndex(SendedMsg.COLUMN_CONTENT)));tvFes.setText(cursor.getString(cursor.getColumnIndex(SendedMsg.COLUMN_FESTIVAL_NAME)));//注意这里的date为long,int型会溢出long date=cursor.getLong(cursor.getColumnIndex(SendedMsg.COLUMN_DATE));tvDate.setText(parseDate(date));String names=cursor.getString(cursor.getColumnIndex(SendedMsg.COLUMN_NAMES));if(TextUtils.isEmpty(names)) {return;}//因为ListView的item有复用的可能性,所以每次都要先除去item中的flContacts在上一次使用时添加的view
                flContacts.removeAllViews();for (String name:names.split(",")) {addTag(name, flContacts);}}};setListAdapter(mCursorAdapter);}private String parseDate(long date) {DateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm");return df.format(date);}private void addTag(String name,FlowLayout fl) {TextView tv= (TextView) mInflater.inflate(R.layout.tag,fl,false);tv.setText(name);fl.addView(tv);}private void initLoader() {getLoaderManager().initLoader(LOADER_ID,null,new LoaderManager.LoaderCallbacks<Cursor>() {//onCreateLoader是一个工厂方法,用来返回一个新的Loader//LoaderManager将会在它第一次创建Loader的时候调用该方法
            @Overridepublic Loader<Cursor> onCreateLoader(int id, Bundle args) {CursorLoader loader=new CursorLoader(getActivity(), SmsProvider.URI_SMS_ALL,null,null,null,null);return loader;}//onLoadFinished方法将在Loader创建完毕的时候自动调用//在数据更新的时候也会调用
            @Overridepublic void onLoadFinished(Loader<Cursor> loader, Cursor data) {if(loader.getId()==LOADER_ID) {mCursorAdapter.swapCursor(data);//更新mCursorAdapter的Cursor
                }}@Overridepublic void onLoaderReset(Loader<Cursor> loader) {mCursorAdapter.swapCursor(null);}});}
}

SmsHistoryFragment中,涉及到了LoaderManager与Loader,而关于这个知识点,推荐一篇优质博文,看完之后肯定会有所收获的。 
(http://blog.csdn.net/murphykwu/article/details/35287303)

还是回到本文中来,因为Android的设计之中,任何耗时的操作都不能放在UI主线程之中。所以类似于网络操作等等耗时的操作都需要使用异步的实现。而在ContentProvider之中,也有可能存在耗时的操作(当查询的数据量很大的时候),这个时候我们也需要使用异步的调用来完成数据的查。当使用异步的query的时候,我们就需要使用LoaderManager了。使用LoaderManager就可以在不阻塞UI主线程的情况下完成数据的加载。

还记得上一篇文章最后提及的两行代码吗?就是为了实时的更新数据用的,更进一步说,是为了同步ListView中显示数据(历史记录),两行代码缺一不可。(检测数据源是Loader的工作,Loader也会执行实际的同步载入操作,而在这之中,那两句代码就起到了一定的作用

另外,关于还有关于CursorAdapter,可以去看看这篇博文: 
http://www.bubuko.com/infodetail-734550.html

对了,小编在刚开始解读源码的时候有一个疑问,mCursorAdapter是在setupListAdapter中初始化的,但是initLoader中就用到了mCursorAdapter,为什么程序可以运行(因为这里是先initLoader再setupListAdapter)(但是实际中也可以先setupListAdapter再initLoader) 
后来实际测试了一下,发现部分具体的流程如下: 
onCreateLoader() -> 初始化mCursorAdapter ->setListAdapter(mCursorAdapter) 
-> onLoadFinished() 
这是因为getLoaderManager().initLoader()中传入的第三个参数是一个回调接口。

Android 节日短信送祝福(功能篇:2-短信历史记录Fragment的编写)相关推荐

  1. android节日祝福短信,Android-节日短信送祝福(UI篇)

    学员1010 2020-03-11 单列模式 第一个null判断 if (mInstance == null) 为了提供效率,多线程没必要每一次进行一次同步 第二个 synchronized(.cla ...

  2. Android 节日短信送祝福(功能篇:1-数据库操作类与自定义ContentProvider)

    首先,还是展示一下部分目录结构:  在节日短信送祝福的功能实现方面,为了能够方便直观展示实现过程,小编我以Java文件为基础,一个一个来展示,免得到时候这个java文件写点,一下又跳到另外一个java ...

  3. Android-节日短信送祝福(功能篇:1-数据库操作类与自定义ContentProvider)

    郑重声明:[慕课网–中级教程]系列的博文均是根据慕课网上的Android开发中级教程相应的视频,在学习之后写的,文中所涉及的源码与视频中的无太大区别,除开个别地方可能有所改善或者加入了自己的想法.如果 ...

  4. 国际网页短信软件平台后台功能篇|移讯云短信系统开发

    国际网页短信软件后台功能篇|移讯云短信系统开发 平台外放接口介绍 支持接入CMPP接口,支持smpp通道接入,支持外放CMPP接口(其他平台可以通过CMPP接入我平台),支持HTTP API JSON ...

  5. 求学信计算机专业英语,【向美国学校求学信范文】 求学信英语范文20篇_求学信英语范文20篇_英语求学信范文150字_东城教研...

    向美国学校求学信范文 关于向美国学校求学信范文,东城教研小编了解到:October12,2011 Office of Undergraduate Admission, Northwestern Uni ...

  6. Android-节日短信送祝福(功能篇:2-短信历史记录Fragment的编写)

    因为用于展示短信记录的是一个ListView,但是为了方便,可以直接继承自ListFragment,就可以免去写ListView对应的布局了,只需要写其item对应的布局即可. item_sended ...

  7. Android-节日短信送祝福(UI篇:1-主布局的基本实现)

    视频地址:http://www.imooc.com/learn/510 这次学习的内容,将会分为两个部分,这里先讲有关UI的部分.而且,Demo是在Android Studio上进行的. 相关素材及源 ...

  8. 服务器端接入有盟推送,实现为android 和 ios推送的功能

    在服务器端要做可以主动推送给客户端一些提示信息,比如会员到期,有人赞了你的评论,有人关注你这样的提示信息, 作为新手,暂时还不能自己写一些restful的东西,借助有盟现成的推送api,做一下记录,方 ...

  9. 从短信类到短信平台之设计篇

    引言 手机短信在系统的应用中越来越广泛,从单纯的发送信息到手机,发展到接收手机发送的短信,进行信息的获取,更有甚者,还可以进行业务的变更,业务数据的修改.从少量的发送,发展到大量的收发,衍生出大量的互 ...

最新文章

  1. Codeforces 446C —— DZY Loves Fibonacci Numbers(线段树)
  2. Linux修改密码是提示“passwd: 鉴定令牌操作错误”问题的处理办法
  3. 记一次坑爹的 “跨域” 问题
  4. 解决bash: mysql: command not found 的方法
  5. 八数码问题——双向广度优先搜索解决
  6. 阿里安全开源顶尖技术“猎豹” 计算更快数据更安全
  7. Java StringBuilder reverse()方法与示例
  8. linux查看分区访问权限,linux查看分区是否开启acl权限
  9. 深航 App 劫持微信;董明珠:给员工分房加薪是应得的回报;ofo 复活 | 极客头条...
  10. JVM常见的七种垃圾收集器的简单比较
  11. gpu跑普通python程序_普通电脑PC怎样跑TensorFlow的GPU模式
  12. KL距离(衡量两个概率分布的差异情况)
  13. 动态规划法---python实现
  14. 计算机sense服务无法启动,workstation服务无法启动解决办法
  15. js中RGB与十六进制颜色转换
  16. Kvaser Android驱动程序已经在许多应用程序中得到了成功的应用
  17. 基于求导的快速exp()算法,exp()快速计算,exp导数算法,exp函数C语言实现
  18. CentOS7下安装lnmp一键安装包
  19. MATLAB(一)——软件及基本操作介绍
  20. 树莓派学习笔记——定时向yeelink上传树莓派CPU温度

热门文章

  1. 灰度实战(三):Apollo配置中心(3)
  2. 由李飞飞领导,斯坦福以人为本AI学院正式成立,比尔·盖茨来捧场
  3. 被开除的Roadstar合伙人决定暂不回应,“报销大保健”也能忍?
  4. TensorFlow手把手教你概率编程:TF Probability内置了开源教材,新手友好
  5. GEF入门实例_总结_04_Eclipse插件启动流程分析
  6. springmvc多文件上传
  7. OOAD理论知识小结
  8. Convert.ToString和ToString的区别
  9. sqlplus 乱码的资料
  10. window2003 httpdns