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<Activity> 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