Android UI【android 仿微信、QQ聊天,带表情,可翻页,带翻页拖动缓冲】
http://blog.csdn.net/lnb333666/article/details/8546497
如题,这是公司项目的一个功能模块,先上个效果图:
其次大致说说原理:
1,首先判断输入的字符,是否包含表情的文字,比如 这个表情对应的文件名为 emoji_1.png,它对应的文字描述 : [可爱],如果我们在输出的是输出这么一句话:老婆,我想你了。 那么我们对应的根本文字就是:老婆,我想你了[可爱]。
2,具体的转换过程就是用正则表达式比配文字中是否含有[xxx]这类的文字,如果有,那么我们就根据拿到的[xxx]找到它对应的资源文件id,当然这其中有一个关系表,看你怎么处理这个关系了。最后将其用SpannableString替换成文字,表面上显示有图片,其实TextView里的text依然是:老婆,我想你了[可爱]。这个过程明白么?
下面贴上DEMO工程的结构:
再贴上几个重要的类:
- package com.example.facedemo;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.regex.Matcher;
- import java.util.regex.Pattern;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.text.Spannable;
- import android.text.SpannableString;
- import android.text.TextUtils;
- import android.text.style.ImageSpan;
- import android.util.Log;
- /**
- *
- ******************************************
- * @author 廖乃波
- * @文件名称 : FaceConversionUtil.java
- * @创建时间 : 2013-1-27 下午02:34:09
- * @文件描述 : 表情轉換工具
- ******************************************
- */
- public class FaceConversionUtil {
- /** 每一页表情的个数 */
- private int pageSize = 20;
- private static FaceConversionUtil mFaceConversionUtil;
- /** 保存于内存中的表情HashMap */
- private HashMap<String, String> emojiMap = new HashMap<String, String>();
- /** 保存于内存中的表情集合 */
- private List<ChatEmoji> emojis = new ArrayList<ChatEmoji>();
- /** 表情分页的结果集合 */
- public List<List<ChatEmoji>> emojiLists = new ArrayList<List<ChatEmoji>>();
- private FaceConversionUtil() {
- }
- public static FaceConversionUtil getInstace() {
- if (mFaceConversionUtil == null) {
- mFaceConversionUtil = new FaceConversionUtil();
- }
- return mFaceConversionUtil;
- }
- /**
- * 得到一个SpanableString对象,通过传入的字符串,并进行正则判断
- *
- * @param context
- * @param str
- * @return
- */
- public SpannableString getExpressionString(Context context, String str) {
- SpannableString spannableString = new SpannableString(str);
- // 正则表达式比配字符串里是否含有表情,如: 我好[开心]啊
- String zhengze = "\\[[^\\]]+\\]";
- // 通过传入的正则表达式来生成一个pattern
- Pattern sinaPatten = Pattern.compile(zhengze, Pattern.CASE_INSENSITIVE);
- try {
- dealExpression(context, spannableString, sinaPatten, 0);
- } catch (Exception e) {
- Log.e("dealExpression", e.getMessage());
- }
- return spannableString;
- }
- /**
- * 添加表情
- *
- * @param context
- * @param imgId
- * @param spannableString
- * @return
- */
- public SpannableString addFace(Context context, int imgId,
- String spannableString) {
- if (TextUtils.isEmpty(spannableString)) {
- return null;
- }
- Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
- imgId);
- bitmap = Bitmap.createScaledBitmap(bitmap, 35, 35, true);
- ImageSpan imageSpan = new ImageSpan(context, bitmap);
- SpannableString spannable = new SpannableString(spannableString);
- spannable.setSpan(imageSpan, 0, spannableString.length(),
- Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
- return spannable;
- }
- /**
- * 对spanableString进行正则判断,如果符合要求,则以表情图片代替
- *
- * @param context
- * @param spannableString
- * @param patten
- * @param start
- * @throws Exception
- */
- private void dealExpression(Context context,
- SpannableString spannableString, Pattern patten, int start)
- throws Exception {
- Matcher matcher = patten.matcher(spannableString);
- while (matcher.find()) {
- String key = matcher.group();
- // 返回第一个字符的索引的文本匹配整个正则表达式,ture 则继续递归
- if (matcher.start() < start) {
- continue;
- }
- String value = emojiMap.get(key);
- if (TextUtils.isEmpty(value)) {
- continue;
- }
- int resId = context.getResources().getIdentifier(value, "drawable",
- context.getPackageName());
- // 通过上面匹配得到的字符串来生成图片资源id,下边的方法可用,但是你工程混淆的时候就有事了,你懂的。不是我介绍的重点
- // Field field=R.drawable.class.getDeclaredField(value);
- // int resId=Integer.parseInt(field.get(null).toString());
- if (resId != 0) {
- Bitmap bitmap = BitmapFactory.decodeResource(
- context.getResources(), resId);
- bitmap = Bitmap.createScaledBitmap(bitmap, 50, 50, true);
- // 通过图片资源id来得到bitmap,用一个ImageSpan来包装
- ImageSpan imageSpan = new ImageSpan(bitmap);
- // 计算该图片名字的长度,也就是要替换的字符串的长度
- int end = matcher.start() + key.length();
- // 将该图片替换字符串中规定的位置中
- spannableString.setSpan(imageSpan, matcher.start(), end,
- Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
- if (end < spannableString.length()) {
- // 如果整个字符串还未验证完,则继续。。
- dealExpression(context, spannableString, patten, end);
- }
- break;
- }
- }
- }
- public void getFileText(Context context) {
- ParseData(FileUtils.getEmojiFile(context), context);
- }
- /**
- * 解析字符
- *
- * @param data
- */
- private void ParseData(List<String> data, Context context) {
- if (data == null) {
- return;
- }
- ChatEmoji emojEentry;
- try {
- for (String str : data) {
- String[] text = str.split(",");
- String fileName = text[0]
- .substring(0, text[0].lastIndexOf("."));
- emojiMap.put(text[1], fileName);
- int resID = context.getResources().getIdentifier(fileName,
- "drawable", context.getPackageName());
- if (resID != 0) {
- emojEentry = new ChatEmoji();
- emojEentry.setId(resID);
- emojEentry.setCharacter(text[1]);
- emojEentry.setFaceName(fileName);
- emojis.add(emojEentry);
- }
- }
- int pageCount = (int) Math.ceil(emojis.size() / 20 + 0.1);
- for (int i = 0; i < pageCount; i++) {
- emojiLists.add(getData(i));
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- /**
- * 获取分页数据
- *
- * @param page
- * @return
- */
- private List<ChatEmoji> getData(int page) {
- int startIndex = page * pageSize;
- int endIndex = startIndex + pageSize;
- if (endIndex > emojis.size()) {
- endIndex = emojis.size();
- }
- // 不这么写,会在viewpager加载中报集合操作异常,我也不知道为什么
- List<ChatEmoji> list = new ArrayList<ChatEmoji>();
- list.addAll(emojis.subList(startIndex, endIndex));
- if (list.size() < pageSize) {
- for (int i = list.size(); i < pageSize; i++) {
- ChatEmoji object = new ChatEmoji();
- list.add(object);
- }
- }
- if (list.size() == pageSize) {
- ChatEmoji object = new ChatEmoji();
- object.setId(R.drawable.face_del_icon);
- list.add(object);
- }
- return list;
- }
- }
下边是表情布局,带输入框的,这样可以多个地方使用,就不不会使用太多多余代码。
- package com.example.facedemo;
- import java.util.ArrayList;
- import java.util.List;
- import android.content.Context;
- import android.graphics.Color;
- import android.graphics.drawable.ColorDrawable;
- import android.support.v4.view.ViewPager;
- import android.support.v4.view.ViewPager.OnPageChangeListener;
- import android.text.SpannableString;
- import android.text.TextUtils;
- import android.util.AttributeSet;
- import android.view.Gravity;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.view.ViewGroup;
- import android.widget.AdapterView;
- import android.widget.AdapterView.OnItemClickListener;
- import android.widget.EditText;
- import android.widget.GridView;
- import android.widget.ImageView;
- import android.widget.LinearLayout;
- import android.widget.RelativeLayout;
- /**
- *
- ******************************************
- * @author 廖乃波
- * @文件名称 : FaceRelativeLayout.java
- * @创建时间 : 2013-1-27 下午02:34:17
- * @文件描述 : 带表情的自定义输入框
- ******************************************
- */
- public class FaceRelativeLayout extends RelativeLayout implements
- OnItemClickListener, OnClickListener {
- private Context context;
- /** 表情页的监听事件 */
- private OnCorpusSelectedListener mListener;
- /** 显示表情页的viewpager */
- private ViewPager vp_face;
- /** 表情页界面集合 */
- private ArrayList<View> pageViews;
- /** 游标显示布局 */
- private LinearLayout layout_point;
- /** 游标点集合 */
- private ArrayList<ImageView> pointViews;
- /** 表情集合 */
- private List<List<ChatEmoji>> emojis;
- /** 表情区域 */
- private View view;
- /** 输入框 */
- private EditText et_sendmessage;
- /** 表情数据填充器 */
- private List<FaceAdapter> faceAdapters;
- /** 当前表情页 */
- private int current = 0;
- public FaceRelativeLayout(Context context) {
- super(context);
- this.context = context;
- }
- public FaceRelativeLayout(Context context, AttributeSet attrs) {
- super(context, attrs);
- this.context = context;
- }
- public FaceRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- this.context = context;
- }
- public void setOnCorpusSelectedListener(OnCorpusSelectedListener listener) {
- mListener = listener;
- }
- /**
- * 表情选择监听
- *
- * @author naibo-liao
- * @时间: 2013-1-15下午04:32:54
- */
- public interface OnCorpusSelectedListener {
- void onCorpusSelected(ChatEmoji emoji);
- void onCorpusDeleted();
- }
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- emojis = FaceConversionUtil.getInstace().emojiLists;
- onCreate();
- }
- private void onCreate() {
- Init_View();
- Init_viewPager();
- Init_Point();
- Init_Data();
- }
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.btn_face:
- // 隐藏表情选择框
- if (view.getVisibility() == View.VISIBLE) {
- view.setVisibility(View.GONE);
- } else {
- view.setVisibility(View.VISIBLE);
- }
- break;
- case R.id.et_sendmessage:
- // 隐藏表情选择框
- if (view.getVisibility() == View.VISIBLE) {
- view.setVisibility(View.GONE);
- }
- break;
- }
- }
- /**
- * 隐藏表情选择框
- */
- public boolean hideFaceView() {
- // 隐藏表情选择框
- if (view.getVisibility() == View.VISIBLE) {
- view.setVisibility(View.GONE);
- return true;
- }
- return false;
- }
- /**
- * 初始化控件
- */
- private void Init_View() {
- vp_face = (ViewPager) findViewById(R.id.vp_contains);
- et_sendmessage = (EditText) findViewById(R.id.et_sendmessage);
- layout_point = (LinearLayout) findViewById(R.id.iv_image);
- et_sendmessage.setOnClickListener(this);
- findViewById(R.id.btn_face).setOnClickListener(this);
- view = findViewById(R.id.ll_facechoose);
- }
- /**
- * 初始化显示表情的viewpager
- */
- private void Init_viewPager() {
- pageViews = new ArrayList<View>();
- // 左侧添加空页
- View nullView1 = new View(context);
- // 设置透明背景
- nullView1.setBackgroundColor(Color.TRANSPARENT);
- pageViews.add(nullView1);
- // 中间添加表情页
- faceAdapters = new ArrayList<FaceAdapter>();
- for (int i = 0; i < emojis.size(); i++) {
- GridView view = new GridView(context);
- FaceAdapter adapter = new FaceAdapter(context, emojis.get(i));
- view.setAdapter(adapter);
- faceAdapters.add(adapter);
- view.setOnItemClickListener(this);
- view.setNumColumns(7);
- view.setBackgroundColor(Color.TRANSPARENT);
- view.setHorizontalSpacing(1);
- view.setVerticalSpacing(1);
- view.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
- view.setCacheColorHint(0);
- view.setPadding(5, 0, 5, 0);
- view.setSelector(new ColorDrawable(Color.TRANSPARENT));
- view.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
- LayoutParams.WRAP_CONTENT));
- view.setGravity(Gravity.CENTER);
- pageViews.add(view);
- }
- // 右侧添加空页面
- View nullView2 = new View(context);
- // 设置透明背景
- nullView2.setBackgroundColor(Color.TRANSPARENT);
- pageViews.add(nullView2);
- }
- /**
- * 初始化游标
- */
- private void Init_Point() {
- pointViews = new ArrayList<ImageView>();
- ImageView imageView;
- for (int i = 0; i < pageViews.size(); i++) {
- imageView = new ImageView(context);
- imageView.setBackgroundResource(R.drawable.d1);
- LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
- new ViewGroup.LayoutParams(LayoutParams.WRAP_CONTENT,
- LayoutParams.WRAP_CONTENT));
- layoutParams.leftMargin = 10;
- layoutParams.rightMargin = 10;
- layoutParams.width = 8;
- layoutParams.height = 8;
- layout_point.addView(imageView, layoutParams);
- if (i == 0 || i == pageViews.size() - 1) {
- imageView.setVisibility(View.GONE);
- }
- if (i == 1) {
- imageView.setBackgroundResource(R.drawable.d2);
- }
- pointViews.add(imageView);
- }
- }
- /**
- * 填充数据
- */
- private void Init_Data() {
- vp_face.setAdapter(new ViewPagerAdapter(pageViews));
- vp_face.setCurrentItem(1);
- current = 0;
- vp_face.setOnPageChangeListener(new OnPageChangeListener() {
- @Override
- public void onPageSelected(int arg0) {
- current = arg0 - 1;
- // 描绘分页点
- draw_Point(arg0);
- // 如果是第一屏或者是最后一屏禁止滑动,其实这里实现的是如果滑动的是第一屏则跳转至第二屏,如果是最后一屏则跳转到倒数第二屏.
- if (arg0 == pointViews.size() - 1 || arg0 == 0) {
- if (arg0 == 0) {
- vp_face.setCurrentItem(arg0 + 1);// 第二屏 会再次实现该回调方法实现跳转.
- pointViews.get(1).setBackgroundResource(R.drawable.d2);
- } else {
- vp_face.setCurrentItem(arg0 - 1);// 倒数第二屏
- pointViews.get(arg0 - 1).setBackgroundResource(
- R.drawable.d2);
- }
- }
- }
- @Override
- public void onPageScrolled(int arg0, float arg1, int arg2) {
- }
- @Override
- public void onPageScrollStateChanged(int arg0) {
- }
- });
- }
- /**
- * 绘制游标背景
- */
- public void draw_Point(int index) {
- for (int i = 1; i < pointViews.size(); i++) {
- if (index == i) {
- pointViews.get(i).setBackgroundResource(R.drawable.d2);
- } else {
- pointViews.get(i).setBackgroundResource(R.drawable.d1);
- }
- }
- }
- @Override
- public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
- ChatEmoji emoji = (ChatEmoji) faceAdapters.get(current).getItem(arg2);
- if (emoji.getId() == R.drawable.face_del_icon) {
- int selection = et_sendmessage.getSelectionStart();
- String text = et_sendmessage.getText().toString();
- if (selection > 0) {
- String text2 = text.substring(selection - 1);
- if ("]".equals(text2)) {
- int start = text.lastIndexOf("[");
- int end = selection;
- et_sendmessage.getText().delete(start, end);
- return;
- }
- et_sendmessage.getText().delete(selection - 1, selection);
- }
- }
- if (!TextUtils.isEmpty(emoji.getCharacter())) {
- if (mListener != null)
- mListener.onCorpusSelected(emoji);
- SpannableString spannableString = FaceConversionUtil.getInstace()
- .addFace(getContext(), emoji.getId(), emoji.getCharacter());
- et_sendmessage.append(spannableString);
- }
- }
- }
接下来是聊天数据填充器的
- package com.example.facedemo;
- import android.content.Context;
- import android.text.SpannableString;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.BaseAdapter;
- import android.widget.TextView;
- import java.util.List;
- /**
- *
- ******************************************
- * @author 廖乃波
- * @文件名称 : ChatMsgAdapter.java
- * @创建时间 : 2013-1-27 下午02:33:16
- * @文件描述 : 消息数据填充起
- ******************************************
- */
- public class ChatMsgAdapter extends BaseAdapter {
- public static interface IMsgViewType {
- int IMVT_COM_MSG = 0;
- int IMVT_TO_MSG = 1;
- }
- private List<ChatMsgEntity> coll;
- private LayoutInflater mInflater;
- private Context context;
- public ChatMsgAdapter(Context context, List<ChatMsgEntity> coll) {
- this.coll = coll;
- mInflater = LayoutInflater.from(context);
- this.context = context;
- }
- public int getCount() {
- return coll.size();
- }
- public Object getItem(int position) {
- return coll.get(position);
- }
- public long getItemId(int position) {
- return position;
- }
- public int getItemViewType(int position) {
- ChatMsgEntity entity = coll.get(position);
- if (entity.getMsgType()) {
- return IMsgViewType.IMVT_COM_MSG;
- } else {
- return IMsgViewType.IMVT_TO_MSG;
- }
- }
- public int getViewTypeCount() {
- return 2;
- }
- public View getView(int position, View convertView, ViewGroup parent) {
- ChatMsgEntity entity = coll.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.tvContent = (TextView) convertView
- .findViewById(R.id.tv_chatcontent);
- viewHolder.isComMsg = isComMsg;
- convertView.setTag(viewHolder);
- } else {
- viewHolder = (ViewHolder) convertView.getTag();
- }
- viewHolder.tvSendTime.setText(entity.getDate());
- SpannableString spannableString = FaceConversionUtil.getInstace().getExpressionString(context, entity.getText());
- viewHolder.tvContent.setText(spannableString);
- return convertView;
- }
- class ViewHolder {
- public TextView tvSendTime;
- public TextView tvContent;
- public boolean isComMsg = true;
- }
- }
- package com.example.facedemo;
- import java.io.BufferedReader;
- import java.io.IOException;
- import java.io.InputStream;
- import java.io.InputStreamReader;
- import java.util.ArrayList;
- import java.util.List;
- import android.content.Context;
- /**
- *
- ******************************************
- * @author 廖乃波
- * @文件名称 : FileUtils.java
- * @创建时间 : 2013-1-27 下午02:35:09
- * @文件描述 : 文件工具类
- ******************************************
- */
- public class FileUtils {
- /**
- * 读取表情配置文件
- *
- * @param context
- * @return
- */
- public static List<String> getEmojiFile(Context context) {
- try {
- List<String> list = new ArrayList<String>();
- InputStream in = context.getResources().getAssets().open("emoji");
- BufferedReader br = new BufferedReader(new InputStreamReader(in,
- "UTF-8"));
- String str = null;
- while ((str = br.readLine()) != null) {
- list.add(str);
- }
- return list;
- } catch (IOException e) {
- e.printStackTrace();
- }
- return null;
- }
- }
下边这个是表情翻页的数据填充,用的是viewpager,每一页填充的是一个gridview
- package com.example.facedemo;
- import java.util.List;
- import android.support.v4.view.PagerAdapter;
- import android.support.v4.view.ViewPager;
- import android.view.View;
- /**
- *
- ******************************************
- * @author 廖乃波
- * @文件名称 : ViewPagerAdapter.java
- * @创建时间 : 2013-1-27 下午02:35:27
- * @文件描述 : ViewPager 数据填充器,切记做其他操作!!!只填充View!!!!
- ******************************************
- */
- public class ViewPagerAdapter extends PagerAdapter {
- private List<View> pageViews;
- public ViewPagerAdapter(List<View> pageViews) {
- super();
- this.pageViews=pageViews;
- }
- // 显示数目
- @Override
- public int getCount() {
- return pageViews.size();
- }
- @Override
- public boolean isViewFromObject(View arg0, Object arg1) {
- return arg0 == arg1;
- }
- @Override
- public int getItemPosition(Object object) {
- return super.getItemPosition(object);
- }
- @Override
- public void destroyItem(View arg0, int arg1, Object arg2) {
- ((ViewPager)arg0).removeView(pageViews.get(arg1));
- }
- /***
- * 获取每一个item�?类于listview中的getview
- */
- @Override
- public Object instantiateItem(View arg0, int arg1) {
- ((ViewPager)arg0).addView(pageViews.get(arg1));
- return pageViews.get(arg1);
- }
- }
最后呢,是表情的配置文件,你想怎么搞都行,我就这么搞的
- emoji_1.png,[可爱]
- emoji_2.png,[笑脸]
- emoji_3.png,[囧]
- emoji_4.png,[生气]
- emoji_5.png,[鬼脸]
- emoji_6.png,[花心]
- emoji_7.png,[害怕]
- emoji_8.png,[我汗]
- emoji_9.png,[尴尬]
- emoji_10.png,[哼哼]
- emoji_11.png,[忧郁]
- emoji_12.png,[呲牙]
- emoji_13.png,[媚眼]
- emoji_14.png,[累]
- emoji_15.png,[苦逼]
- emoji_16.png,[瞌睡]
- emoji_17.png,[哎呀]
- emoji_18.png,[刺瞎]
- emoji_19.png,[哭]
- emoji_20.png,[激动]
- emoji_21.png,[难过]
- emoji_22.png,[害羞]
- emoji_23.png,[高兴]
- emoji_24.png,[愤怒]
- emoji_25.png,[亲]
- emoji_26.png,[飞吻]
- emoji_27.png,[得意]
- emoji_28.png,[惊恐]
- emoji_29.png,[口罩]
- emoji_30.png,[惊讶]
- emoji_31.png,[委屈]
- emoji_32.png,[生病]
- emoji_33.png,[红心]
- emoji_34.png,[心碎]
- emoji_35.png,[玫瑰]
- emoji_36.png,[花]
- emoji_37.png,[外星人]
- emoji_38.png,[金牛座]
- emoji_39.png,[双子座]
- emoji_40.png,[巨蟹座]
- emoji_41.png,[狮子座]
- emoji_42.png,[处女座]
- emoji_43.png,[天平座]
- emoji_44.png,[天蝎座]
- emoji_45.png,[射手座]
- emoji_46.png,[摩羯座]
- emoji_47.png,[水瓶座]
- emoji_48.png,[白羊座]
- emoji_49.png,[双鱼座]
- emoji_50.png,[星座]
- emoji_51.png,[男孩]
- emoji_52.png,[女孩]
- emoji_53.png,[嘴唇]
- emoji_54.png,[爸爸]
- emoji_55.png,[妈妈]
- emoji_56.png,[衣服]
- emoji_57.png,[皮鞋]
- emoji_58.png,[照相]
- emoji_59.png,[电话]
- emoji_60.png,[石头]
- emoji_61.png,[胜利]
- emoji_62.png,[禁止]
- emoji_63.png,[滑雪]
- emoji_64.png,[高尔夫]
- emoji_65.png,[网球]
- emoji_66.png,[棒球]
- emoji_67.png,[冲浪]
- emoji_68.png,[足球]
- emoji_69.png,[小鱼]
- emoji_70.png,[问号]
- emoji_71.png,[叹号]
- emoji_179.png,[顶]
- emoji_180.png,[写字]
- emoji_181.png,[衬衫]
- emoji_182.png,[小花]
- emoji_183.png,[郁金香]
- emoji_184.png,[向日葵]
- emoji_185.png,[鲜花]
- emoji_186.png,[椰树]
- emoji_187.png,[仙人掌]
- emoji_188.png,[气球]
- emoji_189.png,[炸弹]
- emoji_190.png,[喝彩]
- emoji_191.png,[剪子]
- emoji_192.png,[蝴蝶结]
- emoji_193.png,[机密]
- emoji_194.png,[铃声]
- emoji_195.png,[女帽]
- emoji_196.png,[裙子]
- emoji_197.png,[理发店]
- emoji_198.png,[和服]
- emoji_199.png,[比基尼]
- emoji_200.png,[拎包]
- emoji_201.png,[拍摄]
- emoji_202.png,[铃铛]
- emoji_203.png,[音乐]
- emoji_204.png,[心星]
- emoji_205.png,[粉心]
- emoji_206.png,[丘比特]
- emoji_207.png,[吹气]
- emoji_208.png,[口水]
- emoji_209.png,[对]
- emoji_210.png,[错]
- emoji_211.png,[绿茶]
- emoji_212.png,[面包]
- emoji_213.png,[面条]
- emoji_214.png,[咖喱饭]
- emoji_215.png,[饭团]
- emoji_216.png,[麻辣烫]
- emoji_217.png,[寿司]
- emoji_218.png,[苹果]
- emoji_219.png,[橙子]
- emoji_220.png,[草莓]
- emoji_221.png,[西瓜]
- emoji_222.png,[柿子]
- emoji_223.png,[眼睛]
- emoji_224.png,[好的]
忘了布局文件,哇哈哈
- <?xml version="1.0" encoding="utf-8"?>
- <com.example.facedemo.FaceRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/FaceRelativeLayout"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" >
- <RelativeLayout
- android:id="@+id/rl_input"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:background="@drawable/chat_footer_bg" >
- <ImageButton
- android:id="@+id/btn_face"
- android:layout_width="40dip"
- android:layout_height="40dip"
- android:layout_alignParentLeft="true"
- android:layout_centerVertical="true"
- android:layout_marginLeft="8dip"
- android:background="@drawable/chat_send_btn"
- android:src="@drawable/ib_face" />
- <Button
- android:id="@+id/btn_send"
- android:layout_width="60dp"
- android:layout_height="40dp"
- android:layout_alignParentRight="true"
- android:layout_centerVertical="true"
- android:layout_marginRight="10dp"
- android:background="@drawable/chat_send_btn"
- android:text="发送" />
- <EditText
- android:id="@+id/et_sendmessage"
- android:layout_width="fill_parent"
- android:layout_height="40dp"
- android:layout_centerVertical="true"
- android:layout_marginLeft="8dp"
- android:layout_marginRight="10dp"
- android:layout_toLeftOf="@id/btn_send"
- android:layout_toRightOf="@id/btn_face"
- android:background="@drawable/login_edit_normal"
- android:singleLine="true"
- android:textSize="18sp" />
- </RelativeLayout>
- <RelativeLayout
- android:id="@+id/ll_facechoose"
- android:layout_width="fill_parent"
- android:layout_height="124dip"
- android:layout_below="@id/rl_input"
- android:background="#f6f5f5"
- android:visibility="gone" >
- <android.support.v4.view.ViewPager
- android:id="@+id/vp_contains"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
- </android.support.v4.view.ViewPager>
- <LinearLayout
- android:id="@+id/iv_image"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:layout_marginBottom="6dip"
- android:gravity="center"
- android:orientation="horizontal" >
- </LinearLayout>
- </RelativeLayout>
- </com.example.facedemo.FaceRelativeLayout>
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 源码 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<