1、AndroidManifest.xml中activity不设置android:windowSoftInputMode属性或者设置为adjustUnspecified
2、修改过后的KeyboardVisibilityEvent代码
public class KeyboardVisibilityEvent {
private final static int KEYBOARD_VISIBLE_THRESHOLD_DP = 100;
/**
* Set keyboard visibility change event listener.
*
* @param activity Activity
* @param listener KeyboardVisibilityEventListener
*/
public static void setEventListener(final Activity activity, final boolean isFullScreen,
final KeyboardVisibilityEventListener listener) {
if (activity == null) {
throw new NullPointerException("Parameter:activity must not be null");
}
if (listener == null) {
throw new NullPointerException("Parameter:listener must not be null");
}
final View activityRoot = getActivityRoot(activity);
activityRoot.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
private final Rect rootViewRect = new Rect();
private final int visibleThreshold = getVisibleThreshold(activity);
private boolean wasOpened = false;
@Override
public void onGlobalLayout() {
activityRoot.getWindowVisibleDisplayFrame(rootViewRect);
int heightDiff = activityRoot.getRootView().getHeight() - rootViewRect.height();
if(!isFullScreen)
{
heightDiff -= getStatusBarHeight(activity);
}
boolean isOpen = heightDiff > visibleThreshold;
if (isOpen == wasOpened) {
// keyboard state has not changed
return;
}
wasOpened = isOpen;
listener.onVisibilityChanged(isOpen, heightDiff);
}
});
}
/**
* Determine if keyboard is visible
*
* @param activity Activity
* @return Whether keyboard is visible or not
*/
public static boolean isKeyboardVisible(Activity activity) {
Rect r = new Rect();
View activityRoot = getActivityRoot(activity);
int visibleThreshold = getVisibleThreshold(activity);
activityRoot.getWindowVisibleDisplayFrame(r);
int heightDiff = activityRoot.getRootView().getHeight() - r.height();
return heightDiff > visibleThreshold;
}
public static int getVisibleThreshold(Context context)
{
return Math.round(UIUtil.convertDpToPx(context, KEYBOARD_VISIBLE_THRESHOLD_DP));
}
private static View getActivityRoot(Activity activity) {
return ((ViewGroup) activity.findViewById(android.R.id.content)).getChildAt(0);
}
private static int getStatusBarHeight(Context context) {
int result = 0;
int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = context.getResources().getDimensionPixelSize(resourceId);
}
return result;
}
}
3、布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<RelativeLayout android:id="@+id/rl_bottom"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:gravity="center_horizontal|top"
android:layout_alignParentTop="true"
android:text="顶部"
android:textColor="#ff0000"/>
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:gravity="center"
android:layout_centerInParent="true"
android:text="中间"
android:textColor="#ff0000"/>
<TextView
android:layout_width="match_parent"
android:layout_height="200dp"
android:gravity="center_horizontal|bottom"
android:layout_alignParentBottom="true"
android:text="底部"
android:textColor="#ff0000"/>
</RelativeLayout>
<RelativeLayout android:id="@+id/rl_top"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/keyboard_status"
android:text="@string/hello_world"
android:layout_alignParentTop="true"
android:layout_width="match_parent"
android:gravity="center"
android:textSize="30sp"
android:layout_height="100dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#660000ff"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/button"
android:text="点我点我"
android:gravity="center"
android:layout_alignParentTop="true"
android:layout_width="wrap_content"
android:layout_height="40dp" />
<EditText
android:id="@+id/text_field"
android:layout_alignParentBottom="true"
android:layout_width="match_parent"
android:layout_height="40dp" />
</LinearLayout>
<TextView
android:gravity="center"
android:background="#6600ff00"
android:layout_width="match_parent"
android:layout_height="60dp" />
</LinearLayout>
</RelativeLayout>
</RelativeLayout>
4、MainActivity代码
public class MainActivity extends AppCompatActivity {
TextView mKeyboardStatus;
EditText mTextField;
TextView button;
RelativeLayout rlBottom;
RelativeLayout rlTop;
int mKh;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mKeyboardStatus = (TextView) findViewById(R.id.keyboard_status);
mTextField = (EditText) findViewById(R.id.text_field);
button = (TextView) findViewById(R.id.button);
rlTop = (RelativeLayout) findViewById(R.id.rl_top);
rlBottom = (RelativeLayout) findViewById(R.id.rl_bottom);
KeyboardVisibilityEvent.setEventListener(this, false, new KeyboardVisibilityEventListener() {
@Override
public void onVisibilityChanged(boolean isOpen, int kh) {
updateKeyboardStatusText(isOpen);
Log.i("aaaaaaaaaaaaab", "isOpen: " + isOpen + " kh: " + kh);
if(isOpen)
{
RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) rlTop.getLayoutParams();
p.height = rlBottom.getHeight() - kh;
rlTop.setLayoutParams(p);
if(kh > KeyboardVisibilityEvent.getVisibleThreshold(MainActivity.this))
{
mKh = kh;
}
}
else
{
RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) rlTop.getLayoutParams();
p.height = rlBottom.getHeight();
rlTop.setLayoutParams(p);
}
}
});
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RelativeLayout.LayoutParams p = (RelativeLayout.LayoutParams) rlTop.getLayoutParams();
p.height = rlBottom.getHeight() - (mKh > 200 ? mKh : 600);
rlTop.setLayoutParams(p);
UIUtil.showKeyboard(MainActivity.this, mTextField);
}
});
updateKeyboardStatusText(KeyboardVisibilityEvent.isKeyboardVisible(this));
}
private void updateKeyboardStatusText(boolean isOpen) {
mKeyboardStatus.setText(String.format("keyboard is %s", (isOpen ? "visible" : "hidden")));
}
}
5、如果有可滚动view的话,DecorView会resize,所有要监听DecorView变化。
final ViewGroup activityRoot = ((ViewGroup) findViewById(android.R.id.content));
activityRoot.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Log.i("aaaaaaaaaaaaab", "activityRoot: " + activityRoot.getHeight() + "-" + mDecorViewHeight);
if(activityRoot.getHeight() < mDecorViewHeight)
{
Log.i("aaaaaaaaaaaaab", "set activityRoot: ");
ViewGroup.LayoutParams p = (ViewGroup.LayoutParams) activityRoot.getLayoutParams();
p.height = mDecorViewHeight;
activityRoot.setLayoutParams(p);
}
}
});