React Native首屏启动白屏问题加载xml文件解决方案Android

React Native首屏启动白屏问题加载xml文件解决方案Android

很久没有写博客了,记录一下我前几天遇到的启动白屏加载xml文件解决办法。

一开始我在全球最大的同性交友平台github上找到了一款轻巧的解决方案,react-native-smart-splash-screen
这一个库是通过直接加载一张名为splash的固定图片作为首屏启动页面,但是现在Android手机屏幕比例五花八门,这样就会造成图片被拉伸的问题。虽然这个启动页很快就消失,但是作为一个合格的优秀的搬砖工也得学会砌墙。
首先查看了他的库,android文件夹里面有个RCTSplashScreen的Class文件,想必他是在这里面配置的,读了一下他的源码,大概意思是从我的包名资源文件下面找到一个叫spalsh文件名的图片,获取这个图片的id值,然后把这个id塞入一个ImageView对象,然后再把这个ImageView塞入一个Layout对象,最后把这个Layout放在一个dialog里面,启动的时候显示这个dialog,启动完成手动关闭这个dialog。顺着他的思路,我只需要把它的这个image换成自定义的xml文件就可以了。
是时候贴一波代码了

public class RCTSplashScreen {
    public static final int UIAnimationNone = 0;
    public static final int UIAnimationFade = 1;
    public static final int UIAnimationScale = 2;
    private static Dialog dialog;
    private static ImageView imageView;
    private static LinearLayout mLl_parent;
    private static WeakReference wr_activity;
    protected static Activity getActivity() {
        return wr_activity.get();
    }
    public static void openSplashScreen(Activity activity) {
        openSplashScreen(activity, false);
    }
    public static void openSplashScreen(Activity activity, boolean isFullScreen) {
        openSplashScreen(activity, isFullScreen, ImageView.ScaleType.CENTER_CROP);
    }
    public static void openSplashScreen(final Activity activity, final boolean isFullScreen, final ImageView.ScaleType scaleType) {
        if (activity == null) return;
        wr_activity = new WeakReference<>(activity);
        final int drawableId = getImageId();
        if ((dialog != null && dialog.isShowing()) || (drawableId == 0)) {
            return;
        }
        activity.runOnUiThread(new Runnable() {
            public void run() {
                if (!getActivity().isFinishing()) {
                    Context context = getActivity();

                    LayoutParams layoutParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);


                    View view= addView();
                    view.setLayoutParams(layoutParams);
                    dialog = new Dialog(context, isFullScreen ? android.R.style.Theme_Translucent_NoTitleBar_Fullscreen : android.R.style.Theme_Translucent_NoTitleBar);
                    dialog.setContentView(view);
                    dialog.setCancelable(false);
                    dialog.show();
                }
            }
        });
    }
    private static View addView() {
        Context context = getActivity(); // TODO 动态添加布局(xml方式)
        LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);

        LayoutInflater inflater = LayoutInflater.from(context);
        View view = inflater.inflate(R.layout.splash, null);
        view.setLayoutParams(lp);
        return view;
    }
    public static void removeSplashScreen(Activity activity, final int animationType, final int duration) {
        if (activity == null) {
            activity = getActivity();
            if (activity == null) return;
        }
        activity.runOnUiThread(new Runnable() {
            public void run() {
                if (dialog != null && dialog.isShowing()) {
                    AnimationSet animationSet = new AnimationSet(true);
                    if (animationType == UIAnimationScale) {
                        AlphaAnimation fadeOut = new AlphaAnimation(1, 0);
                        fadeOut.setDuration(duration);
                        animationSet.addAnimation(fadeOut);
                        ScaleAnimation scale = new ScaleAnimation(1, 1.5f, 1, 1.5f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.65f);
                        scale.setDuration(duration);
                        animationSet.addAnimation(scale);
                    } else if (animationType == UIAnimationFade) {
                        AlphaAnimation fadeOut = new AlphaAnimation(1, 0);
                        fadeOut.setDuration(duration);
                        animationSet.addAnimation(fadeOut);
                    } else {
                        AlphaAnimation fadeOut = new AlphaAnimation(1, 0);
                        fadeOut.setDuration(0);
                        animationSet.addAnimation(fadeOut);
                    }
                    final View view = ((ViewGroup) dialog.getWindow().getDecorView()).getChildAt(0);
                    view.startAnimation(animationSet);
                    animationSet.setAnimationListener(new Animation.AnimationListener() {
                        @Override
                        public void onAnimationStart(Animation animation) {
                        }
                        @Override
                        public void onAnimationRepeat(Animation animation) {
                        }
                        @Override
                        public void onAnimationEnd(Animation animation) {
                            view.post(new Runnable() {
                                @Override
                                public void run() {
                                    dialog.dismiss();
                                    dialog = null;
                                    imageView = null;
                                }
                            });
                        }
                    });
                }
            }
        });
    }
    private static int getImageId() {
        int drawableId = getActivity().getResources().getIdentifier("splash", "layout", getActivity().getClass().getPackage().getName());
        if (drawableId == 0) {
            drawableId = getActivity().getResources().getIdentifier("splash", "layout", getActivity().getPackageName());
        }
        return drawableId;
    }
}

划重点:
1.getImageId()方法从当前包文件下找到名字为splash的layout文件,取到并返回它的id
2.addView()方法,实例化出来一个LayoutParams 对象,然后向里面添加xml文件,返回出来一个View对象
3.openSplashScreen()这个方法里再把这个新增的view放在dialog里面
这样就完成了~是不是不难。如果大家还有问题欢迎加我QQ交流1414770848

你可能感兴趣的:(坑上搭桥)