Android开发教程之获取系统输入法高度的正确姿势
在Android开发中,有时候需要获取系统输入法的高度,以便处理界面上控件的布局。但是由于不同版本的系统输入法可能存在差异,因此需要采用正确的方法获取系统输入法的高度。
使用ViewTreeObserver实时监听输入法高度变化
在Activity的onCreate方法中可以通过ViewTreeObserver来获取输入法高度。首先需要在布局文件中添加一个布局监听器ViewGroup,然后调用ViewGroup的getViewTreeObserver().addOnGlobalLayoutListener()方法,在监听回调中获取输入法高度。
ViewGroup rootView = findViewById(android.R.id.content);
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
int heightDiff = rootView.getRootView().getHeight() - (r.bottom - r.top);
Log.i(TAG, "onGlobalLayout: heightDiff=" + heightDiff);
// do something with heightDiff
}
});
这段代码中,首先获取了根视图的可见矩形区域,然后计算了输入法高度与根视图高度的差值,即heightDiff。这个值就是输入法的高度,可以在回调中进行相应处理。
使用反射方法获取系统输入法高度
有时候使用ViewTreeObserver监听输入法高度变化可能会有一定的性能问题,此时可以采用反射的方法获取输入法高度。需要使用反射技术来获取全局InputMethodManager对象,然后再通过对象获取当前系统输入法的调用方法,获取输入法高度。
private int getSystemInputMethodHeight(Activity activity) {
int statusBarHeight = getStatusBarHeight(activity);
Class<?> clazz;
Object obj;
Field field;
int height = 0;
try {
clazz = Class.forName("com.android.internal.R$dimen");
obj = clazz.newInstance();
field = clazz.getField("status_bar_height");
int x = Integer.parseInt(field.get(obj).toString());
height = activity.getResources().getDimensionPixelSize(x);
} catch (Exception e) {
e.printStackTrace();
}
int screenHeight = activity.getResources().getDisplayMetrics().heightPixels;
InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
Method getMethod = null;
try {
getMethod = inputMethodManager.getClass().getMethod("getInputMethodWindowVisibleHeight");
getMethod.setAccessible(true);
height = screenHeight - (Integer) getMethod.invoke(inputMethodManager) - statusBarHeight - height;
} catch (Exception e) {
e.printStackTrace();
}
return height;
}
private int getStatusBarHeight(Activity activity) {
int statusBarHeight = 0;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//获取状态栏高度的资源ID
int resourceId = activity.getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
//根据资源ID获取响应的尺寸值
statusBarHeight = activity.getResources().getDimensionPixelSize(resourceId);
}
}
return statusBarHeight;
}
这段代码中需要注意一下两个点:
- 反射需要获取全局的InputMethodManager对象,因此需要调用Activity的getSystemService(Context.INPUT_METHOD_SERVICE)方法获取。
- 在获取输入法高度时,需要先获取状态栏高度和输入法的padding值,最后计算差值就是输入法高度。
示例1:应用中的搜索框
通常在应用中,搜索框通常会使用在页面的最顶部。如果没有考虑到输入法高度,可能会对搜索框造成遮挡。因此,需要计算输入法弹出后的高度,以便使输入框获得合适的布局。
public class MyActivity extends Activity {
private EditText searchBox;
private View rootView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity_layout);
searchBox = findViewById(R.id.search_box);
rootView = findViewById(android.R.id.content);
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
int heightDiff = rootView.getRootView().getHeight() - (r.bottom - r.top);
if (heightDiff > 100) {
// 说明输入法弹出
RelativeLayout.LayoutParams searchLayoutParams = (RelativeLayout.LayoutParams) searchBox.getLayoutParams();
searchLayoutParams.topMargin = heightDiff;
searchBox.setLayoutParams(searchLayoutParams);
} else {
// 说明输入法隐藏
RelativeLayout.LayoutParams searchLayoutParams = (RelativeLayout.LayoutParams) searchBox.getLayoutParams();
searchLayoutParams.topMargin = 0;
searchBox.setLayoutParams(searchLayoutParams);
}
}
});
}
}
这段代码中在onCreate方法中为应用中的根视图添加全局布局监听器,根据输入法高度调整了搜索框的布局设置。
示例2:应用中的输入框
在应用中的一些场景中,输入框可能会出现在底部按钮上方,如底部评论输入框等,我们也需要适配输入法的高度。
public class MyActivity extends Activity {
private EditText editText;
private View rootView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity_layout);
editText = findViewById(R.id.edit_text);
rootView = findViewById(android.R.id.content);
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
int inputMethodHeight = getSystemInputMethodHeight(MyActivity.this);
RelativeLayout.LayoutParams editTextLayoutParams = (RelativeLayout.LayoutParams) editText.getLayoutParams();
editTextLayoutParams.bottomMargin = inputMethodHeight;
editText.setLayoutParams(editTextLayoutParams);
}
});
}
}
这段代码中同样使用了ViewTreeObserver监听输入法高度的变化,并计算了输入法的高度,然后在回调中更新了输入框的布局设置。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android开发教程之获取系统输入法高度的正确姿势 - Python技术站