界面設置
activity_main
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/blue">
<TextView
android:id="@+id/textview_title_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="Magic"
android:gravity="center"
android:textColor="@color/white"/>
</LinearLayout>
<ListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/chat_background"
android:divider="@null">
</ListView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center">
<ImageView
android:id="@+id/image_face"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/eoj"/>
<Button
android:id="@+id/btn_left"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="發送"
android:layout_margin="5dp"
android:background="@drawable/btn_background"/>
<EditText
android:id="@+id/edittext"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_margin="5dp"
android:background="@drawable/btn_nomal"/>
<Button
android:id="@+id/btn_right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="發送"
android:layout_margin="5dp"
android:background="@drawable/btn_background"/>
</LinearLayout>
<GridView
android:id="@+id/grideview"
android:numColumns="4"
android:visibility="gone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#ffffff">
</GridView>
</LinearLayout>
msg_layout(左邊消息的佈局)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textview_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="週一 14:27"
android:gravity="center"
android:padding="10dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/image_head"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/baby1" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textview_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="管理員"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
android:background="@drawable/title_background"/>
<TextView
android:id="@+id/textview_nikename"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="暱稱"/>
</LinearLayout>
<TextView
android:id="@+id/textview_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="你好好好好好好呵護好好你好好好好好好"
android:layout_marginRight="50dp"
android:background="@mipmap/eng9"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
right_layout(右邊消息的佈局)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textview_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="週一 14:27"
android:gravity="center"
android:padding="10dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="right">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/textview_nikename"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:text="暱稱"/>
<TextView
android:id="@+id/textview_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="管理員"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
android:background="@drawable/title_background"/>
</LinearLayout>
<TextView
android:id="@+id/textview_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="你好好好好好好呵護好好你好好好好好好"
android:layout_marginLeft="50dp"
android:background="@mipmap/msg_right"/>
</LinearLayout>
<ImageView
android:id="@+id/image_head"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/photo1" />
</LinearLayout>
</LinearLayout>
image_layout(添加表情)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<ImageView
android:id="@+id/imageview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/dja"/>
</LinearLayout>
MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private EditText mEditText;
private Html.ImageGetter mImageGetter;
private ImageView mImageView;
private ListView mListView;
private List<ChatMessage> mData;
private MessageAdapter mAdapter;
private Button mBtnLeft;
private Button mBtnRight;
private LayoutInflater mInflater;
private String[] mFaceName={"dja","djc","djd","dje","djf","djg","djh","dji","djj","djk","djl","djm"};
private GridView mGrideView;
private FaceAdapter mFaceAdapter;
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEditText= (EditText) findViewById(R.id.edittext);
mImageView= (ImageView) findViewById(R.id.image_face);
mListView= (ListView) findViewById(R.id.listview);
mBtnLeft= (Button) findViewById(R.id.btn_left);
mBtnRight= (Button) findViewById(R.id.btn_right);
mTextView= (TextView) findViewById(R.id.textview_title_time);
mGrideView= (GridView) findViewById(R.id.grideview);
mImageView.setOnClickListener(this);
mBtnLeft.setOnClickListener(this);
mBtnRight.setOnClickListener(this);
mInflater=getLayoutInflater();
mImageGetter=new Html.ImageGetter(){
@Override
public Drawable getDrawable(String source) {
Drawable drawable=null;
if(source!=null){
Class clazz= R.mipmap.class;
try {
Field field=clazz.getDeclaredField(source);
int sourceId=field.getInt(clazz);
drawable=getResources().getDrawable(sourceId);
drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight());
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}else {
drawable=getResources().getDrawable(R.mipmap.ic_launcher);
drawable.setBounds(0,0,drawable.getIntrinsicWidth(),drawable.getIntrinsicHeight());
}
return drawable;
}
};
mData=new ArrayList<>();
mAdapter=new MessageAdapter(mInflater,mData,mImageGetter);
mListView.setAdapter(mAdapter);
mFaceAdapter=new FaceAdapter(getLayoutInflater());
mGrideView.setAdapter(mFaceAdapter);
mGrideView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Spanned spanned=Html.fromHtml("<img src='"+mFaceName[position]+"'/>",mImageGetter,null);
mEditText.getText().insert(mEditText.getSelectionStart(),spanned);
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.image_face:
if(mGrideView.getVisibility()==View.VISIBLE){
mGrideView.setVisibility(View.GONE);
}else{
mGrideView.setVisibility(View.VISIBLE);
}
break;
case R.id.btn_left:
ChatMessage message=new ChatMessage();
message.setHead(R.mipmap.baby1);
message.setTitle("管理員");
message.setNikeName("Magic");
message.setType(MessageAdapter.MESSAGE_LEFT);
message.setTime(System.currentTimeMillis());
message.setMessage(filterHtml(Html.toHtml(mEditText.getText())));
mData.add(message);
mAdapter.notifyDataSetChanged();//通知listview信息發生改變,需要刷新
mListView.setSelection(mData.size()-1);
mEditText.setText("");
break;
case R.id.btn_right:
ChatMessage message2=new ChatMessage();
message2.setHead(R.mipmap.photo1);
message2.setTitle("成員");
message2.setNikeName("Little Star");
message2.setType(MessageAdapter.MESSAGE_RIGHT);
message2.setTime(System.currentTimeMillis());
message2.setMessage(filterHtml(Html.toHtml(mEditText.getText())));
mData.add(message2);
mAdapter.notifyDataSetChanged();//通知listview信息發生改變,需要刷新
mListView.setSelection(mData.size()-1);
mEditText.setText("");
break;
default:
break;
}
}
//去掉EditText的下部空白部分
public String filterHtml(String str){
str= str.replaceAll("<(?!br|img)[^>]+>", "").trim();
return str;
}
}
ChatMessage
public class ChatMessage {
private String title;
private String nikeName;
private Long time;
private int head;
private String message;
private int type;
public ChatMessage(){
}
public ChatMessage(String title, String nikeName, int head, Long time, String message) {
this.title = title;
this.nikeName = nikeName;
this.head = head;
this.time = time;
this.message = message;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getNikeName() {
return nikeName;
}
public void setNikeName(String nikeName) {
this.nikeName = nikeName;
}
public Long getTime() {
return time;
}
public void setTime(Long time) {
this.time = time;
}
public int getHead() {
return head;
}
public void setHead(int head) {
this.head = head;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
FaceAdapter
public class FaceAdapter extends BaseAdapter {
private int[] mFaceData={R.mipmap.dja,R.mipmap.djc,R.mipmap.djd
,R.mipmap.dje,R.mipmap.djf,R.mipmap.djg,R.mipmap.djh,R.mipmap.dji,R.mipmap.djj,R.mipmap.djk,R.mipmap.djl,R.mipmap.djm};
private LayoutInflater mInflater;
public FaceAdapter(LayoutInflater mInflater) {
this.mInflater = mInflater;
}
@Override
public int getCount() {
return mFaceData.length;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder vh=null;
if(convertView==null){
vh=new ViewHolder();
convertView=mInflater.inflate(R.layout.image_layout,null);
vh.imageView= (ImageView) convertView.findViewById(R.id.imageview);
convertView.setTag(vh);
}
vh= (ViewHolder) convertView.getTag();
vh.imageView.setImageResource(mFaceData[position]);
return convertView;
}
class ViewHolder{
ImageView imageView;
}
}
MessageAdapter
public class MessageAdapter extends BaseAdapter {
private LayoutInflater mInflater;
private List<ChatMessage> mData;
private Html.ImageGetter mImageGetter;
private SimpleDateFormat mFormat;
public static final int MAX_TYPE=2;
public static final int MESSAGE_LEFT=0;
public static final int MESSAGE_RIGHT=1;
public MessageAdapter(LayoutInflater mInflater, List<ChatMessage> mData, Html.ImageGetter mImageGetter) {
this.mInflater = mInflater;
this.mData = mData;
this.mImageGetter = mImageGetter;
mFormat=new SimpleDateFormat("EEE HH:mm");
}
@Override
public int getItemViewType(int position) {
return mData.get(position).getType();
}
@Override
public int getViewTypeCount() {
return MAX_TYPE;
}
@Override
public int getCount() {
return mData.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder vh = null;
ViewHolderRight vh2 = null;
int type = getItemViewType(position);
if (convertView == null) {
switch (type) {
case MESSAGE_LEFT:
convertView = mInflater.inflate(R.layout.msg_layout, null);
vh = new ViewHolder();
vh.imageView_head = (ImageView) convertView.findViewById(R.id.image_head);
vh.textView_nikeName = (TextView) convertView.findViewById(R.id.textview_nikename);
vh.textView_title = (TextView) convertView.findViewById(R.id.textview_title);
vh.textView_time = (TextView) convertView.findViewById(R.id.textview_time);
vh.textView_message = (TextView) convertView.findViewById(R.id.textview_message);
convertView.setTag(vh);
break;
case MESSAGE_RIGHT:
convertView = mInflater.inflate(R.layout.right_layout, null);
vh2 = new ViewHolderRight();
vh2.imageView_head = (ImageView) convertView.findViewById(R.id.image_head);
vh2.textView_nikeName = (TextView) convertView.findViewById(R.id.textview_nikename);
vh2.textView_title = (TextView) convertView.findViewById(R.id.textview_title);
vh2.textView_time = (TextView) convertView.findViewById(R.id.textview_time);
vh2.textView_message = (TextView) convertView.findViewById(R.id.textview_message);
convertView.setTag(vh2);
break;
default:
break;
}
}
ChatMessage msg = mData.get(position);
switch (type) {
case MESSAGE_LEFT:
vh = (ViewHolder) convertView.getTag();
Spanned spanned = Html.fromHtml(msg.getMessage(), mImageGetter, null);
vh.textView_message.setText(spanned);
vh.textView_title.setText(msg.getTitle());
String time = mFormat.format(new Date(msg.getTime()));
vh.textView_time.setText(time);
vh.textView_nikeName.setText(msg.getNikeName());
vh.imageView_head.setImageResource(msg.getHead());
break;
case MESSAGE_RIGHT:
vh2= (ViewHolderRight) convertView.getTag();
Spanned spanned2 = Html.fromHtml(msg.getMessage(), mImageGetter, null);
vh2.textView_message.setText(spanned2);
vh2.textView_title.setText(msg.getTitle());
String time2 = mFormat.format(new Date(msg.getTime()));
vh2.textView_time.setText(time2);
vh2.textView_nikeName.setText(msg.getNikeName());
vh2.imageView_head.setImageResource(msg.getHead());
break;
default:
break;
}
return convertView;
}
class ViewHolder{
ImageView imageView_head;
TextView textView_nikeName;
TextView textView_title;
TextView textView_time;
TextView textView_message;
}
class ViewHolderRight{
ImageView imageView_head;
TextView textView_nikeName;
TextView textView_title;
TextView textView_time;
TextView textView_message;
}
}