如题,在解决该问题前,上网搜了一下资料,找到了下面这个方案:
Android webView输入框软键盘遮挡问题-终极解决方案(不好使你打我)
但是,这在纯原生上可行,在rn上却没有效果。主要原因是rn有自己的一套布局测量绘制机制,导致在原生调用requestLayout()没有响应,经过几次实践,得出下面针对rn的解决办法。
- 重写WebView的requestLayout方法,rn绘制时主动通知原生重新布局WebView
public class CusWebView extends WebView{
private boolean mLayoutEnqueued;
public CusWebView(Context context) {
super(context);
}
public CusWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CusWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public CusWebView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
public void requestLayout() {
super.requestLayout();
if (isAttachedToWindow() && !mLayoutEnqueued) {
mLayoutEnqueued = true;
ReactChoreographer.getInstance().postFrameCallback(ReactChoreographer.CallbackType.DISPATCH_UI, new ChoreographerCompat.FrameCallback() {
@Override
public void doFrame(long frameTimeNanos) {
mLayoutEnqueued = false;
measure(
MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(getLayoutParams().height, MeasureSpec.EXACTLY));
layout(getLeft(), getTop(), getRight(), getLayoutParams().height);
}
});
}
}
}
- 修改AndroidBug5497Workaround类
public class AndroidBug5497Workaround {
public static void assistActivity(Activity activity) {
new AndroidBug5497Workaround(activity);
}
private View mChildOfContent;
private int usableHeightPrevious = -1;
private ViewGroup.LayoutParams frameLayoutParams;
Activity mActivity;
private AndroidBug5497Workaround(Activity activity) {
this.mActivity = activity;
ViewGroup vp = activity.findViewById(android.R.id.content);
vp.post(new Runnable() {
@Override
public void run() {
mChildOfContent = findWebView(vp);
if (mChildOfContent == null) {
mChildOfContent = vp;
}
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
possiblyResizeChildOfContent();
}
});
}
});
}
public View findWebView(ViewGroup vp){
for (int i = vp.getChildCount() - 1; i >=0 ; i--){
View view = vp.getChildAt(i);
if (view instanceof CusWebView){
return view;
}else if (view instanceof ViewGroup){
View temp = findWebView((ViewGroup) view);
if (temp != null){
return temp;
}
}
}
return null;
}
private void possiblyResizeChildOfContent() {
int visibleHeight = computeUsableHeight();
if (visibleHeight != usableHeightPrevious) {
if (frameLayoutParams == null) {
frameLayoutParams = mChildOfContent.getLayoutParams();
}
int currentContentHeight = mChildOfContent.getHeight();
int heightDifference = Math.abs(currentContentHeight - visibleHeight);
frameLayoutParams.height = visibleHeight;
usableHeightPrevious = visibleHeight;
mChildOfContent.requestLayout();
}
}
private int computeUsableHeight() {
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
return r.bottom - r.top;// 全屏模式下: return r.bottom
}
}
关健是找出上一步重写的WebView对象,调用它的requestLayout方法