经过一个星期的折腾,终于做完了这个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; @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>
还有许多适配器,其他实现效果的源码就不详细贴了,需要仔细研究,下载本文的源码。
下载地址:点击
版权声明:本文为博主原创文章,未经博主允许不得转载。