React Native笔记(三):解决在RN中使用Android原生WebView时输入框被遮挡问题

如题,在解决该问题前,上网搜了一下资料,找到了下面这个方案:
Android webView输入框软键盘遮挡问题-终极解决方案(不好使你打我)

但是,这在纯原生上可行,在rn上却没有效果。主要原因是rn有自己的一套布局测量绘制机制,导致在原生调用requestLayout()没有响应,经过几次实践,得出下面针对rn的解决办法。

  1. 重写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);
                }
            });
        }
    }
}
  1. 修改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方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萌面小侠Plus

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值