上次做了一个表情的控件,不敢私藏,给大家分享

效果图如下,图片是新浪微博的,该有的功能应该都有了。

bVqjXz

这其实就是一个Fragment,所以用起来很方便,只要

FaceFragment faceFragment = FaceFragment.Instance();

getSupportFragmentManager().beginTransaction().add(R.id.Container,faceFragment).commit();

就可以显示效果图上的效果了。

FaceFragment源码如下:

public class FaceFragment extends Fragment implements View.OnClickListener {

public static FaceFragment Instance() {

FaceFragment instance = new FaceFragment();

Bundle bundle = new Bundle();

instance.setArguments(bundle);

return instance;

}

ViewPager faceViewPager;

EmojiIndicatorView faceIndicator;

TextView faceRecentTv;

TextView faceFirstSetTv;

ArrayList ViewPagerItems = new ArrayList<>();

ArrayList emojiList;

ArrayList recentlyEmojiList;

private int columns = 7; //每一行的表情数量

private int rows = 3; //设置总共有几行

private OnEmojiClickListener listener;

private RecentEmojiManager recentManager;

public void setListener(OnEmojiClickListener listener) {

this.listener = listener;

}

@Override

public void onAttach(Activity activity) {

if (activity instanceof OnEmojiClickListener) {

this.listener = (OnEmojiClickListener) activity;

}

recentManager = RecentEmojiManager.make(activity);

super.onAttach(activity);

}

@Override

public void onCreate(Bundle savedInstanceState) {

emojiList = EmojiUtil.getEmojiList();

try {

//用SharedPerference来保存我们最近使用的表情

if (recentManager.getCollection(RecentEmojiManager.PREFERENCE_NAME) != null) {

recentlyEmojiList = (ArrayList) recentManager.getCollection(RecentEmojiManager.PREFERENCE_NAME);

} else {

recentlyEmojiList = new ArrayList<>();

}

} catch (IOException e) {

e.printStackTrace();

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

super.onCreate(savedInstanceState);

}

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

View view = inflater.inflate(R.layout.fragment_face, container, false);

faceViewPager = (ViewPager) view.findViewById(R.id.face_viewPager);

faceIndicator = (EmojiIndicatorView) view.findViewById(R.id.face_indicator);

faceRecentTv = (TextView) view.findViewById(R.id.face_recent);

faceFirstSetTv = (TextView) view.findViewById(R.id.face_first_set);

initViews();

return view;

}

private void initViews() {

initViewPager(emojiList);

faceFirstSetTv.setSelected(true);

faceFirstSetTv.setOnClickListener(this);

faceRecentTv.setOnClickListener(this);

}

private void initViewPager(ArrayList list) {

intiIndicator(list);

ViewPagerItems.clear();

for (int i = 0; i < getPagerCount(list); i++) {

ViewPagerItems.add(getViewPagerItem(i, list));

}

FaceVPAdapter mVpAdapter = new FaceVPAdapter(ViewPagerItems);

faceViewPager.setAdapter(mVpAdapter);

faceViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {

int oldPosition = 0;

@Override

public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

}

@Override

public void onPageSelected(int position) {

faceIndicator.playBy(oldPosition, position);

oldPosition = position;

}

@Override

public void onPageScrollStateChanged(int state) {

}

});

}

private void intiIndicator(ArrayList list) {

faceIndicator.init(getPagerCount(list));

}

@Override

public void onClick(View v) {

if(v.getId() == R.id.face_first_set){

if (faceIndicator.getVisibility() == View.GONE) {

faceIndicator.setVisibility(View.VISIBLE);

}

if (!faceFirstSetTv.isSelected()) {

faceFirstSetTv.setSelected(true);

initViewPager(emojiList);

}

faceRecentTv.setSelected(false);

}else if (v.getId() == R.id.face_recent){

if (faceIndicator.getVisibility() == View.VISIBLE) {

faceIndicator.setVisibility(View.GONE);

}

if (!faceRecentTv.isSelected()) {

faceRecentTv.setSelected(true);

initViewPager(recentlyEmojiList);

}

faceFirstSetTv.setSelected(false);

}

}

/**

* 根据表情数量以及GridView设置的行数和列数计算Pager数量

*

* @return

*/

private int getPagerCount(ArrayList list) {

int count = list.size();

return count % (columns * rows - 1) == 0 ? count / (columns * rows - 1)

: count / (columns * rows - 1) + 1;

}

private View getViewPagerItem(int position, ArrayList list) {

LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

View layout = inflater.inflate(R.layout.layout_face_grid, null);//表情布局

GridView gridview = (GridView) layout.findViewById(R.id.chart_face_gv);

/**

* 注:因为每一页末尾都有一个删除图标,所以每一页的实际表情columns * rows - 1; 空出最后一个位置给删除图标

* */

final List subList = new ArrayList<>();

subList.addAll(list.subList(position * (columns * rows - 1),

(columns * rows - 1) * (position + 1) > list

.size() ? list.size() : (columns

* rows - 1)

* (position + 1)));

/**

* 末尾添加删除图标

* */

if (subList.size() < (columns * rows - 1)) {

for (int i = subList.size(); i < (columns * rows - 1); i++) {

subList.add(null);

}

}

Emoji deleteEmoji = new Emoji();

deleteEmoji.setImageUri(R.drawable.face_delete);

subList.add(deleteEmoji);

FaceGVAdapter mGvAdapter = new FaceGVAdapter(subList, getActivity());

gridview.setAdapter(mGvAdapter);

gridview.setNumColumns(columns);

// 单击表情执行的操作

gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {

@Override

public void onItemClick(AdapterView> parent, View view, int position, long id) {

if (position == columns * rows - 1) {

if(listener != null){

listener.onEmojiDelete();

}

return;

}

if(listener != null){

listener.onEmojiClick(subList.get(position));

}

insertToRecentList(subList.get(position));

}

});

return gridview;

}

private void insertToRecentList(Emoji emoji) {

if (emoji != null) {

if (recentlyEmojiList.contains(emoji)) {

//如果已经有该表情,就把该表情放到第一个位置

int index = recentlyEmojiList.indexOf(emoji);

Emoji emoji0 = recentlyEmojiList.get(0);

recentlyEmojiList.set(index, emoji0);

recentlyEmojiList.set(0, emoji);

return;

}

if (recentlyEmojiList.size() == (rows * columns - 1)) {

//去掉最后一个

recentlyEmojiList.remove(rows * columns - 2);

}

recentlyEmojiList.add(0, emoji);

}

}

@Override

public void onDestroyView() {

super.onDestroyView();

try {

recentManager.putCollection(RecentEmojiManager.PREFERENCE_NAME, recentlyEmojiList);

} catch (IOException e) {

e.printStackTrace();

}

}

class FaceGVAdapter extends BaseAdapter {

private List list;

private Context mContext;

public FaceGVAdapter(List list, Context mContext) {

super();

this.list = list;

this.mContext = mContext;

}

@Override

public int getCount() {

// TODO Auto-generated method stub

return list.size();

}

@Override

public Object getItem(int position) {

// TODO Auto-generated method stub

return list.get(position);

}

@Override

public long getItemId(int position) {

// TODO Auto-generated method stub

return position;

}

@Override

public View getView(final int position, View convertView, ViewGroup parent) {

ViewHolder holder;

if (convertView == null) {

holder = new ViewHolder();

convertView = LayoutInflater.from(mContext).inflate(R.layout.item_face, null);

holder.iv = (ImageView) convertView.findViewById(R.id.face_image);

convertView.setTag(holder);

} else {

holder = (ViewHolder) convertView.getTag();

}

if (list.get(position) != null) {

holder.iv.setImageBitmap(EmojiUtil.decodeSampledBitmapFromResource(getActivity().getResources(), list.get(position).getImageUri(),

EmojiUtil.dip2px(getActivity(), 32), EmojiUtil.dip2px(getActivity(), 32)));

}

return convertView;

}

class ViewHolder {

ImageView iv;

}

}

class FaceVPAdapter extends PagerAdapter {

// 界面列表

private List views;

public FaceVPAdapter(List views) {

this.views = views;

}

@Override

public void destroyItem(View arg0, int arg1, Object arg2) {

((ViewPager) arg0).removeView((View) (arg2));

}

@Override

public int getCount() {

return views.size();

}

// 初始化arg1位置的界面

@Override

public Object instantiateItem(View arg0, int arg1) {

((ViewPager) arg0).addView(views.get(arg1));

return views.get(arg1);

}

// 判断是否由对象生成界

@Override

public boolean isViewFromObject(View arg0, Object arg1) {

return (arg0 == arg1);

}

}

让你的Activity实现(Fragment中set接口)这个接口来处理emoji的点击事件

public interface OnEmojiClickListener {

void onEmojiDelete();

void onEmojiClick(Emoji emoji);

}

}

你可以在EmojiUtil这个类中定义你的emoji编码去符合你的项目需求以及你需要在TextView中显示的Span大小。

public class EmojiUtil {

private static ArrayList emojiList;

public static ArrayList getEmojiList() {

if (emojiList == null) {

emojiList = generateEmojis();

}

return emojiList;

}

private static ArrayList generateEmojis() {

ArrayList list = new ArrayList<>();

for (int i = 0; i < EmojiResArray.length; i++) {

Emoji emoji = new Emoji();

emoji.setImageUri(EmojiResArray[i]);

emoji.setContent(EmojiTextArray[i]);

list.add(emoji);

}

return list;

}

public static final int[] EmojiResArray = {

R.drawable.d_aini,

R.drawable.d_aoteman,

R.drawable.d_baibai,

R.drawable.d_beishang,

R.drawable.d_bishi,

R.drawable.d_bizui,

R.drawable.d_chanzui,

R.drawable.d_chijing,

R.drawable.d_dahaqi,

R.drawable.d_dalian,

R.drawable.d_ding,

R.drawable.d_doge,

R.drawable.d_feizao,

R.drawable.d_ganmao,

R.drawable.d_guzhang,

R.drawable.d_haha,

R.drawable.d_haixiu,

R.drawable.d_han,

R.drawable.d_hehe,

R.drawable.d_heixian,

R.drawable.d_heng,

R.drawable.d_huaxin,

R.drawable.d_jiyan,

R.drawable.d_keai,

R.drawable.d_kelian,

R.drawable.d_ku,

R.drawable.d_kun,

R.drawable.d_landelini,

R.drawable.d_lei,

R.drawable.d_madaochenggong,

R.drawable.d_miao,

R.drawable.d_nanhaier,

R.drawable.d_nu,

R.drawable.d_numa,

R.drawable.d_numa,

R.drawable.d_qian,

R.drawable.d_qinqin,

R.drawable.d_shayan,

R.drawable.d_shengbing,

R.drawable.d_shenshou,

R.drawable.d_shiwang,

R.drawable.d_shuai,

R.drawable.d_shuijiao,

R.drawable.d_sikao,

R.drawable.d_taikaixin,

R.drawable.d_touxiao,

R.drawable.d_tu,

R.drawable.d_tuzi,

R.drawable.d_wabishi,

R.drawable.d_weiqu,

R.drawable.d_xiaoku,

R.drawable.d_xiongmao,

R.drawable.d_xixi,

R.drawable.d_xu,

R.drawable.d_yinxian,

R.drawable.d_yiwen,

R.drawable.d_youhengheng,

R.drawable.d_yun,

R.drawable.d_zhajipijiu,

R.drawable.d_zhuakuang,

R.drawable.d_zhutou,

R.drawable.d_zuiyou,

R.drawable.d_zuohengheng,

R.drawable.f_geili,

R.drawable.f_hufen,

R.drawable.f_jiong,

R.drawable.f_meng,

R.drawable.f_shenma,

R.drawable.f_v5,

R.drawable.f_xi,

R.drawable.f_zhi,

R.drawable.h_buyao,

R.drawable.h_good,

R.drawable.h_haha,

R.drawable.h_lai,

R.drawable.h_ok,

R.drawable.h_quantou,

R.drawable.h_ruo,

R.drawable.h_woshou,

R.drawable.h_ye,

R.drawable.h_zan,

R.drawable.h_zuoyi,

R.drawable.l_shangxin,

R.drawable.l_xin,

R.drawable.o_dangao,

R.drawable.o_feiji,

R.drawable.o_ganbei,

R.drawable.o_huatong,

R.drawable.o_lazhu,

R.drawable.o_liwu,

R.drawable.o_lvsidai,

R.drawable.o_weibo,

R.drawable.o_weiguan,

R.drawable.o_yinyue,

R.drawable.o_zhaoxiangji,

R.drawable.o_zhong,

R.drawable.w_fuyun,

R.drawable.w_shachenbao,

R.drawable.w_taiyang,

R.drawable.w_weifeng,

R.drawable.w_xianhua,

R.drawable.w_xiayu,

R.drawable.w_yueliang,

};

public static final String[] EmojiTextArray = {

"[爱你]",

"[奥特曼]",

"[拜拜]",

"[悲伤]",

"[鄙视]",

"[闭嘴]",

"[馋嘴]",

"[吃惊]",

"[哈欠]",

"[打脸]",

"[顶]",

"[doge]",

"[肥皂]",

"[感冒]",

"[鼓掌]",

"[哈哈]",

"[害羞]",

"[汗]",

"[微笑]",

"[黑线]",

"[哼]",

"[色]",

"[挤眼]",

"[可爱]",

"[可怜]",

"[酷]",

"[困]",

"[白眼]",

"[泪]",

"[马到成功]",

"[喵喵]",

"[男孩儿]",

"[怒]",

"[怒骂]",

"[女孩儿]",

"[钱]",

"[亲亲]",

"[傻眼]",

"[生病]",

"[草泥马]",

"[失望]",

"[衰]",

"[睡]",

"[思考]",

"[太开心]",

"[偷笑]",

"[吐]",

"[兔子]",

"[挖鼻]",

"[委屈]",

"[笑cry]",

"[熊猫]",

"[嘻嘻]",

"[嘘]",

"[阴险]",

"[疑问]",

"[右哼哼]",

"[晕]",

"[炸鸡啤酒]",

"[抓狂]",

"[猪头]",

"[最右]",

"[左哼哼]",

"[给力]",

"[互粉]",

"[囧]",

"[萌]",

"[神马]",

"[威武]",

"[喜]",

"[织]",

"[NO]",

"[good]",

"[haha]",

"[来]",

"[OK]",

"[拳头]",

"[弱]",

"[握手]",

"[耶]",

"[赞]",

"[作揖]",

"[伤心]",

"[心]",

"[蛋糕]",

"[飞机]",

"[干杯]",

"[话筒]",

"[蜡烛]",

"[礼物]",

"[绿丝带]",

"[围脖]",

"[围观]",

"[音乐]",

"[照相机]",

"[钟]",

"[浮云]",

"[沙尘暴]",

"[太阳]",

"[微风]",

"[鲜花]",

"[下雨]",

"[月亮]",

};

static {

emojiList = generateEmojis();

}

public static int calculateInSampleSize(BitmapFactory.Options options,

int reqWidth, int reqHeight) {

// 源图片的高度和宽度

final int height = options.outHeight;

final int width = options.outWidth;

int inSampleSize = 1;

if (height > reqHeight || width > reqWidth) {

// 计算出实际宽高和目标宽高的比率

final int heightRatio = Math.round((float) height / (float) reqHeight);

final int widthRatio = Math.round((float) width / (float) reqWidth);

// 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高

// 一定都会大于等于目标的宽和高。

inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;

}

return inSampleSize;

}

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,

int reqWidth, int reqHeight) {

// 第一次解析将inJustDecodeBounds设置为true,来获取图片大小

final BitmapFactory.Options options = new BitmapFactory.Options();

options.inJustDecodeBounds = true;

BitmapFactory.decodeResource(res, resId, options);

// 调用上面定义的方法计算inSampleSize值

options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

// 使用获取到的inSampleSize值再次解析图片

options.inJustDecodeBounds = false;

return BitmapFactory.decodeResource(res, resId, options);

}

public static int dip2px(Context context, float dipValue) {

final float scale = context.getResources().getDisplayMetrics().density;

return (int) (dipValue * scale + 0.5f);

}

//传递进来你所需要显示emoji的TextView即可

public static void handlerEmojiText(TextView comment, String content, Context context) throws IOException {

SpannableStringBuilder sb = new SpannableStringBuilder(content);

String regex = "\\[(\\S+?)\\]";

Pattern p = Pattern.compile(regex);

Matcher m = p.matcher(content);

Iterator iterator;

Emoji emoji = null;

while (m.find()) {

iterator = emojiList.iterator();

String tempText = m.group();

while (iterator.hasNext()) {

emoji = iterator.next();

if (tempText.equals(emoji.getContent())) {

//转换为Span并设置Span的大小

sb.setSpan(new ImageSpan(context, decodeSampledBitmapFromResource(context.getResources(), emoji.getImageUri()

, dip2px(context, 18), dip2px(context, 18))),

m.start(), m.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

break;

}

}

}

comment.setText(sb);

}

}

具体操作方法:

或者直接

compile'com.tb.emoji:yykEmoji:1.0.0'

谨此纪念那9月,一起开发的我们--谢遥,唐荣意,史琪锴。

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐