Rect r = new Rect(); /* * decorView是window中的最顶层view,可以从window中通过getDecorView获取到decorView。 * 通过decorView获取到程序显示的区域,包括标题栏,但不包括状态栏。 */ mActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r); //获取屏幕的高度 int screenHeight = mActivity.getWindow().getDecorView().getRootView().getHeight(); //计算软件盘的高度 int softInputHeight = screenHeight - r.bottom;
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/listview"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="0dp"
/>
<FrameLayout
android:id="@+id/fl_emotionview_main"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
/**
* 锁定内容高度,防止跳闪
*/
private void lockContentHeight(){
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mContentView.getLayoutParams();
params.height = mContentView.getHeight();
params.weight = 0.0F;
}
private void unlockContentHeightDelayed() {
mEditText.postDelayed(new Runnable() {
@Override
public void run() {
((LinearLayout.LayoutParams) mContentView.getLayoutParams()).weight = 1.0F;
}
}, 200L);
}
package com.zejian.emotionkeyboard.emotionkeyboardview;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Rect;
import android.os.Build;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.LinearLayout;
import com.zejian.emotionkeyboard.utils.LogUtils;
/**
* author : zejian
* time : 2016年1月5日 上午11:14:27
* email : shinezejian@163.com
* description :源码来自开源项目https://github.com/dss886/Android-EmotionInputDetector
* 本人仅做细微修改以及代码解析
*/
public class EmotionKeyboard {
private static final String SHARE_PREFERENCE_NAME = "EmotionKeyboard";
private static final String SHARE_PREFERENCE_SOFT_INPUT_HEIGHT = "soft_input_height";
private Activity mActivity;
private InputMethodManager mInputManager;//软键盘管理类
private SharedPreferences sp;
private View mEmotionLayout;//表情布局
private EditText mEditText;//
private View mContentView;//内容布局view,即除了表情布局或者软键盘布局以外的布局,用于固定bar的高度,防止跳闪
private EmotionKeyboard(){
}
/**
* 外部静态调用
* @param activity
* @return
*/
public static EmotionKeyboard with(Activity activity) {
EmotionKeyboard emotionInputDetector = new EmotionKeyboard();
emotionInputDetector.mActivity = activity;
emotionInputDetector.mInputManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
emotionInputDetector.sp = activity.getSharedPreferences(SHARE_PREFERENCE_NAME, Context.MODE_PRIVATE);
return emotionInputDetector;
}
/**
* 绑定内容view,此view用于固定bar的高度,防止跳闪
* @param contentView
* @return
*/
public EmotionKeyboard bindToContent(View contentView) {
mContentView = contentView;
return this;
}
/**
* 绑定编辑框
* @param editText
* @return
*/
public EmotionKeyboard bindToEditText(EditText editText) {
mEditText = editText;
mEditText.requestFocus();
mEditText.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP && mEmotionLayout.isShown()) {
lockContentHeight();//显示软件盘时,锁定内容高度,防止跳闪。
hideEmotionLayout(true);//隐藏表情布局,显示软件盘
//软件盘显示后,释放内容高度
mEditText.postDelayed(new Runnable() {
@Override
public void run() {
unlockContentHeightDelayed();
}
}, 200L);
}
return false;
}
});
return this;
}
/**
* 绑定表情按钮
* @param emotionButton
* @return
*/
public EmotionKeyboard bindToEmotionButton(View emotionButton) {
emotionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mEmotionLayout.isShown()) {
lockContentHeight();//显示软件盘时,锁定内容高度,防止跳闪。
hideEmotionLayout(true);//隐藏表情布局,显示软件盘
unlockContentHeightDelayed();//软件盘显示后,释放内容高度
} else {
if (isSoftInputShown()) {//同上
lockContentHeight();
showEmotionLayout();
unlockContentHeightDelayed();
} else {
showEmotionLayout();//两者都没显示,直接显示表情布局
}
}
}
});
return this;
}
/**
* 设置表情内容布局
* @param emotionView
* @return
*/
public EmotionKeyboard setEmotionView(View emotionView) {
mEmotionLayout = emotionView;
return this;
}
public EmotionKeyboard build(){
//设置软件盘的模式:SOFT_INPUT_ADJUST_RESIZE 这个属性表示Activity的主窗口总是会被调整大小,从而保证软键盘显示空间。
//从而方便我们计算软件盘的高度
mActivity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN |
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
//隐藏软件盘
hideSoftInput();
return this;
}
/**
* 点击返回键时先隐藏表情布局
* @return
*/
public boolean interceptBackPress() {
if (mEmotionLayout.isShown()) {
hideEmotionLayout(false);
return true;
}
return false;
}
private void showEmotionLayout() {
int softInputHeight = getSupportSoftInputHeight();
if (softInputHeight == 0) {
softInputHeight = sp.getInt(SHARE_PREFERENCE_SOFT_INPUT_HEIGHT, 400);
}
hideSoftInput();
mEmotionLayout.getLayoutParams().height = softInputHeight;
mEmotionLayout.setVisibility(View.VISIBLE);
}
/**
* 隐藏表情布局
* @param showSoftInput 是否显示软件盘
*/
private void hideEmotionLayout(boolean showSoftInput) {
if (mEmotionLayout.isShown()) {
mEmotionLayout.setVisibility(View.GONE);
if (showSoftInput) {
showSoftInput();
}
}
}
/**
* 锁定内容高度,防止跳闪
*/
private void lockContentHeight() {
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) mContentView.getLayoutParams();
params.height = mContentView.getHeight();
params.weight = 0.0F;
}
/**
* 释放被锁定的内容高度
*/
private void unlockContentHeightDelayed() {
mEditText.postDelayed(new Runnable() {
@Override
public void run() {
((LinearLayout.LayoutParams) mContentView.getLayoutParams()).weight = 1.0F;
}
}, 200L);
}
/**
* 编辑框获取焦点,并显示软件盘
*/
private void showSoftInput() {
mEditText.requestFocus();
mEditText.post(new Runnable() {
@Override
public void run() {
mInputManager.showSoftInput(mEditText, 0);
}
});
}
/**
* 隐藏软件盘
*/
private void hideSoftInput() {
mInputManager.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
}
/**
* 是否显示软件盘
* @return
*/
private boolean isSoftInputShown() {
return getSupportSoftInputHeight() != 0;
}
/**
* 获取软件盘的高度
* @return
*/
private int getSupportSoftInputHeight() {
Rect r = new Rect();
/**
* decorView是window中的最顶层view,可以从window中通过getDecorView获取到decorView。
* 通过decorView获取到程序显示的区域,包括标题栏,但不包括状态栏。
*/
mActivity.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
//获取屏幕的高度
int screenHeight = mActivity.getWindow().getDecorView().getRootView().getHeight();
//计算软件盘的高度
int softInputHeight = screenHeight - r.bottom;
/**
* 某些Android版本下,没有显示软键盘时减出来的高度总是144,而不是零,
* 这是因为高度是包括了虚拟按键栏的(例如华为系列),所以在API Level高于20时,
* 我们需要减去底部虚拟按键栏的高度(如果有的话)
*/
if (Build.VERSION.SDK_INT >= 20) {
// When SDK Level >= 20 (Android L), the softInputHeight will contain the height of softButtonsBar (if has)
softInputHeight = softInputHeight - getSoftButtonsBarHeight();
}
if (softInputHeight < 0) {
LogUtils.w("EmotionKeyboard--Warning: value of softInputHeight is below zero!");
}
//存一份到本地
if (softInputHeight > 0) {
sp.edit().putInt(SHARE_PREFERENCE_SOFT_INPUT_HEIGHT, softInputHeight).apply();
}
return softInputHeight;
}
/**
* 底部虚拟按键栏的高度
* @return
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
private int getSoftButtonsBarHeight() {
DisplayMetrics metrics = new DisplayMetrics();
//这个方法获取可能不是真实屏幕的高度
mActivity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
int usableHeight = metrics.heightPixels;
//获取当前屏幕的真实高度
mActivity.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
int realHeight = metrics.heightPixels;
if (realHeight > usableHeight) {
return realHeight - usableHeight;
} else {
return 0;
}
}
/**
* 获取软键盘高度
* @return
*/
public int getKeyBoardHeight(){
return sp.getInt(SHARE_PREFERENCE_SOFT_INPUT_HEIGHT, 400);
}
}
/**
* 绑定表情按钮
* @param emotionButton
* @return
*/
public EmotionKeyboard bindToEmotionButton(View emotionButton) {
emotionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mEmotionLayout.isShown()) {
lockContentHeight();//显示软件盘时,锁定内容高度,防止跳闪。
hideEmotionLayout(true);//隐藏表情布局,显示软件盘
unlockContentHeightDelayed();//软件盘显示后,释放内容高度
} else {
if (isSoftInputShown()) {//同上
lockContentHeight();
showEmotionLayout();
unlockContentHeightDelayed();
} else {
showEmotionLayout();//两者都没显示,直接显示表情布局
}
}
}
});
return this;
}
mEmotionKeyboard = EmotionKeyboard.with(getActivity())
.setEmotionView(rootView.findViewById(R.id.ll_emotion_layout))//绑定表情面板
.bindToContent(contentView)//绑定内容view
.bindToEditText(!isBindToBarEditText ? ((EditText) contentView) : ((EditText) rootView.findViewById(R.id.bar_edit_text)))//判断绑定那种EditView
.bindToEmotionButton(rootView.findViewById(R.id.emotion_button))//绑定表情按钮
.build();
package com.zejian.emotionkeyboard.emotionkeyboardview;
import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
/**
* Created by zejian
* Time 16/1/7 上午11:12
* Email shinezejian@163.com
* Description:不可横向滑动的ViewPager
*/
public class NoHorizontalScrollerViewPager extends ViewPager{
public NoHorizontalScrollerViewPager(Context context) {
super(context);
}
public NoHorizontalScrollerViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
}
/**
* 重写拦截事件,返回值设置为false,这时便不会横向滑动了。
* @param ev
* @return
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return false;
}
/**
* 重写拦截事件,返回值设置为false,这时便不会横向滑动了。
* @param ev
* @return
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
return false;
}
}
package com.zejian.emotionkeyboard.utils;
import android.support.v4.util.ArrayMap;
import com.zejian.emotionkeyboard.R;
/**
* @author : zejian
* @time : 2016年1月5日 上午11:32:33
* @email : shinezejian@163.com
* @description :表情加载类,可自己添加多种表情,分别建立不同的map存放和不同的标志符即可
*/
public class EmotionUtils {
/**
* 表情类型标志符
*/
public static final int EMOTION_CLASSIC_TYPE=0x0001;//经典表情
/**
* key-表情文字;
* value-表情图片资源
*/
public static ArrayMap<String, Integer> EMPTY_MAP;
public static ArrayMap<String, Integer> EMOTION_CLASSIC_MAP;
static {
EMPTY_MAP = new ArrayMap<>();
EMOTION_CLASSIC_MAP = new ArrayMap<>();
EMOTION_CLASSIC_MAP.put("[呵呵]", R.drawable.d_hehe);
EMOTION_CLASSIC_MAP.put("[嘻嘻]", R.drawable.d_xixi);
EMOTION_CLASSIC_MAP.put("[哈哈]", R.drawable.d_haha);
EMOTION_CLASSIC_MAP.put("[爱你]", R.drawable.d_aini);
EMOTION_CLASSIC_MAP.put("[挖鼻屎]", R.drawable.d_wabishi);
EMOTION_CLASSIC_MAP.put("[吃惊]", R.drawable.d_chijing);
EMOTION_CLASSIC_MAP.put("[晕]", R.drawable.d_yun);
EMOTION_CLASSIC_MAP.put("[泪]", R.drawable.d_lei);
EMOTION_CLASSIC_MAP.put("[馋嘴]", R.drawable.d_chanzui);
EMOTION_CLASSIC_MAP.put("[抓狂]", R.drawable.d_zhuakuang);
EMOTION_CLASSIC_MAP.put("[哼]", R.drawable.d_heng);
EMOTION_CLASSIC_MAP.put("[可爱]", R.drawable.d_keai);
EMOTION_CLASSIC_MAP.put("[怒]", R.drawable.d_nu);
EMOTION_CLASSIC_MAP.put("[汗]", R.drawable.d_han);
EMOTION_CLASSIC_MAP.put("[害羞]", R.drawable.d_haixiu);
EMOTION_CLASSIC_MAP.put("[睡觉]", R.drawable.d_shuijiao);
EMOTION_CLASSIC_MAP.put("[钱]", R.drawable.d_qian);
EMOTION_CLASSIC_MAP.put("[偷笑]", R.drawable.d_touxiao);
EMOTION_CLASSIC_MAP.put("[笑cry]", R.drawable.d_xiaoku);
EMOTION_CLASSIC_MAP.put("[doge]", R.drawable.d_doge);
EMOTION_CLASSIC_MAP.put("[喵喵]", R.drawable.d_miao);
EMOTION_CLASSIC_MAP.put("[酷]", R.drawable.d_ku);
EMOTION_CLASSIC_MAP.put("[衰]", R.drawable.d_shuai);
EMOTION_CLASSIC_MAP.put("[闭嘴]", R.drawable.d_bizui);
EMOTION_CLASSIC_MAP.put("[鄙视]", R.drawable.d_bishi);
EMOTION_CLASSIC_MAP.put("[花心]", R.drawable.d_huaxin);
EMOTION_CLASSIC_MAP.put("[鼓掌]", R.drawable.d_guzhang);
EMOTION_CLASSIC_MAP.put("[悲伤]", R.drawable.d_beishang);
EMOTION_CLASSIC_MAP.put("[思考]", R.drawable.d_sikao);
EMOTION_CLASSIC_MAP.put("[生病]", R.drawable.d_shengbing);
EMOTION_CLASSIC_MAP.put("[亲亲]", R.drawable.d_qinqin);
EMOTION_CLASSIC_MAP.put("[怒骂]", R.drawable.d_numa);
EMOTION_CLASSIC_MAP.put("[太开心]", R.drawable.d_taikaixin);
EMOTION_CLASSIC_MAP.put("[懒得理你]", R.drawable.d_landelini);
EMOTION_CLASSIC_MAP.put("[右哼哼]", R.drawable.d_youhengheng);
EMOTION_CLASSIC_MAP.put("[左哼哼]", R.drawable.d_zuohengheng);
EMOTION_CLASSIC_MAP.put("[嘘]", R.drawable.d_xu);
EMOTION_CLASSIC_MAP.put("[委屈]", R.drawable.d_weiqu);
EMOTION_CLASSIC_MAP.put("[吐]", R.drawable.d_tu);
EMOTION_CLASSIC_MAP.put("[可怜]", R.drawable.d_kelian);
EMOTION_CLASSIC_MAP.put("[打哈气]", R.drawable.d_dahaqi);
EMOTION_CLASSIC_MAP.put("[挤眼]", R.drawable.d_jiyan);
EMOTION_CLASSIC_MAP.put("[失望]", R.drawable.d_shiwang);
EMOTION_CLASSIC_MAP.put("[顶]", R.drawable.d_ding);
EMOTION_CLASSIC_MAP.put("[疑问]", R.drawable.d_yiwen);
EMOTION_CLASSIC_MAP.put("[困]", R.drawable.d_kun);
EMOTION_CLASSIC_MAP.put("[感冒]", R.drawable.d_ganmao);
EMOTION_CLASSIC_MAP.put("[拜拜]", R.drawable.d_baibai);
EMOTION_CLASSIC_MAP.put("[黑线]", R.drawable.d_heixian);
EMOTION_CLASSIC_MAP.put("[阴险]", R.drawable.d_yinxian);
EMOTION_CLASSIC_MAP.put("[打脸]", R.drawable.d_dalian);
EMOTION_CLASSIC_MAP.put("[傻眼]", R.drawable.d_shayan);
EMOTION_CLASSIC_MAP.put("[猪头]", R.drawable.d_zhutou);
EMOTION_CLASSIC_MAP.put("[熊猫]", R.drawable.d_xiongmao);
EMOTION_CLASSIC_MAP.put("[兔子]", R.drawable.d_tuzi);
}
/**
* 根据名称获取当前表情图标R值
* @param EmotionType 表情类型标志符
* @param imgName 名称
* @return
*/
public static int getImgByName(int EmotionType,String imgName) {
Integer integer=null;
switch (EmotionType){
case EMOTION_CLASSIC_TYPE:
integer = EMOTION_CLASSIC_MAP.get(imgName);
break;
default:
LogUtils.e("the emojiMap is null!!");
break;
}
return integer == null ? -1 : integer;
}
/**
* 根据类型获取表情数据
* @param EmotionType
* @return
*/
public static ArrayMap<String, Integer> getEmojiMap(int EmotionType){
ArrayMap EmojiMap=null;
switch (EmotionType){
case EMOTION_CLASSIC_TYPE:
EmojiMap=EMOTION_CLASSIC_MAP;
break;
default:
EmojiMap=EMPTY_MAP;
break;
}
return EmojiMap;
}
}
/**
* 获取fragment的方法
* @param emotionType 表情类型,用于判断使用哪个map集合的表情
*/
public Fragment getFragment(int emotionType){
Bundle bundle = new Bundle();
bundle.putInt(FragmentFactory.EMOTION_MAP_TYPE,emotionType);
EmotiomComplateFragment fragment= EmotiomComplateFragment.newInstance(EmotiomComplateFragment.class,bundle);
return fragment;
}
//创建fragment的工厂类 FragmentFactory factory=FragmentFactory.getSingleFactoryInstance(); //创建修改实例 EmotiomComplateFragment f1= (EmotiomComplateFragment) factory.getFragment(EmotionUtils.EMOTION_CLASSIC_TYPE);
SpannableString spannableString = new SpannableString(source); int size = (int) tv.getTextSize()*13/10; Bitmap bitmap = BitmapFactory.decodeResource(res, imgRes); Bitmap scaleBitmap = Bitmap.createScaledBitmap(bitmap, size, size, true); ImageSpan span = new ImageSpan(context, scaleBitmap); spannableString.setSpan(span, start, start + key.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
package com.zejian.emotionkeyboard.utils;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ImageSpan;
import android.widget.TextView;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author : zejian
* @time : 2016年1月5日 上午11:30:39
* @email : shinezejian@163.com
* @description :文本中的emojb字符处理为表情图片
*/
public class SpanStringUtils {
public static SpannableString getEmotionContent(int emotion_map_type,final Context context, final TextView tv, String source) {
SpannableString spannableString = new SpannableString(source);
Resources res = context.getResources();
String regexEmotion = "\\[([\u4e00-\u9fa5\\w])+\\]";
Pattern patternEmotion = Pattern.compile(regexEmotion);
Matcher matcherEmotion = patternEmotion.matcher(spannableString);
while (matcherEmotion.find()) {
// 获取匹配到的具体字符
String key = matcherEmotion.group();
// 匹配字符串的开始位置
int start = matcherEmotion.start();
// 利用表情名字获取到对应的图片
Integer imgRes = EmotionUtils.getImgByName(emotion_map_type,key);
if (imgRes != null) {
// 压缩表情图片
int size = (int) tv.getTextSize()*13/10;
Bitmap bitmap = BitmapFactory.decodeResource(res, imgRes);
Bitmap scaleBitmap = Bitmap.createScaledBitmap(bitmap, size, size, true);
ImageSpan span = new ImageSpan(context, scaleBitmap);
spannableString.setSpan(span, start, start + key.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
return spannableString;
}
}
package com.zejian.emotionkeyboard.fragment;
import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.GridView;
import android.widget.LinearLayout;
import com.zejian.emotionkeyboard.R;
import com.zejian.emotionkeyboard.adapter.EmotionGridViewAdapter;
import com.zejian.emotionkeyboard.adapter.EmotionPagerAdapter;
import com.zejian.emotionkeyboard.emotionkeyboardview.EmojiIndicatorView;
import com.zejian.emotionkeyboard.utils.DisplayUtils;
import com.zejian.emotionkeyboard.utils.EmotionUtils;
import com.zejian.emotionkeyboard.utils.GlobalOnItemClickManagerUtils;
import java.util.ArrayList;
import java.util.List;
/**
* Created by zejian
* Time 16/1/5 下午4:32
* Email shinezejian@163.com
* Description:可替换的模板表情,gridview实现
*/
public class EmotiomComplateFragment extends BaseFragment {
private EmotionPagerAdapter emotionPagerGvAdapter;
private ViewPager vp_complate_emotion_layout;
private EmojiIndicatorView ll_point_group;//表情面板对应的点列表
private int emotion_map_type;
/**
* 创建与Fragment对象关联的View视图时调用
* @param inflater
* @param container
* @param savedInstanceState
* @return
*/
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_complate_emotion, container, false);
initView(rootView);
initListener();
return rootView;
}
/**
* 初始化view控件
*/
protected void initView(View rootView){
vp_complate_emotion_layout = (ViewPager) rootView.findViewById(R.id.vp_complate_emotion_layout);
ll_point_group= (EmojiIndicatorView) rootView.findViewById(R.id.ll_point_group);
//获取map的类型
emotion_map_type=args.getInt(FragmentFactory.EMOTION_MAP_TYPE);
initEmotion();
}
/**
* 初始化监听器
*/
protected void initListener(){
vp_complate_emotion_layout.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
int oldPagerPos=0;
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
ll_point_group.playByStartPointToNext(oldPagerPos,position);
oldPagerPos=position;
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
}
/**
* 初始化表情面板
* 思路:获取表情的总数,按每行存放7个表情,动态计算出每个表情所占的宽度大小(包含间距),
* 而每个表情的高与宽应该是相等的,这里我们约定只存放3行
* 每个面板最多存放7*3=21个表情,再减去一个删除键,即每个面板包含20个表情
* 根据表情总数,循环创建多个容量为20的List,存放表情,对于大小不满20进行特殊
* 处理即可。
*/
private void initEmotion() {
// 获取屏幕宽度
int screenWidth = DisplayUtils.getScreenWidthPixels(getActivity());
// item的间距
int spacing = DisplayUtils.dp2px(getActivity(), 12);
// 动态计算item的宽度和高度
int itemWidth = (screenWidth - spacing * 8) / 7;
//动态计算gridview的总高度
int gvHeight = itemWidth * 3 + spacing * 6;
List<GridView> emotionViews = new ArrayList<>();
List<String> emotionNames = new ArrayList<>();
// 遍历所有的表情的key
for (String emojiName : EmotionUtils.getEmojiMap(emotion_map_type).keySet()) {
emotionNames.add(emojiName);
// 每20个表情作为一组,同时添加到ViewPager对应的view集合中
if (emotionNames.size() == 20) {
GridView gv = createEmotionGridView(emotionNames, screenWidth, spacing, itemWidth, gvHeight);
emotionViews.add(gv);
// 添加完一组表情,重新创建一个表情名字集合
emotionNames = new ArrayList<>();
}
}
// 判断最后是否有不足20个表情的剩余情况
if (emotionNames.size() > 0) {
GridView gv = createEmotionGridView(emotionNames, screenWidth, spacing, itemWidth, gvHeight);
emotionViews.add(gv);
}
//初始化指示器
ll_point_group.initIndicator(emotionViews.size());
// 将多个GridView添加显示到ViewPager中
emotionPagerGvAdapter = new EmotionPagerAdapter(emotionViews);
vp_complate_emotion_layout.setAdapter(emotionPagerGvAdapter);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(screenWidth, gvHeight);
vp_complate_emotion_layout.setLayoutParams(params);
}
/**
* 创建显示表情的GridView
*/
private GridView createEmotionGridView(List<String> emotionNames, int gvWidth, int padding, int itemWidth, int gvHeight) {
// 创建GridView
GridView gv = new GridView(getActivity());
//设置点击背景透明
gv.setSelector(android.R.color.transparent);
//设置7列
gv.setNumColumns(7);
gv.setPadding(padding, padding, padding, padding);
gv.setHorizontalSpacing(padding);
gv.setVerticalSpacing(padding * 2);
//设置GridView的宽高
ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(gvWidth, gvHeight);
gv.setLayoutParams(params);
// 给GridView设置表情图片
EmotionGridViewAdapter adapter = new EmotionGridViewAdapter(getActivity(), emotionNames, itemWidth,emotion_map_type);
gv.setAdapter(adapter);
//设置全局点击事件
gv.setOnItemClickListener(GlobalOnItemClickManagerUtils.getInstance(getActivity()).getOnItemClickListener(emotion_map_type));
return gv;
}
}
// 点击的是表情
EmotionGridViewAdapter emotionGvAdapter = (EmotionGridViewAdapter) itemAdapter;
if (position == emotionGvAdapter.getCount() - 1) {
// 如果点击了最后一个回退按钮,则调用删除键事件
mEditText.dispatchKeyEvent(new KeyEvent(
KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
} else {
// 如果点击了表情,则添加到输入框中
String emotionName = emotionGvAdapter.getItem(position);
// 获取当前光标位置,在指定位置上添加表情图片文本
int curPosition = mEditText.getSelectionStart();
StringBuilder sb = new StringBuilder(mEditText.getText().toString());
sb.insert(curPosition, emotionName);
// 特殊文字处理,将表情等转换一下
mEditText.setText(SpanStringUtils.getEmotionContent(emotion_map_type,
mContext, mEditText, sb.toString()));
// 将光标设置到新增完表情的右侧
mEditText.setSelection(curPosition + emotionName.length());
}
package com.zejian.emotionkeyboard.utils;
import android.content.Context;
import android.view.KeyEvent;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import com.zejian.emotionkeyboard.adapter.EmotionGridViewAdapter;
/**
* Created by zejian
* Time 16/1/8 下午5:05
* Email shinezejian@163.com
* Description:点击表情的全局监听管理类
*/
public class GlobalOnItemClickManagerUtils {
private static GlobalOnItemClickManagerUtils instance;
private EditText mEditText;//输入框
private static Context mContext;
public static GlobalOnItemClickManagerUtils getInstance(Context context) {
mContext=context;
if (instance == null) {
synchronized (GlobalOnItemClickManagerUtils.class) {
if(instance == null) {
instance = new GlobalOnItemClickManagerUtils();
}
}
}
return instance;
}
public void attachToEditText(EditText editText) {
mEditText = editText;
}
public AdapterView.OnItemClickListener getOnItemClickListener(final int emotion_map_type) {
return new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Object itemAdapter = parent.getAdapter();
if (itemAdapter instanceof EmotionGridViewAdapter) {
// 点击的是表情
EmotionGridViewAdapter emotionGvAdapter = (EmotionGridViewAdapter) itemAdapter;
if (position == emotionGvAdapter.getCount() - 1) {
// 如果点击了最后一个回退按钮,则调用删除键事件
mEditText.dispatchKeyEvent(new KeyEvent(
KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL));
} else {
// 如果点击了表情,则添加到输入框中
String emotionName = emotionGvAdapter.getItem(position);
// 获取当前光标位置,在指定位置上添加表情图片文本
int curPosition = mEditText.getSelectionStart();
StringBuilder sb = new StringBuilder(mEditText.getText().toString());
sb.insert(curPosition, emotionName);
// 特殊文字处理,将表情等转换一下
mEditText.setText(SpanStringUtils.getEmotionContent(emotion_map_type,
mContext, mEditText, sb.toString()));
// 将光标设置到新增完表情的右侧
mEditText.setSelection(curPosition + emotionName.length());
}
}
}
};
}
}
//创建全局监听
GlobalOnItemClickManagerUtils globalOnItemClickManager= GlobalOnItemClickManagerUtils.getInstance(getActivity());
if(isBindToBarEditText){
//绑定当前Bar的编辑框
globalOnItemClickManager.attachToEditText(bar_edit_text);
}else{
// false,则表示绑定contentView, 此时外部提供的contentView必定也是EditText
globalOnItemClickManager.attachToEditText((EditText) contentView);
mEmotionKeyboard.bindToEditText((EditText)contentView);
}
//设置全局点击事件 gv.setOnItemClickListener(GlobalOnItemClickManagerUtils.getInstance(getActivity()).getOnItemClickListener(emotion_map_type));
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有