Created
August 9, 2016 08:20
-
-
Save panthole/f70e6bdcf1fbcf12a629a87c0f568e5d to your computer and use it in GitHub Desktop.
Android 监听软键盘弹起消失的布局
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.content.Context; | |
import android.util.AttributeSet; | |
import android.util.DisplayMetrics; | |
import android.view.WindowManager; | |
import android.widget.RelativeLayout; | |
import java.util.ArrayList; | |
public class SoftListenLayout extends RelativeLayout { | |
private OnKeyboardChangedListener onKeyboardChangedListener; | |
private int mMaxParentHeight = 0; | |
private ArrayList<Integer> heightList = new ArrayList<>(); | |
private int mOldHeight = 0; | |
private int mMinLayoutHeight = 0; | |
private int mMaxNavBarHeight = 0; | |
public SoftListenLayout(Context context, AttributeSet attrs) { | |
super(context, attrs); | |
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); | |
DisplayMetrics metrics = new DisplayMetrics(); | |
manager.getDefaultDisplay().getMetrics(metrics); | |
mMinLayoutHeight = | |
metrics.heightPixels * 2 / 3; //the height of layout is at least 2/3 of screen height | |
mMaxNavBarHeight = metrics.heightPixels / 6; // max height of navigation bar is 1/6 of height | |
} | |
/** | |
* when keyboard hide, three onMeasure will be called | |
* onMeasure measureHeight = 1533 | |
* onMeasure measureHeight = 725 | |
* onLayout top = 0, bottom = 1533 | |
* onMeasure measureHeight = 725 | |
* onLayout top = 0, bottom = 725 | |
*/ | |
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
int measureHeight = measureHeight(heightMeasureSpec); | |
if (mMaxParentHeight != 0 | |
&& Math.abs(measureHeight - mOldHeight) | |
< mMaxNavBarHeight) { //for some devices whose the bottom navigation bar can be hiden or shown | |
mMaxParentHeight += (measureHeight - mOldHeight); | |
} else if (mMaxParentHeight == 0 | |
|| measureHeight > mMinLayoutHeight) { //ignore keyboard shown making height shorter | |
mMaxParentHeight = measureHeight; | |
} | |
heightList.add(measureHeight); | |
int heightMode = MeasureSpec.getMode(heightMeasureSpec); | |
int expandSpec = MeasureSpec.makeMeasureSpec(mMaxParentHeight, heightMode); | |
super.onMeasure(widthMeasureSpec, expandSpec); | |
mOldHeight = measureHeight; | |
} | |
@Override protected void onLayout(boolean changed, int l, int t, int r, int b) { | |
super.onLayout(changed, l, t, r, mMaxParentHeight); | |
if (heightList.size() >= 2) { //keyboard hide or show, onMeasure will be called twice | |
int oldh = heightList.get(0); | |
int newh = heightList.get(heightList.size() - 1); | |
int dividerHeight = Math.abs(newh - oldh); | |
if (dividerHeight > mMaxNavBarHeight) { //means keyboard hide or show | |
if (newh < oldh) { | |
if (null != onKeyboardChangedListener) { | |
onKeyboardChangedListener.onSoftKeyboardPop(dividerHeight); | |
} | |
} else { | |
if (null != onKeyboardChangedListener) { | |
onKeyboardChangedListener. | |
onSoftKeyboardClose(); | |
} | |
} | |
} | |
heightList.clear(); | |
} else { | |
heightList.clear(); | |
} | |
} | |
private int measureHeight(int pHeightMeasureSpec) { | |
int result = 0; | |
int heightMode = MeasureSpec.getMode(pHeightMeasureSpec); | |
int heightSize = MeasureSpec.getSize(pHeightMeasureSpec); | |
switch (heightMode) { | |
case MeasureSpec.AT_MOST: | |
case MeasureSpec.EXACTLY: | |
result = heightSize; | |
break; | |
} | |
return result; | |
} | |
public void setOnKeyboardChangedListener(OnKeyboardChangedListener onKeyboardChangedListener) { | |
this.onKeyboardChangedListener = onKeyboardChangedListener; | |
} | |
public interface OnKeyboardChangedListener { | |
void onSoftKeyboardPop(int height); | |
void onSoftKeyboardClose(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment