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

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


  气泡聊天最终要的是素材,要用到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();
	}
}


  谢谢大家的支持!以前一直要大家留邮箱发代码实在太麻烦了,所以Shamoo把代码上传到资源。链接:点击打开链接

  需要一分资源分,大家评论一下那一分就还回来了,别恨我,哈哈~~

  

展开阅读全文

Git 实用技巧

11-24
这几年越来越多的开发团队使用了Git,掌握Git的使用已经越来越重要,已经是一个开发者必备的一项技能;但很多人在刚开始学习Git的时候会遇到很多疑问,比如之前使用过SVN的开发者想不通Git提交代码为什么需要先commit然后再去push,而不是一条命令一次性搞定; 更多的开发者对Git已经入门,不过在遇到一些代码冲突、需要恢复Git代码时候就不知所措,这个时候哪些对 Git掌握得比较好的少数人,就像团队中的神一样,在队友遇到 Git 相关的问题的时候用各种流利的操作来帮助队友于水火。 我去年刚加入新团队,发现一些同事对Git的常规操作没太大问题,但对Git的理解还是比较生疏,比如说分支和分支之间的关联关系、合并代码时候的冲突解决、提交代码前未拉取新代码导致冲突问题的处理等,我在协助处理这些问题的时候也记录各种问题的解决办法,希望整理后通过教程帮助到更多对Git操作进阶的开发者。 本期教程学习方法分为“掌握基础——稳步进阶——熟悉协作”三个层次。从掌握基础的 Git的推送和拉取开始,以案例进行演示,分析每一个步骤的操作方式和原理,从理解Git 工具的操作到学会代码存储结构、演示不同场景下Git遇到问题的不同处理方案。循序渐进让同学们掌握Git工具在团队协作中的整体协作流程。 在教程中会通过大量案例进行分析,案例会模拟在工作中遇到的问题,从最基础的代码提交和拉取、代码冲突解决、代码仓库的数据维护、Git服务端搭建等。为了让同学们容易理解,对Git简单易懂,文章中详细记录了详细的操作步骤,提供大量演示截图和解析。在教程的最后部分,会从提升团队整体效率的角度对Git工具进行讲解,包括规范操作、Gitlab的搭建、钩子事件的应用等。 为了让同学们可以利用碎片化时间来灵活学习,在教程文章中大程度降低了上下文的依赖,让大家可以在工作之余进行学习与实战,并同时掌握里面涉及的Git不常见操作的相关知识,理解Git工具在工作遇到的问题解决思路和方法,相信一定会对大家的前端技能进阶大有帮助。
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值