//此系列博文是《第一行Android代码》的学习笔记,如有错漏,欢迎指正!

  运用简单的布局知识,我们可以来尝试制作一个聊天界面。

一、制作 Nine-Patch 图片 :

  Nine-Patch图片是一种被特殊处理过的 png 图片,能够指定哪些区域可以被拉伸而哪些区域不可以。一般用来作为聊天信息的背景。在此我们先准备一张png图片。然后在 Android sdk 目录下有一个 tools 文件夹,在这个文件夹中找到 draw9patch.bat文件。 双击打开之后, 在导航栏点击 File→Open 9-patch将 msg.png加载进来。我们可以在图片的四个边框绘制一个个的小黑点, 在上边框和左边框绘制的部分就表示当图片需要拉伸时就拉伸黑点标记的区域, 在下边框和右边框绘制的部分则表示内容会被放置的区域。右侧是三种不同拉伸情况下的预览图:

  

  最后点击导航栏 File→Save 9-patch 把绘制好的图片进行保存,此时的文件名就是msg_left.9.png。同样,我们制作一张msg_right.9.png。

二、编写布局文件:  

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     android:background="#d8e0e8"
 6     android:orientation="vertical" >
 7     <ListView
 8         android:id="@+id/msg_list_view"
 9         android:layout_width="match_parent"
10         android:layout_height="0dp"
11         android:layout_weight="1"
12         android:divider="#0000" >
13     </ListView>
14     <LinearLayout
15         android:layout_width="match_parent"
16         android:layout_height="wrap_content" >
17         <EditText
18             android:id="@+id/input_text"
19             android:layout_width="0dp"
20             android:layout_height="wrap_content"
21             android:layout_weight="1"
22             android:hint="Type somthing here"
23             android:maxLines="2" />
24         <Button
25             android:id="@+id/send"
26             android:layout_width="wrap_content"
27             android:layout_height="wrap_content"
28             android:text="Send" />
29     </LinearLayout>
30 </LinearLayout>

View Code

  我们指定了一个ListView用来显示聊天内容,另外还有一个EditText和button。其中ListView 中用到了一个 android:divider属性,它可以指定 ListView 分隔线的颜色,这里#0000 表示将分隔线设为透明色。

三、编写Msg类:

  为了后续的操作,我们定义一个Msg类:

 1 public class Msg {
 2     public static final int TYPE_RECEIVED = 0;
 3     public static final int TYPE_SENT = 1;
 4     private String content;
 5     private int type;
 6     public Msg(String content, int type) {
 7         this.content = content;
 8         this.type = type;
 9     }
10     public String getContent() {
11         return content;
12     }
13     public int getType() {
14         return type;
15     }
16 }

View Code

  Msg 类中只有两个字段,content表示消息的内容,type 表示消息的类型。其中消息类型有两个值可选,TYPE_RECEIVED 表示这是一条收到的消息,TYPE_SENT 表示这是一条发出的消息。

四、编写ListView的子布局:

  新建 msg_item.xml:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:layout_width="match_parent"
 3     android:layout_height="match_parent"
 4     android:orientation="vertical"
 5     android:padding="10dp" >
 6     <LinearLayout
 7         android:id="@+id/left_layout"
 8         android:layout_width="wrap_content"
 9         android:layout_height="wrap_content"
10         android:layout_gravity="left"
11         android:background="@drawable/msg_left" >
12         <TextView
13             android:id="@+id/left_msg"
14             android:layout_width="wrap_content"
15             android:layout_height="wrap_content"
16             android:layout_gravity="center"
17             android:layout_margin="10dp"
18             android:textColor="#fff" />
19     </LinearLayout>
20     <LinearLayout
21         android:id="@+id/right_layout"
22         android:layout_width="wrap_content"
23         android:layout_height="wrap_content"
24         android:layout_gravity="right"
25         android:background="@drawable/msg_right" >
26         <TextView
27             android:id="@+id/right_msg"
28             android:layout_width="wrap_content"
29             android:layout_height="wrap_content"
30             android:layout_gravity="center"
31             android:layout_margin="10dp" />
32     </LinearLayout>
33 </LinearLayout>

View Code

  这里我们让收到的消息居左对齐,发出的消息居右对齐,并且分别使用 message_left.9.png和 message_right.9.png 作为背景图。这里我们让收到的消息和发出的消息都放在同一个布局里,在稍后在代码中我们根据消息的类型来决定隐藏和显示哪种消息。

五、创建 ListView的适配器类:

  同样,我们需要新建一个适配器类:

 1 public class MsgAdapter extends ArrayAdapter<Msg> {
 2     private int resourceId;
 3     public MsgAdapter(Context context, int textViewResourceId, List<Msg>
 4             objects) {
 5         super(context, textViewResourceId, objects);
 6         resourceId = textViewResourceId;
 7     }
 8     @Override
 9     public View getView(int position, View convertView, ViewGroup parent) {
10         Msg msg = getItem(position);
11         View view;
12         ViewHolder viewHolder;
13         if (convertView == null) {
14             view = LayoutInflater.from(getContext()).inflate(resourceId, null);
15             viewHolder = new ViewHolder();
16             viewHolder.leftLayout = (LinearLayout) view.findViewById(R.id.left_layout);
17             viewHolder.rightLayout = (LinearLayout) view.findViewById(R.id.right_layout);
18             viewHolder.leftMsg = (TextView) view.findViewById(R.id.left_msg);
19             viewHolder.rightMsg = (TextView) view.findViewById(R.id.right_msg);
20             view.setTag(viewHolder);
21         }
22         else {
23             view = convertView;
24             viewHolder = (ViewHolder) view.getTag();
25         } //提高ListView的效率
26
27         if (msg.getType() == Msg.TYPE_RECEIVED) {
28 // 如果是收到的消息,则显示左边的消息布局,将右边的消息布局隐藏
29             viewHolder.leftLayout.setVisibility(View.VISIBLE);
30             viewHolder.rightLayout.setVisibility(View.GONE);
31             viewHolder.leftMsg.setText(msg.getContent());
32         } else if(msg.getType() == Msg.TYPE_SENT) {
33 // 如果是发出的消息,则显示右边的消息布局,将左边的消息布局隐藏
34             viewHolder.rightLayout.setVisibility(View.VISIBLE);
35             viewHolder.leftLayout.setVisibility(View.GONE);
36             viewHolder.rightMsg.setText(msg.getContent());
37         }
38         return view;
39     }
40     class ViewHolder {
41         LinearLayout leftLayout;
42         LinearLayout rightLayout;
43         TextView leftMsg;
44         TextView rightMsg;
45     }
46 }

View Code

  代码中在 getView()方法中增加了对消息类型的判断。如果这条消息是收到的,则显示左边的消息布局,如果这条消息是发出的,则显示右边的消息布局。

六、添加主活动的逻辑:

 1 public class MainActivity extends AppCompatActivity {
 2     private ListView msgListView;
 3     private EditText inputText;
 4     private Button send;
 5     private MsgAdapter adapter;
 6     private List<Msg> msgList = new ArrayList<Msg>();
 7     private int index = 1;
 8     @Override
 9     protected void onCreate(Bundle savedInstanceState) {
10         super.onCreate(savedInstanceState);
11         //requestWindowFeature(Window.FEATURE_NO_TITLE);
12         setContentView(R.layout.activity_main);
13         initMsgs(); // 初始化消息数据
14         adapter = new MsgAdapter(MainActivity.this, R.layout.msg_item, msgList);
15         inputText = (EditText) findViewById(R.id.input_text);
16         send = (Button) findViewById(R.id.send);
17         msgListView = (ListView) findViewById(R.id.msg_list_view);
18         msgListView.setAdapter(adapter);
19         send.setOnClickListener(new View.OnClickListener() {
20             @Override
21             public void onClick(View v) {
22                 String content = inputText.getText().toString();
23                 if (!"".equals(content)) {//content内容不为空时
24                     index++;
25                     Msg msg = new Msg(content, index%2);
26                     msgList.add(msg);
27                     adapter.notifyDataSetChanged(); // 当有新消息时,刷新ListView中的显示
28                     msgListView.setSelection(msgList.size()); // 将ListView定位到最后一行
29                     inputText.setText(""); // 清空输入框中的内容
30                 }
31             }
32         });
33     }
34
35     private void initMsgs() {
36         Msg msg1 = new Msg("娘子?", Msg.TYPE_RECEIVED);
37         msgList.add(msg1);
38         Msg msg2 = new Msg("啊哈?", Msg.TYPE_SENT);
39         msgList.add(msg2);
40     }
41 }

View Code

  在 initMsgs()方法中我们先初始化了几条数据用于在 ListView 中显示。然后在发送按钮的点击事件里获取了 EditText中的内容, 如果内容不为空则创建出一个新的 Msg 对象, 并把它添加到 msgList列表中去。之后又调用了适配器的 notifyDataSetChanged()方法,用于通知列表的数据发生了变化,这样新增的一条消息才能够在 ListView 中显示。接着调用 ListView的 setSelection()方法将显示的数据定位到最后一行,以保证一定可以看得到最后发出的一条消息。最后调用 EditText的 setText()方法将输入的内容清空。另外,我们加上一个标志index,这样就能轮流发送和接受信息了。

  最后我们的程序运行如下:

  

  //End.

  

转载于:https://www.cnblogs.com/Vincent-Bryan/p/5391290.html

Android学习笔记(十二)——实战:制作一个聊天界面相关推荐

  1. Android 学习笔记(十二):安卓中的事件分发机制

    一.事件分发的对象是谁 答:点击事件(Touch事件) 定义 当用户触摸屏幕时(View或ViewGroup派生的控件),将产生点击事件.Touch事件的相关细节(发生触摸的位置.时间等)被封装成Mo ...

  2. 吴恩达《机器学习》学习笔记十二——机器学习系统

    吴恩达<机器学习>学习笔记十二--机器学习系统 一.设计机器学习系统的思想 1.快速实现+绘制学习曲线--寻找重点优化的方向 2.误差分析 3.数值估计 二.偏斜类问题(类别不均衡) 三. ...

  3. ROS学习笔记十二:使用roswtf

    ROS学习笔记十二:使用roswtf 在使用ROS过程中,roswtf工具可以为我们提供ROS系统是否正常工作的检查作用. 注意:在进行下列操作之前,请确保roscore没有运行. 检查ROS是否安装 ...

  4. Python语言入门这一篇就够了-学习笔记(十二万字)

    Python语言入门这一篇就够了-学习笔记(十二万字) 友情提示:先关注收藏,再查看,12万字保姆级 Python语言从入门到精通教程. 文章目录 Python语言入门这一篇就够了-学习笔记(十二万字 ...

  5. Polyworks脚本开发学习笔记(十二)-输出和读取文本文件

    Polyworks脚本开发学习笔记(十二)-输出和读取文本文件 Polyworks作为一个测量工具,将测量的数据方便的导出到文本文件则是一项必须的功能.在DATA_FILE这个命令下提供了很多子命令用 ...

  6. OpenCV学习笔记(十二)——图像分割与提取

    在图像处理的过程中,经常需要从图像中将前景对象作为目标图像分割或者提取出来.例如,在视频监控中,观测到的是固定背景下的视频内容,而我们对背景本身并无兴趣,感兴趣的是背景中出现的车辆.行人或者其他对象. ...

  7. 【转】 Pro Android学习笔记(二十):用户界面和控制(8):GridView和Spinner

    目录(?)[-] GridView Spinner GridView GridView是网格状布局,如图所示.在了解ListView后,很容易了解GridView.下面是例子的XML文件. <? ...

  8. 【转】Pro Android学习笔记(二五):用户界面和控制(13):LinearLayout和TableLayout...

    目录(?)[-] 布局Layout 线性布局LinearLayout 表格布局TableLayout 布局Layout Layout是容器,用于对所包含的view进行布局.layout是view的子类 ...

  9. 【现代机器人学】学习笔记十二:轮式移动机器人

    目录 轮式机器人类型 全向轮式机器人 建模 单个全向轮是怎么运动的 多个全向轮是如何带动底盘运动的 运动规划和反馈控制 非完整约束轮式移动机器人 建模 独轮车 差速驱动机器人 车型机器人 非完整移动机 ...

最新文章

  1. bat maven 一键打包1.0
  2. 美国国安局承包商被捕,被刑事指控盗窃机密
  3. Puppet之简单安装Nginx
  4. 成功部署SD-WAN策略应注意的几个事项—Vecloud微云
  5. 用了这么多年的泛型,你对它到底有多了解?
  6. 缓存服务器在Linux下的运用
  7. 嵌入式linux python移植过程_嵌入式linux项目开发(一)——BOA移植
  8. Python 中 3 个不可思议的返回
  9. Oracle数据库常用十一大操作指令
  10. 何小鹏退出UC浏览器母公司股东名单
  11. pyqt5下pushButton框保留用户历史输入
  12. TortoiseSVN 命令 (命令行执行工具)
  13. firewalls 查看防火墙状态_5条命令玩转Linux系统防火墙
  14. Outlook-没有自动回复-使用规则创建外出邮件
  15. 静候Google I/O 2014大会开幕
  16. 【网络相关】curl可以访问浏览器打不开,无法访问此网站,ERR_UNSAFE_PORT。10080端口
  17. 微信小程序前端备忘录记事本搜索功能
  18. 【Python】具有异常处理功能的计算BMI值的python程序
  19. android释放内存只有1GB,手机内存不够用?教你5秒删掉1G垃圾,提升速度!
  20. 什么品牌台灯最舒服?盘点2023最好的台灯品牌

热门文章

  1. Oracle的SGA与系统vm.nr_hugepages
  2. matlab矩形脉冲信号_通信数字信号处理基本知识
  3. 2018年终工作总结动态PPT模板
  4. 济南计算机中考分数,济南中考总分
  5. C#通过Expression实现 字符串转表达式 自定义计算体积参数
  6. 职工配偶提取住房公积金
  7. 思维导图by lrllrl
  8. 基于Unity编辑器开发技能编辑器(三)
  9. hackinglab-脚本关9——逗比的手机验证码
  10. 杭州师范大学c语言程序设计机试,杭州师范大学C语言试题第5套