
manifest文件中activity注册声明没有该属性时或者设置该属性如下adjustPan:
android:windowSoftInputMode="adjustPan"
表现为整个布局被上移,很多时候布局文件里面自定义的标题也会被推出屏幕之外,面对常有的自定义标题栏十分难堪。
有没有什么办法固定住标题栏,而下面的不动呢?答案是有的。我们来试试adjustResize
android:windowSoftInputMode="adjustResize"

尴尬了,这个值直接不做任何布局反应,完全遮挡住输入框。
再来试试套ScrollView大法:


经测试,外层套一个ScrollView很完美应对"自定义标题栏不动,多编辑框界面能保持上移输入时可见"的需求。而此时无论有没有设置adjustResize或者adjustPan不再有关系。但是简单解决方案只能应对特殊的情况,一般来讲这还不够自由,不够一般性治标不治本。
简单的布局下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!--自定义Linenearlayout-->
<com.example.schoolservice.view.ChatSendBottom
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
</com.example.schoolservice.view.ChatSendBottom>
</RelativeLayout>
manifest文件不做修改或者添加android:windowSoftInputMode="adjustPan",都出现如下遮挡效果。

添加android:windowSoftInputMode="adjustResize"时,布局被完美顶起,没有遮挡。

getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
但是在activity代码里写上如上代码以获得全屏效果,即刻回到没有设置adjustResize时的被遮挡部分输入框状态,很明显全屏模式下不能够简单地adjustResize解决被遮挡问题。
认真查了查资料,简单配置布局文件(套一层scrollViiew),或者设置manifest文件都不能真正解决问题,尽管在一定的场景下能够应对简单问题。
保持界面“局部”不被输入法上移改变适宜套ScrollView,而上不上移由adjustPan或者adjustResize决定,前者是默认(指不指定都一样,尽管一样有上移布局效果,但很多时候布置在布局底部的编辑框会被遮住一部分+傻瓜式全部上移),后者是相对智能的处理,但在一些场景会导致意外的效果,比如案例1直接没有上移效果完全遮挡住,但在案例2中又有明显的优化效果。总而言之除了scrollview能百分百能够控制上移界面内容,adjustPan、adjustResize都不可靠,很大可能与布局管理器的内容设定有关,懵了很久,反正我是没耐心刨根究底研究了。java代码动态控制布局才是出路。
参考大佬文章:android全屏/沉浸式状态栏下,各种键盘挡住输入框解决办法
public class SoftHideKeyBoardUtil {
public static void assistActivity (Activity activity) {
new SoftHideKeyBoardUtil(activity);
}
private View mChildOfContent;
private int usableHeightPrevious;
private FrameLayout.LayoutParams frameLayoutParams;
//为适应华为小米等手机键盘上方出现黑条或不适配
private int contentHeight;//获取setContentView本来view的高度
private boolean isfirst = true;//只用获取一次
private int statusBarHeight;//状态栏高度
private SoftHideKeyBoardUtil(Activity activity) {
//1、找到Activity的最外层布局控件,它其实是一个DecorView,它所用的控件就是FrameLayout
FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
//2、获取到setContentView放进去的View
mChildOfContent = content.getChildAt(0);
//3、给Activity的xml布局设置View树监听,当布局有变化,如键盘弹出或收起时,都会回调此监听
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
//4、软键盘弹起会使GlobalLayout发生变化
public void onGlobalLayout() {
if (isfirst) {
contentHeight = mChildOfContent.getHeight();//兼容华为等机型
isfirst = false;
}
//5、当前布局发生变化时,对Activity的xml布局进行重绘
possiblyResizeChildOfContent();
}
});
//6、获取到Activity的xml布局的放置参数
frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
}
// 获取界面可用高度,如果软键盘弹起后,Activity的xml布局可用高度需要减去键盘高度
private void possiblyResizeChildOfContent() {
//1、获取当前界面可用高度,键盘弹起后,当前界面可用布局会减少键盘的高度
int usableHeightNow = computeUsableHeight();
//2、如果当前可用高度和原始值不一样
if (usableHeightNow != usableHeightPrevious) {
//3、获取Activity中xml中布局在当前界面显示的高度
int usableHeightSansKeyboard = mChildOfContent.getRootView().getHeight();
//4、Activity中xml布局的高度-当前可用高度
int heightDifference = usableHeightSansKeyboard - usableHeightNow;
//5、高度差大于屏幕1/4时,说明键盘弹出
if (heightDifference > (usableHeightSansKeyboard/4)) {
// 6、键盘弹出了,Activity的xml布局高度应当减去键盘高度
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference + statusBarHeight;
} else {
frameLayoutParams.height = usableHeightSansKeyboard - heightDifference;
}
} else {
frameLayoutParams.height = contentHeight;
}
//7、 重绘Activity的xml布局
mChildOfContent.requestLayout();
usableHeightPrevious = usableHeightNow;
}
}
private int computeUsableHeight() {
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
// 全屏模式下:直接返回r.bottom,r.top其实是状态栏的高度
return (r.bottom - r.top);
}
}
主活动里面配置这个:
SoftHideKeyBoardUtil.assistActivity(this);

问题终于得到缓解,起码全屏模式下输入法弹出时自定义的编辑框所在的布局可以整体刚好上移到输入法高度之上。但是缺点仍然明显,输入法弹出时上面的控件会产生跳变,先是闪现到既定位置之外再下落回来。体验很差。