会话详情页


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. Eclipse oxygen 版本汉化教程

    Eclipse oxygen 版本汉化步骤如下: 第一步:打开Eclipse 第二步:浏览器打开网址 http://www.eclipse.org/babel/downloads.php 1.复制对应 ...

  2. angular中如果几个请求相互不依赖,但是请求结果需要一起处理,可以使用

  3. svg绘制一个简单地饼图

    一个简单地svg绘制饼图的demo,代码如下 <!DOCTYPE html> <html> <head> <meta charset="UTF-8& ...

  4. UI交互设计关键词:情感化设计与心理

    情感化设计,一定有一个关键词.情感,是指人对周围事物和自身以及对自己行为的态度,它是人对客观事物的一种特殊的反映形式,是主体对外界刺激给予肯定或否定的心理反应,也是对客观事物是否符合自己需要的态度或体 ...

  5. mysql 数据库的备份和还原

    1. 逻辑备份 (和存储引擎无关) mysqldump -uroot -p schoolDB TSubject > /mysqlbackup/schoolDB.TSubject.sql  (备份 ...

  6. APP优化(转载)

  7. int main(int argc, char** argv) 以及CommandLineParser

    参考链接: 关于int main(int argc, char** argv) http://blog.csdn.net/liuhuiyi/article/details/8239303 http:/ ...

  8. 关于阿里云ECS服务器修改远程端口的一点总结

    般修改公司的远程服务器的登录端口号分为两大步: 一.修改注册表中的两个地方的端口号:(注册表打开命令:regedit) [HKEY_LOCAL_MACHINE\SYSTEM\CurrentContro ...

  9. django中的modelform和modelfoemset

    一. ModelForm ModelForm是根据Model来定制的Form 二. ModelForm的创建 from django import forms from app import mode ...

  10. 渗透测试的理论部分4——开放式Web应用程序安全项目

    开放式Web应用程序安全项目(Open Web Application Security Project OWASP) 定期退出Top 10 project(排名前十的安全隐患防守规则) 公开了编写安 ...