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

来源:互联网 发布:nginx 404 重定向 编辑:程序博客网 时间:2024/06/10 06:21

经过一个星期的折腾,终于做完了这个Android 聊天表情输入、表情翻页带效果、下拉刷新聊天记录。这只是一个单独聊天表情的输入,以及聊天的效果实现。因为我没有写服务器,所以没有双方聊天的效果。主要是聊天中表情的选择,发送。表情翻页带有不同的效果。我在主要代码中都写了注释。下面看代码实现。附上本文源码,代码较多。

下载地址:点击

一、先看实现的效果图


二、调用接口以及设置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;@Overrideprotected 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() {@Overridepublic 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() {@Overridepublic void onTextChanged(CharSequence s, int start, int before,int count) {}@Overridepublic void beforeTextChanged(CharSequence s, int start, int count,int after) {}@Overridepublic void afterTextChanged(Editable s) {if (s.length() > 0) {sendBtn.setEnabled(true);} else {sendBtn.setEnabled(false);}}});faceBtn.setOnClickListener(this);sendBtn.setOnClickListener(this);}@Overridepublic 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;}@Overridepublic 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() {@Overridepublic void onPageSelected(int arg0) {currentPage = arg0;}@Overridepublic void onPageScrolled(int arg0, float arg1, int arg2) {// do nothing}@Overridepublic 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() {@Overridepublic 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;}};}@Overrideprotected void onPause() {// TODO Auto-generated method stubmInputMethodManager.hideSoftInputFromWindow(msgEt.getWindowToken(), 0);faceLinearLayout.setVisibility(View.GONE);isFaceShow = false;super.onPause();}//处理下拉刷新的效果@Overridepublic 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());}@Overridepublic 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>

还有许多适配器,其他实现效果的源码就不详细贴了,需要仔细研究,下载本文的源码。

下载地址:点击


3 1
原创粉丝点击