Android 聊天表情输入、表情翻页带效果、下拉刷新聊天记录

经过一个星期的折腾,最终做完了这个Android 聊天表情输入、表情翻页带效果、下拉刷新聊天记录。这仅仅是一个单独聊天表情的输入,以及聊天的效果实现。由于我没有写server,所以没有两方聊天的效果。

主要是聊天中表情的选择。发送。

表情翻页带有不同的效果。

我在主要代码中都写了凝视。以下看代码实现。附上本文源代码,代码较多。

下载地址:点击

一、先看实现的效果图


二、调用接口以及设置MainActivity

package com.example.activity;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import com.org.adapter.FaceAdapter;
import com.org.adapter.FacePageAdeapter;
import com.org.adapter.MessageAdapter;
import com.org.util.MyApplication;
import com.org.util.SharePreferenceUtil;
import com.org.view.CirclePageIndicator;
import com.org.view.JazzyViewPager;
import com.org.view.JazzyViewPager.TransitionEffect;
import com.org.xlistview.MsgListView;
import com.org.xlistview.MsgListView.IXListViewListener;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.drawable.ColorDrawable;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.text.Editable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextWatcher;
import android.text.style.ImageSpan;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.View.OnTouchListener;
import android.view.ViewGroup.LayoutParams;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;

public class MainActivity extends Activity 
implements 
OnClickListener,
OnTouchListener,
IXListViewListener{

	private Button sendBtn;
	private ImageButton faceBtn;
	private LinearLayout faceLinearLayout;
	private EditText msgEt;
	private InputMethodManager mInputMethodManager;
	private MessageAdapter mMessageAdapter;
	private JazzyViewPager faceViewPager;
	private MsgListView mMsgListView;
	private MyApplication mApplication;
	private SharePreferenceUtil mSpUtil;
	private WindowManager.LayoutParams mLayoutParams;
	private List<String> mListFaceKeys;
	private int currentPage = 0;
	private boolean isFaceShow = false;
	private static int MsgPagerNum;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.chat_main);
		initData();
		initUI();
		initFacePage();
	}
	
	private void initData() {
		mApplication = MyApplication.getInstance();
		//SharePreference存储类
		mSpUtil = new SharePreferenceUtil(this, "message_save");
		//初始化消息列表适配器
		mMessageAdapter = new MessageAdapter(this, initMsgData());
		
		//载入表情的列表
		Set<String> keySet = MyApplication.getInstance().getFaceMap().keySet();
		mListFaceKeys = new ArrayList<String>();
		mListFaceKeys.addAll(keySet);
		MsgPagerNum = 0;
	}
	private void initUI() {
		mInputMethodManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
		//获取窗体触摸操作
		mLayoutParams = getWindow().getAttributes();
		
		mMsgListView = (MsgListView) findViewById(R.id.msg_listView);
		// 触摸ListView隐藏表情和输入法
		mMsgListView.setOnTouchListener(this);
		mMsgListView.setPullLoadEnable(false);
		mMsgListView.setXListViewListener(this);
		mMsgListView.setAdapter(mMessageAdapter);
		mMsgListView.setSelection(mMessageAdapter.getCount() - 1);
		
		sendBtn = (Button) findViewById(R.id.send_btn);
		faceBtn = (ImageButton) findViewById(R.id.face_btn);
		faceLinearLayout = (LinearLayout) findViewById(R.id.face_ll);
		msgEt = (EditText) findViewById(R.id.msg_et);
		faceLinearLayout = (LinearLayout) findViewById(R.id.face_ll);
		faceViewPager = (JazzyViewPager) findViewById(R.id.face_pager);
		
		//标题栏控件
		TextView mTitle = (TextView) findViewById(R.id.ivTitleName);
		mTitle.setText("默默笙箫");
		TextView mTitleLeftBtn = (TextView) findViewById(R.id.ivTitleBtnLeft);
		mTitleLeftBtn.setVisibility(View.VISIBLE);
		mTitleLeftBtn.setOnClickListener(this);
		
		//输入框的触摸监听的绑定
		msgEt.setOnTouchListener(this);
		msgEt.setOnKeyListener(new OnKeyListener() {

			@Override
			public boolean onKey(View v, int keyCode, KeyEvent event) {
				if (keyCode == KeyEvent.KEYCODE_BACK) {
					if (mLayoutParams.softInputMode == WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
							|| isFaceShow) {
						faceLinearLayout.setVisibility(View.GONE);
						isFaceShow = false;
						// imm.showSoftInput(msgEt, 0);
						return true;
					}
				}
				return false;
			}
		});
		
		//输入框的实时输入长度的监听
		msgEt.addTextChangedListener(new TextWatcher() {
			@Override
			public void onTextChanged(CharSequence s, int start, int before,
					int count) {
			}

			@Override
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
			}

			@Override
			public void afterTextChanged(Editable s) {
				if (s.length() > 0) {
					sendBtn.setEnabled(true);
				} else {
					sendBtn.setEnabled(false);
				}
			}
		});
		
		faceBtn.setOnClickListener(this);
		sendBtn.setOnClickListener(this);
	}
	
	@Override
	public boolean onTouch(View v, MotionEvent event) {
		switch (v.getId()) {
		case R.id.msg_listView:   //ListView触摸实现
			mInputMethodManager.hideSoftInputFromWindow(msgEt.getWindowToken(), 0);
			faceLinearLayout.setVisibility(View.GONE);
			isFaceShow = false;
			break;
		case R.id.msg_et:    //输入框触摸实现
			mInputMethodManager.showSoftInput(msgEt, 0);
			faceLinearLayout.setVisibility(View.GONE);
			isFaceShow = false;
			break;

		default:
			break;
		}
		return false;
	}
	
	//历史数据。在開始时显示
	private List<MessageItem> initMsgData() {
		List<MessageItem> msgList = new ArrayList<MessageItem>();// 消息对象数组
		
		MessageItem item = new MessageItem(MessageItem.MESSAGE_TYPE_TEXT,
				mSpUtil.getNick(), System.currentTimeMillis(), "历史消息",
				mSpUtil.getHeadIcon(), false, 0);
		msgList.add(item);
		return msgList;

	}
	
	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.face_btn:  //弹出表情
			if (!isFaceShow) {
				mInputMethodManager.hideSoftInputFromWindow(msgEt.getWindowToken(), 0);
				try {
					Thread.sleep(80);// 解决此时会黑一下屏幕的问题
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				faceLinearLayout.setVisibility(View.VISIBLE);
				isFaceShow = true;
			} else {
				faceLinearLayout.setVisibility(View.GONE);
				isFaceShow = false;
			}
			break;
		case R.id.send_btn:// 发送消息
			String msg = msgEt.getText().toString();
			MessageItem item = new MessageItem(MessageItem.MESSAGE_TYPE_TEXT,
					mSpUtil.getNick(), System.currentTimeMillis(), msg,
					mSpUtil.getHeadIcon(), false, 0);
			mMessageAdapter.upDateMsg(item);
			
			mMsgListView.setSelection(mMessageAdapter.getCount() - 1);
			msgEt.setText("");
			break;
		case R.id.ivTitleBtnLeft:
			finish();
			break;
//		case R.id.ivTitleBtnRigh:
//			break;
		default:
			break;
		}
		
	}
	
	//载入表情。以及设置翻页效果
	private void initFacePage() {
		List<View> lv = new ArrayList<View>();
		for (int i = 0; i < MyApplication.NUM_PAGE; ++i)
			lv.add(getGridView(i));
		FacePageAdeapter adapter = new FacePageAdeapter(lv, faceViewPager);
		faceViewPager.setAdapter(adapter);
		faceViewPager.setCurrentItem(currentPage);
		faceViewPager.setTransitionEffect(mEffects[mSpUtil.getFaceEffect()]);
		CirclePageIndicator indicator = (CirclePageIndicator) findViewById(R.id.indicator);
		indicator.setViewPager(faceViewPager);
		adapter.notifyDataSetChanged();
		faceLinearLayout.setVisibility(View.GONE);
		indicator.setOnPageChangeListener(new OnPageChangeListener() {

			@Override
			public void onPageSelected(int arg0) {
				currentPage = arg0;
			}

			@Override
			public void onPageScrolled(int arg0, float arg1, int arg2) {
				// do nothing
			}

			@Override
			public void onPageScrollStateChanged(int arg0) {
				// do nothing
			}
		});

	}
	
	//表情表格控件放置。设置背景
	private GridView getGridView(int i) {
		GridView gv = new GridView(this);
		gv.setNumColumns(7);      //一行显示7个表情
		gv.setSelector(new ColorDrawable(Color.TRANSPARENT));// 屏蔽GridView默认点击效果
		gv.setBackgroundColor(Color.TRANSPARENT);
		gv.setCacheColorHint(Color.TRANSPARENT);
		gv.setHorizontalSpacing(1);
		gv.setVerticalSpacing(1);
		gv.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
		gv.setGravity(Gravity.CENTER);
		gv.setAdapter(new FaceAdapter(this, i));
		gv.setOnTouchListener(forbidenScroll());    	// 防止乱pageview乱滚动
		gv.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				if (arg2 == MyApplication.NUM) {   // 删除表情键的位置
					int selection = msgEt.getSelectionStart();
					String text = msgEt.getText().toString();
					if (selection > 0) {
						String text2 = text.substring(selection - 1);
						if ("]".equals(text2)) {
							int start = text.lastIndexOf("[");
							int end = selection;
							msgEt.getText().delete(start, end);
							return;
						}
						msgEt.getText().delete(selection - 1, selection);
					}
				} else {
					int count = currentPage * MyApplication.NUM + arg2;
					// 凝视的部分,在EditText中显示字符串
					// String ori = msgEt.getText().toString();
					// int index = msgEt.getSelectionStart();
					// StringBuilder stringBuilder = new StringBuilder(ori);
					// stringBuilder.insert(index, keys.get(count));
					// msgEt.setText(stringBuilder.toString());
					// msgEt.setSelection(index + keys.get(count).length());

					// 以下这部分。在EditText中显示表情
					Bitmap bitmap = BitmapFactory.decodeResource(
							getResources(), (Integer) MyApplication
									.getInstance().getFaceMap().values()
									.toArray()[count]);
					if (bitmap != null) {
						int rawHeigh = bitmap.getHeight();
						int rawWidth = bitmap.getHeight();
						int newHeight = 40;
						int newWidth = 40;
						// 计算缩放因子
						float heightScale = ((float) newHeight) / rawHeigh;
						float widthScale = ((float) newWidth) / rawWidth;
						// 新建立矩阵
						Matrix matrix = new Matrix();
						matrix.postScale(heightScale, widthScale);
						// 设置图片的旋转角度
						// matrix.postRotate(-30);
						// 设置图片的倾斜
						// matrix.postSkew(0.1f, 0.1f);
						// 将图片大小压缩
						// 压缩后图片的宽和高以及kB大小均会变化
						Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0,
								rawWidth, rawHeigh, matrix, true);
						ImageSpan imageSpan = new ImageSpan(MainActivity.this,
								newBitmap);
						String emojiStr = mListFaceKeys.get(count);
						SpannableString spannableString = new SpannableString(
								emojiStr);
						spannableString.setSpan(imageSpan,
								emojiStr.indexOf('['),
								emojiStr.indexOf(']') + 1,
								Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
						msgEt.append(spannableString);
					} else {
						String ori = msgEt.getText().toString();
						int index = msgEt.getSelectionStart();
						StringBuilder stringBuilder = new StringBuilder(ori);
						stringBuilder.insert(index, mListFaceKeys.get(count));
						msgEt.setText(stringBuilder.toString());
						msgEt.setSelection(index + mListFaceKeys.get(count).length());
					}
				}
			}
		});
		return gv;
	}	
	
	// 防止乱pageview乱滚动
	private OnTouchListener forbidenScroll() {
		return new OnTouchListener() {
			public boolean onTouch(View v, MotionEvent event) {
				if (event.getAction() == MotionEvent.ACTION_MOVE) {
					return true;
				}
				return false;
			}
		};
	}
	
	@Override
	protected void onPause() {
		// TODO Auto-generated method stub
		mInputMethodManager.hideSoftInputFromWindow(msgEt.getWindowToken(), 0);
		faceLinearLayout.setVisibility(View.GONE);
		isFaceShow = false;
		super.onPause();
	}
	
	
	//处理下拉刷新的效果
	@Override
	public void onRefresh() {
		MsgPagerNum++;
		List<MessageItem> msgList = initMsgData();
		int position = mMessageAdapter.getCount();
		mMessageAdapter.setMessageList(msgList);
		mMsgListView.stopRefresh();
		
		mMsgListView.setSelection(mMessageAdapter.getCount() - position - 1);
		Log.i("Show","MsgPagerNum = " + mMessageAdapter + ", adapter.getCount() = "
				+ mMessageAdapter.getCount());
		
	}
	@Override
	public void onLoadMore() {
		// TODO Auto-generated method stub
		
	}

	private TransitionEffect mEffects[] = { TransitionEffect.Standard,
			TransitionEffect.Tablet, TransitionEffect.CubeIn,
			TransitionEffect.CubeOut, TransitionEffect.FlipVertical,
			TransitionEffect.FlipHorizontal, TransitionEffect.Stack,
			TransitionEffect.ZoomIn, TransitionEffect.ZoomOut,
			TransitionEffect.RotateUp, TransitionEffect.RotateDown,
			TransitionEffect.Accordion, };// 表情翻页效果

}
二、基本的xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/root"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <include layout="@layout/common_title_bg" />

    <FrameLayout
        android:layout_width="fill_parent"
        android:layout_height="0.0dip"
        android:layout_weight="1.0"
        android:background="@drawable/chat_bg_01" >

        <com.org.xlistview.MsgListView
            android:id="@+id/msg_listView"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:divider="@null"
            android:listSelector="@android:color/transparent"
            android:transcriptMode="normal" />
    </FrameLayout>

    <LinearLayout
        android:id="@+id/inputBar"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/bottombar_bg"
        android:gravity="center_vertical" >

        <!-- <ImageButton
            android:id="@+id/more_btn"
            android:layout_width="42.0dip"
            android:layout_height="fill_parent"
            android:background="@android:color/transparent"
            android:paddingLeft="10.0dip"
            android:src="@drawable/pop_btn_selector" /> -->

        <ImageButton
            android:id="@+id/face_btn"
            android:layout_width="42.0dip"
            android:layout_height="fill_parent"
            android:background="@android:color/transparent"
            android:paddingLeft="5.0dip"
            android:paddingRight="5.0dip"
            android:src="@drawable/pop_btn_face_selector" />

        <EditText
            android:id="@+id/msg_et"
            android:layout_width="0.0dip"
            android:layout_height="40dip"
            android:layout_marginBottom="6.0dip"
            android:layout_marginTop="6.0dip"
            android:layout_weight="1.0"
            android:background="@drawable/chat_bottombar_input"
            android:inputType="textMultiLine"
            android:maxHeight="68.0dip"
            android:paddingBottom="4.0dip"
            android:paddingLeft="10.0dip"
            android:paddingRight="14.0dip"
            android:paddingTop="4.0dip"
            android:textSize="16.0sp" />

        <LinearLayout
            android:id="@+id/send_layout"
            android:layout_width="56.0dip"
            android:layout_height="fill_parent"
            android:layout_gravity="left|center"
            android:clickable="true"
            android:gravity="center_vertical" >

            <Button
                android:id="@+id/send_btn"
                android:layout_width="42.0dip"
                android:layout_height="34.0dip"
                android:layout_marginLeft="4.0dip"
                android:background="@drawable/chat_bottombar_btn_selector"
                android:enabled="false"
                android:shadowColor="#ff568ab5"
                android:shadowDx="0.0"
                android:shadowDy="-1.0"
                android:shadowRadius="0.2"
                android:text="发送"
                android:textColor="@color/send_btn_textcolor"
                android:textSize="14.0sp" />
        </LinearLayout>
    </LinearLayout>

    <FrameLayout
        android:id="@+id/panelLayout"
        android:layout_width="fill_parent"
        android:layout_height="204.0dip"
        android:background="#ff34373c"
        android:visibility="gone" >

        <GridView
            android:id="@+id/panel"
            android:layout_width="fill_parent"
            android:layout_height="204.0dip"
            android:gravity="center"
            android:listSelector="#ff34373c"
            android:numColumns="4"
            android:paddingLeft="11.0dip"
            android:paddingRight="11.0dip"
            android:paddingTop="14.0dip"
            android:scrollbars="none"
            android:stretchMode="columnWidth"
            android:verticalSpacing="14.0dip" />

        <ImageView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/chat_plugin_shadow" />
    </FrameLayout>

    <LinearLayout
        android:id="@+id/face_ll"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="#fff0f0f0"
        android:orientation="vertical"
        android:paddingBottom="5dip"
        android:paddingTop="5dip"
        android:visibility="gone" >

        <com.org.view.JazzyViewPager
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:id="@+id/face_pager"
            app:style="cubeout"
            android:layout_width="fill_parent"
            android:layout_height="120.0dip"
            android:layout_marginLeft="5dip"
            android:layout_marginRight="5dip"
            android:background="#0000"
            android:flipInterval="30"
            android:persistentDrawingCache="animation" />

        <com.org.view.CirclePageIndicator
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:id="@+id/indicator"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:padding="10dip" />
    </LinearLayout>

</LinearLayout>

还有很多适配器,其它实现效果的源代码就不具体贴了,须要细致研究,下载本文的源代码。

下载地址:点击


posted @ 2017-05-17 21:48  mfmdaoyou  阅读(410)  评论(0编辑  收藏  举报