一、一般情况下给Activity设置如下属性,软盘弹出后布局自定上顶起来
android:windowSoftInputMode="adjustPan|stateHidden"
android:screenOrientation="portrait"
二、但也在一些布局中,给EditText设置输入类型,EditText获取焦点后,再次点击时,布局不能正常顶起,这时我们需要通过计算键盘的高度,键盘弹出时,布局往上移。
需要注意的是,xml布局最外层必须是相对布局RelativeLayout。
第一步:获取状态栏的高度,如果没有的话,就不需要了
/** * 获取状态栏高度 * @param context * @return */ public static int getStatusBarHeight(Context context) { try { Class<?> c = Class.forName("com.android.internal.R$dimen"); Object obj = c.newInstance(); Field field = c.getField("status_bar_height"); int x = Integer.parseInt(field.get(obj).toString()); int height = context.getResources().getDimensionPixelSize(x); return height; } catch (Exception e) { e.printStackTrace(); } return 0; }第二步:给EditText设置焦点监听
main_edt.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { hasFocusOfEdtPhone = hasFocus; } });第三步:给键盘设置全局监听
public void setKeyBoardOnShowedListener(Activity activity) { final View decorView = activity.getWindow().getDecorView(); decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { Rect rect = new Rect(); parent_layout.getWindowVisibleDisplayFrame(rect); // 屏幕高度。这个高度不含虚拟按键的高度 int screenHeight = parent_layout.getRootView().getHeight(); //设置默认值 为屏幕的三分之一 keyboardHeight = screenHeight / 3; // 在不显示软键盘时,heightDiff等于状态栏的高度 // 在显示软键盘时,heightDiff会变大,等于软键盘加状态栏的高度。 // 所以heightDiff大于状态栏高度时表示软键盘出现了, int heightDiff = screenHeight - (rect.bottom - rect.top); /** * 如果有状态栏就要添加这句话 */ statusBarHeight = getStatusBarHeight(MainActivity.this); // 这时可算出软键盘的高度,即heightDiff减去状态栏的高度 if (keyboardHeight < heightDiff && heightDiff > statusBarHeight) { keyboardHeight = heightDiff - statusBarHeight; } //计算键盘开合 Rect rect2 = new Rect(); decorView.getWindowVisibleDisplayFrame(rect2); int displayHeight = rect2.bottom - rect2.top; int height = decorView.getHeight(); boolean isShowed = (double) displayHeight / height < 0.8; if (isShowed && hasFocusOfEdtPhone) {//键盘弹出且EditText获取焦点 parent_layout.setY(-(keyboardHeight)); } else { parent_layout.setY(0); } } }); }三、核心代码:
package testslideswitch.testedittext; import android.app.Activity; import android.content.Context; import android.graphics.Rect; import android.os.Bundle; import android.view.View; import android.view.ViewTreeObserver; import android.widget.EditText; import android.widget.RelativeLayout; import java.lang.reflect.Field; public class MainActivity extends Activity { private RelativeLayout parent_layout; private EditText main_edt; /** 软键盘的高度*/ private int keyboardHeight; /** 状态栏的高度*/ private int statusBarHeight; /** 判断输入框是否获取焦点(这个如果有多个输入框时会用到)*/ private boolean hasFocusOfEdtPhone; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); setWidgetListener(); } /** * 初始化View */ private void initView() { parent_layout = (RelativeLayout) findViewById(R.id.main_parent_layout); main_edt = (EditText) findViewById(R.id.main_edt); } /** * 设置监听 */ private void setWidgetListener() { main_edt.setOnFocusChangeListener(new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { hasFocusOfEdtPhone = hasFocus; } }); setKeyBoardOnShowedListener(this); } /** * * 监听软键盘全局监听 * <h3>Version</h3> 1.0 * <h3>CreateTime</h3> 2016/3/30,23:47 * <h3>UpdateTime</h3> 2016/3/30,23:47 * <h3>CreateAuthor</h3> luzhenbang * <h3>UpdateAuthor</h3> * <h3>UpdateInfo</h3> (此处输入修改内容,若无修改可不写.) * @param activity */ public void setKeyBoardOnShowedListener(Activity activity) { final View decorView = activity.getWindow().getDecorView(); decorView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { Rect rect = new Rect(); parent_layout.getWindowVisibleDisplayFrame(rect); // 屏幕高度。这个高度不含虚拟按键的高度 int screenHeight = parent_layout.getRootView().getHeight(); //设置默认值 为屏幕的三分之一 keyboardHeight = screenHeight / 3; // 在不显示软键盘时,heightDiff等于状态栏的高度 // 在显示软键盘时,heightDiff会变大,等于软键盘加状态栏的高度。 // 所以heightDiff大于状态栏高度时表示软键盘出现了, int heightDiff = screenHeight - (rect.bottom - rect.top); /** * 如果有状态栏就要添加这句话 */ statusBarHeight = getStatusBarHeight(MainActivity.this); // 这时可算出软键盘的高度,即heightDiff减去状态栏的高度 if (keyboardHeight < heightDiff && heightDiff > statusBarHeight) { keyboardHeight = heightDiff - statusBarHeight; } //计算键盘开合 Rect rect2 = new Rect(); decorView.getWindowVisibleDisplayFrame(rect2); int displayHeight = rect2.bottom - rect2.top; int height = decorView.getHeight(); boolean isShowed = (double) displayHeight / height < 0.8; if (isShowed && hasFocusOfEdtPhone) {//键盘弹出且EditText获取焦点 parent_layout.setY(-(keyboardHeight)); } else { parent_layout.setY(0); } } }); } /** * 获取状态栏高度 * @param context * @return */ public static int getStatusBarHeight(Context context) { try { Class<?> c = Class.forName("com.android.internal.R$dimen"); Object obj = c.newInstance(); Field field = c.getField("status_bar_height"); int x = Integer.parseInt(field.get(obj).toString()); int height = context.getResources().getDimensionPixelSize(x); return height; } catch (Exception e) { e.printStackTrace(); } return 0; } }xml文件:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/main_parent_layout" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:text="Hello World!" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:layout_weight="1"/> <EditText android:id="@+id/main_edt" android:hint="请输入内容" android:inputType="text" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> </RelativeLayout>四、效果图
软盘弹出前:
软盘弹出后:
参考文献:
http://www.csjwang.com/jishu/jiantingruanjianpan-442/