android 调出键盘表情_Android 解决表情面板和软键盘切换时跳闪的问题

本文介绍了如何解决Android应用中在显示表情面板时,与软键盘切换导致的表情面板跳闪问题。通过保持表情面板高度与软键盘一致并固定内容输入框位置,实现平滑切换的效果,提供了具体的实现类`EmojiKeyboard`及其关键方法的详细说明。
摘要由CSDN通过智能技术生成

现在很多应用都会在让用户输入各种文本信息的时候同时多提供一个表情面板,这样就会出现一个问题,即表情面板的跳闪问题

要输入文本信息,那固然是需要弹出软键盘,在软键盘显示的情况下,此时如果要切换显示出表情面板,由于表情面板不可能和用户的软键盘高度恰好一样,此外由于控件的上下移位,就会出现表情面板的跳闪现象

在点击切换按钮的时候,表情面板会先向上跳,然后再往下移,这样就会带来很差的用户体验,效果如下图所示:

这里提供一个解决方案,使软键盘和表情面板可以很自然地切换,效果如下图所示:

解决思路主要是这样:系统在弹出软键盘时,会将内容输入框View以及其之上的View都给顶上去,当切换到表情面板时,只有将表情面板的高度保持为和软键盘的高度一致,才能自然地切换。此外,还需要将内容输入框View以及其之上的View的位置固定住,这样才不会出现跳闪问题

主要的操作逻辑都在 EmojiKeyboard 类中

/**

* 作者: chenZY

* 时间: 2017/8/26 18:12

* 描述:

*/

public class EmojiKeyboard {

private Activity activity;

//文本输入框

private EditText editText;

//表情面板

private View emojiPanelView;

//内容View,即除了表情布局和输入框布局以外的布局

//用于固定输入框一行的高度以防止跳闪

private View contentView;

private InputMethodManager inputMethodManager;

private SharedPreferences sharedPreferences;

private static final String EMOJI_KEYBOARD = "EmojiKeyboard";

private static final String KEY_SOFT_KEYBOARD_HEIGHT = "SoftKeyboardHeight";

private static final int SOFT_KEYBOARD_HEIGHT_DEFAULT = 654;

private Handler handler;

public EmojiKeyboard(Activity activity, EditText editText, View emojiPanelView, View emojiPanelSwitchView, View contentView) {

init(activity, editText, emojiPanelView, emojiPanelSwitchView, contentView);

}

private void init(Activity activity, EditText editText, View emojiPanelView, View emojiPanelSwitchView, View contentView) {

this.activity = activity;

this.editText = editText;

this.emojiPanelView = emojiPanelView;

this.contentView = contentView;

this.editText.setOnTouchListener(new View.OnTouchListener() {

@Override

public boolean onTouch(final View v, MotionEvent event) {

if (event.getAction() == MotionEvent.ACTION_UP && EmojiKeyboard.this.emojiPanelView.isShown()) {

lockContentViewHeight();

hideEmojiPanel(true);

unlockContentViewHeight();

}

return false;

}

});

this.contentView.setOnTouchListener(new View.OnTouchListener() {

@Override

public boolean onTouch(View view, MotionEvent motionEvent) {

if (motionEvent.getAction() == MotionEvent.ACTION_UP) {

if (EmojiKeyboard.this.emojiPanelView.isShown()) {

hideEmojiPanel(false);

} else if (isSoftKeyboardShown()) {

hideSoftKeyboard();

}

}

return false;

}

});

//用于弹出表情面板的View

emojiPanelSwitchView.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

if (EmojiKeyboard.this.emojiPanelView.isShown()) {

lockContentViewHeight();

hideEmojiPanel(true);

unlockContentViewHeight();

} else {

if (isSoftKeyboardShown()) {

lockContentViewHeight();

showEmojiPanel();

unlockContentViewHeight();

} else {

showEmojiPanel();

}

}

}

});

this.inputMethodManager = (InputMethodManager) this.activity.getSystemService(Context.INPUT_METHOD_SERVICE);

this.sharedPreferences = this.activity.getSharedPreferences(EMOJI_KEYBOARD, Context.MODE_PRIVATE);

this.activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

this.handler = new Handler();

init();

}

/**

* 如果之前没有保存过键盘高度值

* 则在进入Activity时自动打开键盘,并把高度值保存下来

*/

private void init() {

if (!sharedPreferences.contains(KEY_SOFT_KEYBOARD_HEIGHT)) {

handler.postDelayed(new Runnable() {

@Override

public void run() {

showSoftKeyboard(true);

}

}, 200);

}

}

/**

* 当点击返回键时需要先隐藏表情面板

*/

public boolean interceptBackPress() {

if (emojiPanelView.isShown()) {

hideEmojiPanel(false);

return true;

}

return false;

}

/**

* 锁定内容View以防止跳闪

*/

private void lockContentViewHeight() {

LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) contentView.getLayoutParams();

layoutParams.height = contentView.getHeight();

layoutParams.weight = 0;

}

/**

* 释放锁定的内容View

*/

private void unlockContentViewHeight() {

handler.postDelayed(new Runnable() {

@Override

public void run() {

((LinearLayout.LayoutParams) contentView.getLayoutParams()).weight = 1;

}

}, 200);

}

/**

* 获取键盘的高度

*/

private int getSoftKeyboardHeight() {

Rect rect = new Rect();

activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);

//屏幕当前可见高度,不包括状态栏

int displayHeight = rect.bottom - rect.top;

//屏幕可用高度

int availableHeight = ScreenUtils.getAvailableScreenHeight(activity);

//用于计算键盘高度

int softInputHeight = availableHeight - displayHeight - ScreenUtils.getStatusBarHeight(activity);

Log.e("TAG-di", displayHeight + "");

Log.e("TAG-av", availableHeight + "");

Log.e("TAG-so", softInputHeight + "");

if (softInputHeight != 0) {

// 因为考虑到用户可能会主动调整键盘高度,所以只能是每次获取到键盘高度时都将其存储起来

sharedPreferences.edit().putInt(KEY_SOFT_KEYBOARD_HEIGHT, softInputHeight).apply();

}

return softInputHeight;

}

/**

* 获取本地存储的键盘高度值或者是返回默认值

*/

private int getSoftKeyboardHeightLocalValue() {

return sharedPreferences.getInt(KEY_SOFT_KEYBOARD_HEIGHT, SOFT_KEYBOARD_HEIGHT_DEFAULT);

}

/**

* 判断是否显示了键盘

*/

private boolean isSoftKeyboardShown() {

return getSoftKeyboardHeight() != 0;

}

/**

* 令编辑框获取焦点并显示键盘

*/

private void showSoftKeyboard(boolean saveSoftKeyboardHeight) {

editText.requestFocus();

inputMethodManager.showSoftInput(editText, 0);

if (saveSoftKeyboardHeight) {

handler.postDelayed(new Runnable() {

@Override

public void run() {

getSoftKeyboardHeight();

}

}, 200);

}

}

/**

* 隐藏键盘

*/

private void hideSoftKeyboard() {

inputMethodManager.hideSoftInputFromWindow(editText.getWindowToken(), 0);

}

/**

* 显示表情面板

*/

private void showEmojiPanel() {

int softKeyboardHeight = getSoftKeyboardHeight();

if (softKeyboardHeight == 0) {

softKeyboardHeight = getSoftKeyboardHeightLocalValue();

} else {

hideSoftKeyboard();

}

emojiPanelView.getLayoutParams().height = softKeyboardHeight;

emojiPanelView.setVisibility(View.VISIBLE);

if (emojiPanelVisibilityChangeListener != null) {

emojiPanelVisibilityChangeListener.onShowEmojiPanel();

}

}

/**

* 隐藏表情面板,同时指定是否随后开启键盘

*/

private void hideEmojiPanel(boolean showSoftKeyboard) {

if (emojiPanelView.isShown()) {

emojiPanelView.setVisibility(View.GONE);

if (showSoftKeyboard) {

showSoftKeyboard(false);

}

if (emojiPanelVisibilityChangeListener != null) {

emojiPanelVisibilityChangeListener.onHideEmojiPanel();

}

}

}

public interface OnEmojiPanelVisibilityChangeListener {

void onShowEmojiPanel();

void onHideEmojiPanel();

}

private OnEmojiPanelVisibilityChangeListener emojiPanelVisibilityChangeListener;

public void setEmoticonPanelVisibilityChangeListener(OnEmojiPanelVisibilityChangeListener emojiPanelVisibilityChangeListener) {

this.emojiPanelVisibilityChangeListener = emojiPanelVisibilityChangeListener;

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值