在搭建聊天页面的时候,软键盘和表情布局,选图片布局以及语音布局切换的时,会出现布局跳动的现象,这里github上找了一个大牛写的自定义控件,完美解决了这个问题,我把Studio上的项目转移到的IDEA上,并写成了依赖包。
首先,为了在聊天页面第一次弹出表情或者其他布局时,高度是和软件盘的高度一致,需要在聊天页面之前,有软键盘弹出的地方,保存一下软键盘的高度,一般选在登录或者注册页面,添加一个方法即可。。。。
<span style="font-size:18px;">/**
* 获取软键盘的高度并保存
*/
private void saveKeyBoardHeight(){
final View decorView = getWindow().getDecorView();
decorView.getViewTreeObserver().
addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
/**
* the result is pixels
*/
@Override
public void onGlobalLayout() {
Rect r = new Rect();
decorView.getWindowVisibleDisplayFrame(r);
int screenHeight = decorView.getRootView().getHeight();
int heightDifference = screenHeight - (r.bottom - r.top);
Log.e("KeyboardSize", "KeyboardSize: " + heightDifference);
if (heightDifference > 200){
KeyboardUtil.saveKeyboardHeight(MyActivity.this, heightDifference - r.top);
}
}
});
}</span>
其次,在聊天的页面加入两段代码:
<span style="font-size:18px;">/**
* 这个方法是布局和软键盘平缓切换的关键
*/
KeyboardUtil.attach(this, mPanelRoot,
// Add keyboard showing state callback, do like this when you want to listen in the
// keyboard's show/hide change.
new KeyboardUtil.OnKeyboardShowingListener() {
@Override
public void onKeyboardShowing(boolean isShowing) {
Log.d(TAG, String.format("Keyboard is %s", isShowing ? "showing" : "hiding"));
}
});
KPSwitchConflictUtil.attach(mPanelRoot, mPlusIv,mVoiceIv,null,mSendEdt,
new KPSwitchConflictUtil.SwitchClickListener() {
@Override
public void onClickSwitch(boolean switchToPanel, int flag) {
if (switchToPanel) {
mSendEdt.clearFocus();
// flag 标志位
// 显示那个布局自己定
if (flag == 1){
layout1.setVisibility(View.VISIBLE);
layout2.setVisibility(View.GONE);
}else{
layout1.setVisibility(View.GONE);
layout2.setVisibility(View.VISIBLE);
}
} else {
mSendEdt.requestFocus();
Log.d("switchToPanel"," false == "+flag);
}
}
});</span>
页面切换的逻辑关键代码在 KPSwitchConflictUtil的attach方法中:
public static void attach(/** 根布局 **/final View panelLayout,
/** 点击btn **/final View switchBtnOne,
/** 点击btn **/final View switchBtnTwo,
/** 点击btn **/final View switchBtnThree,
/** Edittext **/final View focusView,
/** Nullable **/final SwitchClickListener switchClickListener) {
final Activity activity = (Activity) panelLayout.getContext();
if (switchBtnOne != null) {
switchBtnOne.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int flag = 1;
// 如果显示的是软键盘
if (mFlag == 0){
if (switchClickListener != null) {
switchClickListener.onClickSwitch(true,flag);
}
showPanel(panelLayout);
mFlag = flag;
}else if (mFlag == flag){
if (switchClickListener != null) {
switchClickListener.onClickSwitch(false,flag);
}
showKeyboard(panelLayout, focusView);
}else{
if (switchClickListener != null) {
switchClickListener.onClickSwitch(true,flag);
}
showPanel(panelLayout);
mFlag = flag;
}
}
});
}
if (switchBtnTwo != null) {
switchBtnTwo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Log.d("mFlag", " switchBtnTwo mFlag == " + mFlag);
int flag = 2;
if (mFlag == 0){
if (switchClickListener != null) {
switchClickListener.onClickSwitch(true,flag);
}
showPanel(panelLayout);
mFlag = flag;
}else if (mFlag == flag){
if (switchClickListener != null) {
switchClickListener.onClickSwitch(false,flag);
}
showKeyboard(panelLayout, focusView);
}else{
if (switchClickListener != null) {
switchClickListener.onClickSwitch(true,flag);
}
showPanel(panelLayout);
mFlag = flag;
}
}
});
}
if (switchBtnThree != null) {
switchBtnThree.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int flag = 3;
if (mFlag == 0){
if (switchClickListener != null) {
switchClickListener.onClickSwitch(true,flag);
}
showPanel(panelLayout);
mFlag = flag;
}else if (mFlag == flag){
if (switchClickListener != null) {
switchClickListener.onClickSwitch(false,flag);
}
showKeyboard(panelLayout, focusView);
}else{
if (switchClickListener != null) {
switchClickListener.onClickSwitch(true,flag);
}
showPanel(panelLayout);
mFlag = flag;
}
}
});
}
if (isHandleByPlaceholder(activity)) {
focusView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
/**
* Show the fake empty keyboard-same-height panel to fix the conflict when
* keyboard going to show.
* @see KPSwitchConflictUtil#showKeyboard(View, View)
*/
panelLayout.setVisibility(View.INVISIBLE);
}
return false;
}
});
}
}
原本的逻辑被我修改一下,因为他只有一个布局,考虑到我们的项目需要表情、图片、语音三部分,所以修改成三个布局和软键盘切换。如果需要更多可在这里继续添加,如果不需要三个,传入null即可。
<span style="font-size:18px;">mSendEdt.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
KPSwitchConflictUtil.mFlag = 0;
}
return false;
}
});</span>
源码地址:http://download.youkuaiyun.com/detail/qq55214/9566481