Android仿微信聊天界面布局

来源:互联网 发布:用java写九九乘法表 编辑:程序博客网 时间:2024/05/20 16:13

           在Android开发中,很多时候都需要接入即时通信功能,那么就需要一个聊天的布局界面,下面就来给大家介绍一下,怎么来布局聊天界面。

        1.第一步首先是制作9.patch图片,这个在Android  sdk 目录下tools文件,找到draw9patch.bat文件双击打开。这是一个专门用来处理安卓里面图像的小工具,你可以对图片指定拉伸的效果,具体教程可以百度,很简单的。

          2.编写主界面

[html] view plain copy
print?
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:background="#d8e0e8"   
  6.     android:orientation="vertical">  
  7.       
  8.     <ListView   
  9.         android:id="@+id/msg_list_view"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="0dp"  
  12.         android:layout_weight="1"  
  13.         android:divider="#0000">  
  14.           
  15.     </ListView>  
  16.   
  17.       
  18.    <LinearLayout   
  19.        android:layout_width="match_parent"  
  20.        android:layout_height="wrap_content">  
  21.          
  22.        <EditText   
  23.            android:id="@+id/input_text"  
  24.            android:layout_width="0dp"  
  25.            android:layout_height="wrap_content"  
  26.            android:layout_weight="1"  
  27.            android:hint="Typ something in here"  
  28.            android:maxLines="2"/>  
  29.          
  30.        <Button   
  31.            android:id="@+id/send"  
  32.            android:layout_width="wrap_content"  
  33.            android:layout_height="wrap_content"  
  34.            android:text="send"/>  
  35.          
  36.     </LinearLayout>  
  37. </LinearLayout>  
主界面里我们可以看到有一个ListView用于加载信息,线性布局进行嵌套,里层里有一个编辑框和一个按钮。下图就是布局初步效果图:

3.编写ListView子项布局,新建一个布局文件

[html] view plain copy
print?
  1. <span style="font-size:12px;"><?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:orientation="vertical"   
  6.     android:padding="10dp">  
  7.       
  8.     <LinearLayout   
  9.         android:id="@+id/left_layout"  
  10.         android:layout_width="wrap_content"  
  11.         android:layout_height="wrap_content"  
  12.         android:layout_gravity="left"  
  13.         android:background="@drawable/message_left">  
  14.           
  15.         <TextView   
  16.             android:id="@+id/left_msg"  
  17.             android:layout_width="wrap_content"  
  18.             android:layout_height="wrap_content"  
  19.             android:gravity="center"  
  20.             android:layout_margin="10dp"  
  21.             android:textColor="#fff"/>  
  22.           
  23.     </LinearLayout>  
  24.   
  25.     <LinearLayout   
  26.         android:id="@+id/right_Layout"  
  27.         android:layout_width="wrap_content"  
  28.         android:layout_height="wrap_content"  
  29.         android:layout_gravity="right"  
  30.         android:background="@drawable/message_right"  
  31.         >  
  32.           
  33.         <TextView   
  34.             android:id="@+id/right_msg"  
  35.             android:layout_width="wrap_content"  
  36.             android:layout_height="wrap_content"  
  37.             android:layout_gravity="center"  
  38.             android:layout_margin="10dp"/>   
  39.           
  40.     </LinearLayout>  
  41. </LinearLayout></span>  
       这里最外层是线性布局,里边嵌套两个线性布局。这两个布局分别是给消息发送界面和消息接收界面。后面可以通过设置布局的显示和隐藏属性来显示我们需要的消息。这也是最近学习布局收获的一点,光学课本上的单个布局的特点没有应用到实际的应用里边,很难自己想象原来布局可以这样灵活。

效果图如下:

3.完成MainActivity.Java,写好布局文件以后开始写代码,这里需要大概写的几点是:

1.定义消息类的实体类Msg

public class Msg{  }

里面需要设置消息的类型:发送,接收,内容。

2.ListView适配器的建立

首先它需要继承ArrayAdapter,将泛型指定为Msg类。

这里运用到了很多书上说的ListView的优化,通过if_else判断,如果convertView为空就重新初始化加载布局,这时就需要加载很多东西,如果convertView不为空时,说明它之前有缓存,可以重用,那我们直接调用它,就大大提高了运行的效率。

还有通过创建ViewHolder这个内部类,可以对控件的实例进行缓存。当convertView为空时。将控件的实例存在ViewHolder里,调用setTag()方法,将ViewHolder对象存储在View里。当ViewHolder不为空时,调用View的setTag()方法,重新取出ViewHolder。这样就不用每次调用findViewById()方法获取控件。

3.收发消息布局的隐藏和显示

通过判断消息的类型,进行设置显示和隐藏消息。

if(msg.getType()==Msg.RECEIVED){
                //如果是收到的消息,则显示左边消息布局,将右边消息布局隐藏
                viewHolder.leftLayout.setVisibility(View.VISIBLE);
                viewHolder.rightLayout.setVisibility(View.GONE);
                viewHolder.leftMsg.setText(msg.getContent());
            }else if(msg.getType()==Msg.SENT){
                //如果是发出去的消息,显示右边布局的消息布局,将左边的消息布局隐藏
                viewHolder.rightLayout.setVisibility(View.VISIBLE);
                viewHolder.leftLayout.setVisibility(View.GONE);
                viewHolder.rightMsg.setText(msg.getContent());
            }

4.初始化消息initMsg()

写几条消息测试一下首发消息是否正确。

5.给按钮send设置监听器事件

这里用到的是send.setOnClickListener(new OnClickListener(){   },这一看就是匿名内部类的方式。


这里只是大体说了一下编写的大概内容,具体的可以看下面源代码:

[java] view plain copy
print?
  1. package com.example.chat_layout;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5. import android.R.string;  
  6. import android.os.Bundle;  
  7. import android.app.Activity;  
  8. import android.content.Context;  
  9. import android.view.LayoutInflater;  
  10. import android.view.Menu;  
  11. import android.view.View;  
  12. import android.view.View.OnClickListener;  
  13. import android.view.ViewGroup;  
  14. import android.view.Window;  
  15. import android.widget.Adapter;  
  16. import android.widget.ArrayAdapter;  
  17. import android.widget.Button;  
  18. import android.widget.EditText;  
  19. import android.widget.LinearLayout;  
  20. import android.widget.ListView;  
  21. import android.widget.TextView;  
  22.   
  23. public class MainActivity extends Activity {  
  24.      /*
  25.    Created byYWHon 2017/2/26.
  26. */ 
  27.     private ListView msgListView;  
  28.       
  29.     private EditText inputText;  
  30.   
  31.     private Button send;  
  32.       
  33.     private MsgAdapter adapter;  
  34.       
  35.     private List<Msg> msgList = new ArrayList<Msg>();  
  36.       
  37.     @Override  
  38.     protected void onCreate(Bundle savedInstanceState) {  
  39.         super.onCreate(savedInstanceState);  
  40.         requestWindowFeature(Window.FEATURE_NO_TITLE);//设置窗口没有标题栏  
  41.         setContentView(R.layout.activity_main);  
  42.         initMsg();  
  43.         adapter = new MsgAdapter(MainActivity.this, R.layout.msg_item, msgList);  
  44.         inputText = (EditText) findViewById(R.id.input_text);  
  45.         send = (Button) findViewById(R.id.send);  
  46.         msgListView = (ListView) findViewById(R.id.msg_list_view);  
  47.         msgListView.setAdapter(adapter);  
  48.         send.setOnClickListener(new OnClickListener(){  
  49.   
  50.             @Override  
  51.             public void onClick(View v) {  
  52.                 String content = inputText.getText().toString();  
  53.                 if(!"".equals(content)){  
  54.                     Msg msg = new Msg(content, Msg.SENT);  
  55.                     msgList.add(msg);  
  56.                     adapter.notifyDataSetChanged();//有新消息时,刷新ListView中的显示  
  57.                     msgListView.setSelection(msgList.size());//将ListView定位到最后一行  
  58.                     inputText.setText("");//清空输入框的内容  
  59.                 }  
  60.             }  
  61.               
  62.         });  
  63.     }  
  64.   
  65.     private void initMsg() {  
  66.         Msg msg1 = new Msg("I miss you!",Msg.RECEIVED);  
  67.         msgList.add(msg1);  
  68.           
  69.         Msg msg2 = new Msg("I miss you,too!",Msg.SENT);  
  70.         msgList.add(msg2);  
  71.           
  72.         Msg msg3 = new Msg("I will come back soon!",Msg.RECEIVED);  
  73.         msgList.add(msg3);  
  74.           
  75.     }  
  76.   
  77.     @Override  
  78.     public boolean onCreateOptionsMenu(Menu menu) {  
  79.         // Inflate the menu; this adds items to the action bar if it is present.  
  80.         getMenuInflater().inflate(R.menu.main, menu);  
  81.         return true;  
  82.     }  
  83.       
  84.       
  85.       
  86.     public class Msg{  
  87.           
  88.         public static final int RECEIVED = 0;//收到一条消息  
  89.           
  90.         public static final int SENT = 1;//发出一条消息  
  91.           
  92.         private String  content;//消息的内容  
  93.           
  94.         private int type;//消息的类型  
  95.           
  96.         public  Msg(String content,int type){  
  97.             this.content = content;  
  98.             this.type = type;  
  99.         }  
  100.           
  101.         public String getContent(){  
  102.             return content;  
  103.         }  
  104.           
  105.         public int getType(){  
  106.             return type;  
  107.         }  
  108.     }  
  109.       
  110.     public class MsgAdapter extends ArrayAdapter<Msg>{  
  111.         private int resourceId;  
  112.   
  113.         public MsgAdapter(Context context, int textViewresourceId, List<Msg> objects) {  
  114.             super(context, textViewresourceId, objects);  
  115.             resourceId = textViewresourceId;  
  116.         }  
  117.           
  118.         @Override  
  119.         public View getView(int position, View convertView, ViewGroup parent) {  
  120.             Msg msg = getItem(position);  
  121.             View view;  
  122.             ViewHolder viewHolder;  
  123.               
  124.             if(convertView == null){  
  125.             view = LayoutInflater.from(getContext()).inflate(resourceId, null);  
  126.             viewHolder = new ViewHolder();  
  127.             viewHolder.leftLayout = (LinearLayout)view.findViewById(R.id.left_layout);  
  128.             viewHolder.rightLayout = (LinearLayout)view.findViewById(R.id.right_Layout);  
  129.             viewHolder.leftMsg = (TextView)view.findViewById(R.id.left_msg);  
  130.             viewHolder.rightMsg = (TextView)view.findViewById(R.id.right_msg);  
  131.             view.setTag(viewHolder);  
  132.             }else{  
  133.                 view = convertView;  
  134.                 viewHolder = (ViewHolder) view.getTag();  
  135.             }  
  136.               
  137.             if(msg.getType()==Msg.RECEIVED){  
  138.                 //如果是收到的消息,则显示左边消息布局,将右边消息布局隐藏  
  139.                 viewHolder.leftLayout.setVisibility(View.VISIBLE);  
  140.                 viewHolder.rightLayout.setVisibility(View.GONE);  
  141.                 viewHolder.leftMsg.setText(msg.getContent());  
  142.             }else if(msg.getType()==Msg.SENT){  
  143.                 //如果是发出去的消息,显示右边布局的消息布局,将左边的消息布局隐藏  
  144.                 viewHolder.rightLayout.setVisibility(View.VISIBLE);  
  145.                 viewHolder.leftLayout.setVisibility(View.GONE);  
  146.                 viewHolder.rightMsg.setText(msg.getContent());  
  147.             }  
  148.             return view;  
  149.         }  
  150.           
  151.         class ViewHolder{  
  152.             LinearLayout leftLayout;  
  153.             LinearLayout rightLayout;  
  154.             TextView leftMsg;  
  155.             TextView rightMsg;  
  156.         }  
  157.     }  
  158.       
  159. }  
           最后效果图:可以看到除了程序中初始化的3条消息,ok这是通过底下编辑器输入的,看一看到实现了聊天对话框的基本内容和要求。




1 0
原创粉丝点击