Android仿微信气泡聊天界面设计

jopen 7年前

微信的气泡聊天是仿iPhone自带短信而设计出来的,不过感觉还不错可以尝试一下仿着微信的气泡聊天做一个Demo,给大家分享一下!效果图如下:

20130731232426859.png

  气泡聊天最终要的是素材,要用到9.png文件的素材,这样气泡会随着聊天内容的多少而改变气泡的大小且不失真。为了方便,我就直接在微信里面提取出来啦。


  聊天的内容是用ListView来显示的,将聊天的内容封装成一个ChatMsgEntity类的对象里面,然后交给自定义的ListView适配器将聊天内容显示出来。

  ChatMsgEntity.java比较简单,只是聊天的内容存储、设置和获取。

package com.example.school;    public class ChatMsgEntity {      private static final String TAG = ChatMsgEntity.class.getSimpleName();      //名字      private String name;      //日期      private String date;      //聊天内容      private String text;      //是否为对方发来的信息      private boolean isComMeg = true;        public String getName() {          return name;      }        public void setName(String name) {          this.name = name;      }        public String getDate() {          return date;      }        public void setDate(String date) {          this.date = date;      }        public String getText() {          return text;      }        public void setText(String text) {          this.text = text;      }        public boolean getMsgType() {          return isComMeg;      }        public void setMsgType(boolean isComMsg) {       isComMeg = isComMsg;      }        public ChatMsgEntity() {      }        public ChatMsgEntity(String name, String date, String text, boolean isComMsg) {          this.name = name;          this.date = date;          this.text = text;          this.isComMeg = isComMsg;      }  }
  显示ListView的适配器ChatMsgViewAdpater.java:
package com.example.school;    import android.R.integer;  import android.content.Context;  import android.database.DataSetObserver;    import android.util.Log;  import android.view.LayoutInflater;  import android.view.View;  import android.view.View.OnClickListener;  import android.view.View.OnLongClickListener;  import android.view.ViewGroup;    import android.widget.BaseAdapter;  import android.widget.CheckBox;  import android.widget.LinearLayout;  import android.widget.TextView;    import java.util.ArrayList;  import java.util.List;    public class ChatMsgViewAdapter extends BaseAdapter {      //ListView视图的内容由IMsgViewType决定   public static interface IMsgViewType   {    //对方发来的信息    int IMVT_COM_MSG = 0;    //自己发出的信息    int IMVT_TO_MSG = 1;   }         private static final String TAG = ChatMsgViewAdapter.class.getSimpleName();      private List<ChatMsgEntity> data;      private Context context;        private LayoutInflater mInflater;        public ChatMsgViewAdapter(Context context, List<ChatMsgEntity> data) {          this.context = context;          this.data = data;          mInflater = LayoutInflater.from(context);      }        //获取ListView的项个数      public int getCount() {          return data.size();      }        //获取项      public Object getItem(int position) {          return data.get(position);      }        //获取项的ID      public long getItemId(int position) {          return position;      }        //获取项的类型   public int getItemViewType(int position) {    // TODO Auto-generated method stub     ChatMsgEntity entity = data.get(position);          if (entity.getMsgType())     {      return IMsgViewType.IMVT_COM_MSG;     }else{      return IMsgViewType.IMVT_TO_MSG;     }        }     //获取项的类型数   public int getViewTypeCount() {    // TODO Auto-generated method stub    return 2;   }      //获取View      public View getView(int position, View convertView, ViewGroup parent) {              ChatMsgEntity entity = data.get(position);       boolean isComMsg = entity.getMsgType();               ViewHolder viewHolder = null;        if (convertView == null)       {          if (isComMsg)       {           //如果是对方发来的消息,则显示的是左气泡        convertView = mInflater.inflate(R.layout.chatting_item_msg_text_left, null);       }else{        //如果是自己发出的消息,则显示的是右气泡        convertView = mInflater.inflate(R.layout.chatting_item_msg_text_right, null);       }            viewHolder = new ViewHolder();       viewHolder.tvSendTime = (TextView) convertView.findViewById(R.id.tv_sendtime);       viewHolder.tvUserName = (TextView) convertView.findViewById(R.id.tv_username);       viewHolder.tvContent = (TextView) convertView.findViewById(R.id.tv_chatcontent);       viewHolder.isComMsg = isComMsg;              convertView.setTag(viewHolder);       }else{           viewHolder = (ViewHolder) convertView.getTag();       }       viewHolder.tvSendTime.setText(entity.getDate());       viewHolder.tvUserName.setText(entity.getName());       viewHolder.tvContent.setText(entity.getText());              return convertView;      }            //通过ViewHolder显示项的内容      static class ViewHolder {           public TextView tvSendTime;          public TextView tvUserName;          public TextView tvContent;          public boolean isComMsg = true;      }        }
  对方发来消息的显示布局chatting_item_msg_text_left.xml
<?xml version="1.0" encoding="utf-8"?>  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"       android:layout_width="fill_parent"       android:layout_height="wrap_content"       android:orientation="vertical"       android:padding="6dp">       <LinearLayout           android:layout_width="fill_parent"           android:layout_height="wrap_content"           android:orientation="vertical"            android:gravity="center_horizontal">           <TextView               android:id="@+id/tv_sendtime"               android:layout_width="wrap_content"               android:layout_height="wrap_content"               style="@style/chat_text_date_style"/>       </LinearLayout>       <RelativeLayout           android:layout_width="fill_parent"           android:layout_height="wrap_content"           android:layout_marginTop="5dp" >             <ImageView                android:id="@+id/iv_userhead"                android:layout_width="wrap_content"               android:layout_height="wrap_content"               android:focusable="false"                android:layout_alignParentLeft="true"                      android:layout_alignParentTop="true"                android:background="@drawable/mini_avatar_shadow"/>       <TextView                android:id="@+id/tv_chatcontent"                android:layout_toRightOf="@id/iv_userhead"               android:layout_marginLeft="10dp"               android:layout_width="wrap_content"               android:layout_height="wrap_content"               android:background="@drawable/chatfrom_bg"               style="@style/chat_content_date_style"/>                  <TextView                android:id="@+id/tv_username"                android:layout_width="wrap_content"               android:layout_height="wrap_content"               android:layout_below="@id/iv_userhead"               android:layout_alignParentLeft="true"               android:layout_toLeftOf="@id/tv_chatcontent"               style="@style/chat_text_name_style"/>       </RelativeLayout>  </LinearLayout>

  chatting_item_msg_text_right.xml和上面差不多,只是气泡和头像的方向在右边,就不贴代码了。

  

  主界面的布局chat.xml

    <?xml version="1.0" encoding="utf-8"?>        <RelativeLayout            xmlns:android="http://schemas.android.com/apk/res/android"            android:layout_width="fill_parent"            android:layout_height="fill_parent"            android:background="#f0f0e0" >            <RelativeLayout                android:id="@+id/rl_layout"                 android:layout_width="fill_parent"                android:layout_height="wrap_content"                android:background="@drawable/title" >                <Button                     android:id="@+id/btn_back"                     android:gravity="center_vertical"                     android:layout_marginLeft="5dp"                     android:paddingLeft="18dp"                     android:textSize="18.0sp"                     android:textColor="#ffffff"                      android:background="@drawable/selector_btn_back"                     android:layout_width="70dp"                     android:layout_height="wrap_content"                     android:text="@string/back" />                <TextView                    android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:text="@string/school_title_name"                    android:layout_centerInParent="true"                    style="@style/my_txt"/>                <ImageView                     android:layout_width="wrap_content"                    android:layout_height="wrap_content"                    android:background="@drawable/campus_info"                    android:layout_centerVertical="true"                    android:layout_alignParentRight="true"                    android:layout_marginRight="15dp"/>                </RelativeLayout>            <RelativeLayout                android:id="@+id/rl_bottom"                android:layout_width="fill_parent"                android:layout_height="wrap_content"                android:layout_alignParentBottom="true"                android:background="@drawable/layout_bg1" >                <Button                    android:id="@+id/btn_send"                    android:layout_width="60dp"                    android:layout_height="40dp"                    android:layout_alignParentRight="true"                    android:layout_marginRight="10dp"                    android:layout_centerVertical="true"                    android:text="@string/send" />                <EditText                    android:id="@+id/et_sendmessage"                    android:layout_width="fill_parent"                    android:layout_height="40dp"                    android:layout_toLeftOf="@id/btn_send"                    android:layout_marginLeft="10dp"                    android:layout_marginRight="10dp"                    android:background="@drawable/edittext1"                    android:layout_centerVertical="true"                    android:singleLine="true"                    android:textSize="18sp"/>            </RelativeLayout>            <ListView                android:id="@+id/listview"                android:layout_below="@id/rl_layout"                android:layout_above="@id/rl_bottom"                android:layout_width="fill_parent"                android:layout_height="fill_parent"                android:layout_marginLeft="10.0dip"                 android:layout_marginTop="10.0dip"                 android:layout_marginRight="10.0dip"                android:divider="@null"                android:dividerHeight="5dp"                android:scrollbars="none"                android:cacheColorHint="#00000000"/>        </RelativeLayout>  
  ChatActivity.java
    package com.example.chat;                import java.util.ArrayList;        import java.util.Calendar;        import java.util.List;                import com.example.school.R;                import android.os.Bundle;        import android.app.Activity;        import android.content.Intent;        import android.view.KeyEvent;        import android.view.Menu;        import android.view.View;        import android.view.Window;        import android.view.View.OnClickListener;        import android.widget.AdapterView;        import android.widget.AdapterView.OnItemClickListener;        import android.widget.Button;        import android.widget.EditText;        import android.widget.ListView;        import android.widget.TextView;                public class ChatActivity extends Activity implements OnClickListener {            private Button mBtnSend;            private Button mBtnBack;            private EditText mEditTextContent;            //聊天内容的适配器            private ChatMsgViewAdapter mAdapter;            private ListView mListView;            //聊天的内容            private List<ChatMsgEntity> mDataArrays = new ArrayList<ChatMsgEntity>();                        @Override            public void onCreate(Bundle savedInstanceState) {                super.onCreate(savedInstanceState);                requestWindowFeature(Window.FEATURE_NO_TITLE);// 去掉标题栏                setContentView(R.layout.chat);                initView();                initData();            }                        //初始化视图            private void initView() {                mListView = (ListView) findViewById(R.id.listview);                mBtnBack = (Button) findViewById(R.id.btn_back);                mBtnBack.setOnClickListener(this);                mBtnSend = (Button) findViewById(R.id.btn_send);                mBtnSend.setOnClickListener(this);                mEditTextContent = (EditText) findViewById(R.id.et_sendmessage);            }                    private String[] msgArray = new String[]{"  孩子们,要好好学习,天天向上!要好好听课,不要翘课!不要挂科,多拿奖学金!三等奖学金的争取拿二等,二等的争取拿一等,一等的争取拿励志!",                     "姚妈妈还有什么吩咐...",                     "还有,明天早上记得跑操啊,不来的就扣德育分!",                     "德育分是什么?扣了会怎么样?",                     "德育分会影响奖学金评比,严重的话,会影响毕业",                     "哇!学院那么不人道?",                    "你要是你不听话,我当场让你不能毕业!",                     "姚妈妈,我知错了(- -我错在哪了...)"};                    private String[]dataArray = new String[]{"2012-09-01 18:00", "2012-09-01 18:10",                     "2012-09-01 18:11", "2012-09-01 18:20",                     "2012-09-01 18:30", "2012-09-01 18:35",                     "2012-09-01 18:40", "2012-09-01 18:50"};            private final static int COUNT = 8;                        //初始化要显示的数据            private void initData() {                for(int i = 0; i < COUNT; i++) {                    ChatMsgEntity entity = new ChatMsgEntity();                    entity.setDate(dataArray[i]);                    if (i % 2 == 0)                    {                        entity.setName("姚妈妈");                        entity.setMsgType(true);                    }else{                        entity.setName("Shamoo");                        entity.setMsgType(false);                    }                                        entity.setText(msgArray[i]);                    mDataArrays.add(entity);                }                mAdapter = new ChatMsgViewAdapter(this, mDataArrays);                mListView.setAdapter(mAdapter);            }                        public void onClick(View view) {                // TODO Auto-generated method stub                switch(view.getId()) {                case R.id.btn_back:                    back();                    break;                case R.id.btn_send:                    send();                    break;                }            }                    private void send()            {                String contString = mEditTextContent.getText().toString();                if (contString.length() > 0)                {                    ChatMsgEntity entity = new ChatMsgEntity();                    entity.setDate(getDate());                    entity.setName("");                    entity.setMsgType(false);                    entity.setText(contString);                    mDataArrays.add(entity);                    mAdapter.notifyDataSetChanged();                    mEditTextContent.setText("");                    mListView.setSelection(mListView.getCount() - 1);                }            }                        //获取日期            private String getDate() {                Calendar c = Calendar.getInstance();                String year = String.valueOf(c.get(Calendar.YEAR));                String month = String.valueOf(c.get(Calendar.MONTH));                String day = String.valueOf(c.get(Calendar.DAY_OF_MONTH) + 1);                String hour = String.valueOf(c.get(Calendar.HOUR_OF_DAY));                String mins = String.valueOf(c.get(Calendar.MINUTE));                StringBuffer sbBuffer = new StringBuffer();                sbBuffer.append(year + "-" + month + "-" + day + " " + hour + ":" + mins);                 return sbBuffer.toString();            }            public boolean onKeyDown(int keyCode, KeyEvent event) {                back();                return true;            }                        private void back() {                finish();            }        }  

来自:http://blog.csdn.net/stephenzcl/article/details/9674385