会话详情页


listview条目布局

TableLayout是一行几列的意思
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="match_parent"
  3. android:layout_height="wrap_content"
  4. android:orientation="vertical" >
  5. <!-- android:shrinkColumns="0" 压缩第0列,当第0列的内容过多时,不至于将其他列的内容,挤出屏幕 -->
  6. <TableLayout
  7. android:id="@+id/tl_receive"
  8. android:layout_width="match_parent"
  9. android:shrinkColumns="0"
  10. android:layout_height="wrap_content" >
  11. <TableRow android:layout_height="wrap_content" >
  12. <TextView
  13. android:id="@+id/tv_msg_receive"
  14. android:layout_width="wrap_content"
  15. android:layout_height="wrap_content"
  16. android:background="@drawable/receive_msg_bubble"
  17. android:text="asdfasdfasdfasdfasdfsdfadfadfasdfasfsdfadffad" />
  18. <TextView
  19. android:id="@+id/tv_date_receive"
  20. android:layout_width="wrap_content"
  21. android:layout_height="match_parent"
  22. android:gravity="bottom"
  23. android:text="2014/10/10" />
  24. </TableRow>
  25. </TableLayout>
  26. <!-- android:shrinkColumns="1" 压缩第0列,当第0列的内容过多时,不至于将其他列的内容,挤出屏幕 -->
  27. <TableLayout
  28. android:id="@+id/tl_send"
  29. android:layout_width="match_parent"
  30. android:shrinkColumns="1"
  31. android:layout_height="wrap_content" >
  32. <TableRow android:layout_height="wrap_content"
  33. android:gravity="right">
  34. <TextView
  35. android:id="@+id/tv_date_send"
  36. android:layout_width="wrap_content"
  37. android:layout_height="match_parent"
  38. android:gravity="bottom"
  39. android:text="2014/10/10" />
  40. <TextView
  41. android:id="@+id/tv_msg_send"
  42. android:layout_width="wrap_content"
  43. android:layout_height="wrap_content"
  44. android:background="@drawable/send_msg_bubble"
  45. android:text="sfsdfadadsadsfasdfadfffad" />
  46. </TableRow>
  47. </TableLayout>
  48. <!-- 另一种实现 方式 -->
  49. <!-- <LinearLayout
  50. android:layout_width="match_parent"
  51. android:layout_height="wrap_content"
  52. android:gravity="right"
  53. >
  54. <LinearLayout
  55. android:layout_width="wrap_content"
  56. android:layout_height="wrap_content"
  57. >
  58. <TextView
  59. android:layout_width="wrap_content"
  60. android:layout_height="match_parent"
  61. android:gravity="bottom"
  62. android:text="2014/10/10" />
  63. <TextView
  64. android:layout_width="0dp"
  65. android:layout_height="wrap_content"
  66. android:layout_weight="2"
  67. android:background="@drawable/send_msg_bubble"
  68. android:text="asdfdf" />
  69. </LinearLayout>
  70. </LinearLayout> -->
  71. </LinearLayout>
代码:
  1. public class ConversationDetail extends Activity implements OnClickListener{
  2. /**
  3. *联系人的电话号码
  4. */
  5. private String address;
  6. private Context ctx;
  7. private ListView listView;
  8. private EditText inputMsg;
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12. ctx = this;
  13. address = getIntent().getStringExtra("address");
  14. if(address == null){
  15. throw new RuntimeException("联系人是空,我不知道显示哪个会话记录");
  16. }
  17. setContentView(R.layout.activity_conversation_detail);
  18. init();
  19. listView = (ListView) findViewById(R.id.lv_conversation_detail);
  20. adapter = new MyListAdapter(this, null);
  21. listView.setAdapter(adapter);
  22. //设置listView条目之间的分隔线为null ,即,不要分隔线
  23. listView.setDivider(null);
  24. prepareData();
  25. }
  26. private void prepareData() {
  27. MyQueryHandler
    1. public class MyQueryHandler extends AsyncQueryHandler{
    2. public MyQueryHandler(ContentResolver cr) {
    3. super(cr);
    4. }
    5. @Override
    6. protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
    7. System.out.println("onQueryComplete : token:"+token);
    8. System.out.println("onQueryComplete : cookie:"+cookie);
    9. Tools.printCursor(cursor);
    10. if(cookie!=null && cookie instanceof CursorAdapter){
    11. CursorAdapter adapter = (CursorAdapter) cookie;
    12. // 给adapter 设置新的cursor
    13. adapter.changeCursor(cursor);
    14. }
    15. if(cursorChangedListener!=null){
    16. cursorChangedListener.onCursorChanged(token, cookie, cursor);
    17. }
    18. }
    19. public IOnCursorChangedListener getCursorChangedListener() {
    20. return cursorChangedListener;
    21. }
    22. public void setOnCursorChangedListener(IOnCursorChangedListener cursorChangedListener) {
    23. this.cursorChangedListener = cursorChangedListener;
    24. }
    25. private IOnCursorChangedListener cursorChangedListener;
    26. /**
    27. * 声明,cursor改变时的监听接口
    28. * @author Administrator
    29. *
    30. */
    31. public interface IOnCursorChangedListener{
    32. void onCursorChanged(int token, Object cookie, Cursor cursor);
    33. }
    34. }
    //回调接口写法:这样就把adapter有回传回来了
  28. MyQueryHandler myQueryHandler = new MyQueryHandler(getContentResolver());
  29. myQueryHandler.setOnCursorChangedListener(new MyQueryHandler.IOnCursorChangedListener() {
  30. @Override
  31. /**
  32. * 当adapter 获得 cursor 的时候,回调此方法
  33. */
  34. public void onCursorChanged(int token, Object cookie, Cursor cursor) {
  35. // 让listview 显示最后一行
  36. listView.setSelection(adapter.getCount()-1);
  37. }
  38. });
  39. myQueryHandler.startQuery(99, adapter, MyConstants.URI_SMS, projection, " address="+address, null, " date ");
  40. }
  41. /**
  42. * 显示会话详情,所需要的列
  43. */
  44. private String[] projection={
  45. "_id","body","date","type"
  46. };
  47. /**
  48. * 短信内容所在列的索引值 为 1
  49. */
  50. private final int INDEX_BODY = 1;
  51. private final int INDEX_DATE = 2;
  52. private final int INDEX_TYPE = 3;
  53. private void init() {
  54. TextView title = (TextView) findViewById(R.id.tv_title_conversation_detail);
  55. String name = Tools.findNameByNumber(ctx, address);
  56. if(name !=null){ // 有此联系人
  57. title.setText(name);
  58. }else{ // 无此联系人
  59. title.setText(address);
  60. }
  61. findViewById(R.id.btn_back).setOnClickListener(this);
  62. findViewById(R.id.btn_ok).setOnClickListener(this);
  63. inputMsg = (EditText) findViewById(R.id.et_input_msg_conversation_detail);
  64. }
  65. @Override
  66. /**
  67. * 响应按钮的点击事件
  68. */
  69. public void onClick(View v) {
  70. switch (v.getId()) {
  71. case R.id.btn_back: // 后退按钮
  72. finish();
  73. break;
  74. case R.id.btn_ok: // 确定按钮
  75. //先判断输入的是否有内容,
  76. //如果有内容的话,就将内容以短信的形式发送出去,
  77. String msg = inputMsg.getText().toString();
  78. if(TextUtils.isEmpty(msg.trim())){
  79. Toast.makeText(ctx, "请输入短信内容", 0).show();
  80. return ;
  81. }
  82. // 发送短信
  83. Tools.sendMessage(ctx,msg,address);
  84. //清空输入框
  85. inputMsg.setText("");
  86. // 隐藏输入法键盘
  87. InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
  88. // 隐藏输入法的 API
  89. imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS);
  90. break;
  91. }
  92. }
  93. private MyListAdapter adapter;
  94. private class MyListAdapter extends CursorAdapter{
  95. public MyListAdapter(Context context, Cursor c) {
  96. super(context, c);
  97. }
  98. @Override
  99. /**
  100. * 当内容发生改变的时候,回调此方法
  101. */
  102. protected void onContentChanged() {
  103. // super 里面,做了重新查询的动作
  104. super.onContentChanged();
  105. // 让listView 显示最后一行
  106. listView.setSelection(getCount()-1);
  107. }
  108. @Override
  109. public View newView(Context context, Cursor cursor, ViewGroup parent) {
  110. View view =View.inflate(ctx, R.layout.list_item_conversation_detail, null);
  111. ViewHolder vh = new ViewHolder();
  112. vh.tlReceive = (TableLayout) view.findViewById(R.id.tl_receive);
  113. vh.msgReceive = (TextView) view.findViewById(R.id.tv_msg_receive);
  114. vh.dateReceive = (TextView) view.findViewById(R.id.tv_date_receive);
  115. vh.tlSend = (TableLayout) view.findViewById(R.id.tl_send);
  116. vh.msgSend = (TextView) view.findViewById(R.id.tv_msg_send);
  117. vh.dateSend = (TextView) view.findViewById(R.id.tv_date_send);
  118. view.setTag(vh);
  119. return view;
  120. }
  121. @Override
  122. public void bindView(View view, Context context, Cursor cursor) {
  123. ViewHolder vh = (ViewHolder) view.getTag();
  124. // 给listView条目设置内容
  125. int type = cursor.getInt(INDEX_TYPE);// 获得短信类型
  126. String text = cursor.getString(INDEX_BODY);//获得短信内容
  127. long when = cursor.getLong(INDEX_DATE);// 获得日期
  128. String dateStr = DateFormat.getDateFormat(ctx).format(when);
  129. if(type == MyConstants.TYPE_RECEIVE){ // 接收到的短信
  130. vh.tlReceive.setVisibility(View.VISIBLE);
  131. vh.tlSend.setVisibility(View.GONE);
  132. //设置短信内容
  133. vh.msgReceive.setText(text);
  134. //设置日期
  135. vh.dateReceive.setText(dateStr);
  136. }else{
  137. vh.tlReceive.setVisibility(View.GONE);
  138. vh.tlSend.setVisibility(View.VISIBLE);
  139. //设置短信内容
  140. vh.msgSend.setText(text);
  141. vh.dateSend.setText(dateStr);
  142. }
  143. }
  144. }
  145. private class ViewHolder {
  146. public TableLayout tlReceive;
  147. public TextView msgReceive;
  148. public TextView dateReceive;
  149. public TableLayout tlSend;
  150. public TextView msgSend;
  151. public TextView dateSend;
  152. }
  153. }

4.TableLayout、回调接口的更多相关文章

  1. Android回调接口的写法

    方法一: 定义一个接口,里面写想要对外提供的方法,在逻辑层方法的参数里传递进去,让在需要的时候调接口里的方法. 实例一: public class SmsUtils { public interfac ...

  2. Android中回调接口的使用

    MainActivity如下: package cn.testcallback; import android.os.Bundle; import android.app.Activity; /** ...

  3. 手势识别官方教程(2)识别常见手势用GestureDetector+手势回调接口/手势抽象类

    简介 GestureDetector识别手势. GestureDetector.OnGestureListener是识别手势后的回调接口.GestureDetector.SimpleOnGesture ...

  4. 使用回调接口实现ActiveX控件和它的容器程序的通讯

    本文阅读基础:有一定的C++基础知识(了解继承.回调函数),对MFC的消息机制有一定了解,对COM的基础知识有一定了解,对ActiveX控件有一定了解. 一. 前言 ActiveX控件和它的容器程序如 ...

  5. 【Android 应用开发】 自定义组件 宽高适配方法, 手势监听器操作组件, 回调接口维护策略, 绘制方法分析 -- 基于 WheelView 组件分析自定义组件

    博客地址 : http://blog.csdn.net/shulianghan/article/details/41520569 代码下载 : -- GitHub : https://github.c ...

  6. Spring Boot启动过程及回调接口汇总

    Spring Boot启动过程及回调接口汇总 链接: https://www.itcodemonkey.com/article/1431.html 来自:chanjarster (Daniel Qia ...

  7. C#POST 支付宝/微信回调接口

    一般支付宝/微信的回调接口都会返回xml格式,下面是调用类似这种接口的办法: public async Task<string> GetData() { string requestUrl ...

  8. vue回调接口

    1.微博回调接口 1.1oauth/urls.py 中添加路由 urlpatterns = [ path('weibo/callback/', views.OauthWeiboCallback.as_ ...

  9. Android中添加监听回调接口的方法

    在Android中,我们经常会添加一些监听回调的接口供别的类来回调,比如自定义一个PopupWindow,需要让new这个PopupWindow的Activity来监听PopupWindow中的一些组 ...

随机推荐

  1. .net core中的分布式缓存和负载均衡

    通过减少生成内容所需的工作,缓存可以显著提高应用的性能和可伸缩性,缓存对不经常更改的数据效果最佳,缓存生成的数据副本的返回速度可以比从原始源返回更快.ASP.NET Core 支持多种不同的缓存,最简 ...

  2. 检查手机是否安装外置SD卡

    /** * 检测是否安装外置SD卡 * * @return */ public boolean checkSDcard() { StorageList list = new StorageList(t ...

  3. windows server 2016安装

    slmgr /skms kms.03k.org slmgr /ato slmgr /ipk WC2BQ-8NRM3-FDDYY-2BFGV-KHKQY kms服务器: https://03k.org/ ...

  4. asp.net上传图片到服务器

    ASP.NET的FileUpload控件可用于上传文件到服务器.HoverTreeTop新增了一个“阅图”功能,图片就是用FileUpload上传的.阅图功能查看:http://hovertree.c ...

  5. token回话保持,axios请求拦截和导航守卫以及token过期处理

    1:了解token:有时候大家又说token令牌.整个机制是前端第一次登陆发送请求,后端会根据前端的用户名和密码, 通过一些列的算法的到一个token令牌, 这个令牌是独一无二的,前端每次发送请求都需 ...

  6. 20170529计划---统计业务量并生成EXCEL通过邮件发送

    每个月都要统计这些业务量的东东,烦死了,赶紧通过python写一个来搞定吧,三天搞定吧,未完待续哈. 2017-5-29 19:50粗略地做了一个思维导图哈 终于第三天完成啦 #encoding=ut ...

  7. Numpy 数组属性

    Numpy 数组的维数称为秩(rank),一维数组的秩为 1 , 二维数组的秩为 2 , 以此类推:在Numpy中, 每一个线性的数组称为是一个轴(axis),也就是维度(dimensios).比如说 ...

  8. JSP 页面跳转的实现方法

    客户端跳转 1. 使用 href 超链接标记  <a href="new.jsp">跳转</a> 2. 使用表单提交完成跳转  <form actio ...

  9. godoc

    Godoc-一个Go代码文档化工具 Python - Docstring Java - javadoc

  10. SGD训练时收敛速度的变化研究。

    一个典型的SGD过程中,一个epoch内的一批样本的平均梯度与梯度方差,在下图中得到了展示. 无论什么样的网络结构,无论是哪一层网络的梯度,大体上都遵循下面这样的规律: 高信号/噪音比一段时间之后,信 ...