原文链接 :Avoiding cold starts on Android
原文作者 : Saúl Molinero
译文出自 : http://blog.csdn.net/zhulove86
译者 : Tony Zhu

在过去几周,在android开发者社区中看一些关于冷启动(clod start)、闪屏(splash screen)、启动界面的动画。在本文中,我将阐明这些动画是否有必要,如何使用以及如何更好提供极致的用户体验。

本文中提到的代码和示例,可以在GitHub上获取。

Splash Screen,lunch screen和cold start

柯尔特(Colt McAnlis,在谷歌开发人员倡导者)通过在Cyril Morrier分享了主题文章,再次展开关于Splash/Lanuce screen在Android系统上使用的讨论。其中除其他事项外,讨论了为什么应该避免使用在Android上使用Splash Screen,声称这会伤害了用户体验,增加应用的大小等。

在我看来,用户应该尽快的看到应用的内容。但不可避免的,当用户启动一个应用程序时,Android会创建一个新的进程。在应用加载中,显示一个由应用theme构建的黑/白屏,或是第一个Activity的theme。

当我们应用非常复杂,并且我们重写了很多被用于初始化分析,报错等功能的对象,应用启动的负载就会变的很大。


Airbnb在应用初始化中显示白屏。

对于用户黑屏并不是最好的选择。如果我们的应用加载的时间很慢,我们应该使用一个占位,用实际内容简单的填充;或另一方面,如果我们的开发工作是复杂的,我们可以显示应用的logo,以增强品牌效应。


AliExpress 在初始化中显示其logo

你的新伙伴, windowBackground

如之前讨论,在进程加载状态时由WindowManager显示的窗口被设置为application主题。具体在android:windowBackground中值。参考lan Lake的文章,如果我们通过使用设定 这个属性,main activity的背景色之上在最中心显示一个bitmap,我们可以获得如下的效果:

<?xml version="1.0" encoding="utf-8"?><layer-list     xmlns:android="http://schemas.android.com/apk/res/android"    android:opacity="opaque">    <item android:drawable="@color/grey"/>    <item>        <bitmap            android:gravity="center"            android:src="@drawable/img_pizza"/>    item>layer-list>

我们必须牢记以避免出现问题,应该是不透明的,android:opacity=”opaque”。并且在layout中该activity的父activity背景色也应该被一种颜色填充,如果没有的话, 在启动时所展示的将被保留在你的activity中。

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    android:background="@color/grey"    >    <android.support.v7.widget.Toolbar        android:layout_width="match_parent"        android:layout_height="?attr/actionBarSize"        android:background="?colorPrimary"        android:elevation="4dp"        />LinearLayout>

改变应用引导(onboarding)样式

利用窗口背景色,我们可以丰富用户体验的效果。如果我们的应用复杂,并且要展示一个类似登录或者选择的不透明界面,我们采用位图相同的定位点(anchor point)和动画实现,可以达到非常好的效果。


这个动画,转变一个ImageView,其中包含了相同的的资源 。

ViewCompat.animate(logoImageView)    .translationY(-250)    .setStartDelay(STARTUP_DELAY)    .setDuration(ANIM_ITEM_DURATION).setInterpolator(         new DecelerateInterpolator(1.2f)).start();

这个ImageView略高于屏幕的中心,这可以通过状态栏的影响,离 top 边缘12dp,正好是状态栏一半的高度。

<ImageView    android:id="@+id/img_logo"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_gravity="center"    android:layout_marginTop="12dp"    android:src="@drawable/img_face"    tools:visibility="gone"    />

改变占位的样式

通过 我们可以创建一个占位的UI,在该UI中显示main activity的内容。举例,我们可以利用 模拟一个工具栏。

<?xml version="1.0" encoding="utf-8"?><layer-list    xmlns:android="http://schemas.android.com/apk/res/android"    android:opacity="opaque"    >    <item>        <shape>            <solid android:color="@color/grey"/>        shape>    item>    <item        android:height="180dp"        android:gravity="top">        <shape android:shape="rectangle">            <solid android:color="?colorPrimary"/>        shape>    item>layer-list>

在这种情况下,第二个 模拟工具栏来显示实际的内容,甚至我们可以设置相同的高度(略小于状态栏的宽度),并且在工具栏上使用一些好的动画,可以给用户提供较好的用户体验。

private void collapseToolbar() {    int toolBarHeight;    TypedValue tv = new TypedValue();    getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true);    toolBarHeight = TypedValue.complexToDimensionPixelSize(        tv.data, getResources().getDisplayMetrics());    ValueAnimator valueHeightAnimator = ValueAnimator        .ofInt(mContentViewHeight, toolBarHeight);    valueHeightAnimator.addUpdateListener(        new ValueAnimator.AnimatorUpdateListener() {        @Override        public void onAnimationUpdate(ValueAnimator animation) {            ViewGroup.LayoutParams lp = mToolbar.getLayoutParams();            lp.height = (Integer) animation.getAnimatedValue();            mToolbar.setLayoutParams(lp);        }    });    valueHeightAnimator.start();    valueHeightAnimator.addListener(        new AnimatorListenerAdapter() {        @Override        public void onAnimationEnd(Animator animation) {            super.onAnimationEnd(animation);            // Fire recycler animator            mAdapter.addAll(ModelItem.getFakeItems());            // Animate fab            ViewCompat.animate(mFab).setStartDelay(600)                .setDuration(400).scaleY(1).scaleX(1).start();        }    });}

相关资料:
onboarding-examples - Github
Uber onboarding
Use cold start time effectively with a branded launch theme - Ian Lake
Splash Screens Are Evil, Don’t Use Them! - Cyril Mottier
Launch screens - Material Design Spec
Launch screens - MaterialDoc, Gonzalo Toledano


由于时间仓促、翻译水平有限,其中有许多不足之处在所难免,敬请批评指正。

更多相关文章

  1. Android中不同应用间实现SharedPreferences数据共享
  2. 关于Android(安卓)Studio3.2新建项目Android(安卓)resource link
  3. Android(安卓)- Manifest 文件 详解
  4. Android之应用程序基础
  5. Android四大组件的理解
  6. Android官方入门文档[1]创建一个Android项目
  7. Android(安卓)P SystemUI之StatusBar UI布局status_bar.xml解析
  8. 第三章 Android程序设计基础
  9. android用户界面-组件Widget-地图视图MapView

随机推荐

  1. kubernetes其他控制器之PodDisruptionBud
  2. 网页
  3. 安全防卫技术-当有人抓你衣领时
  4. Let's Encrypt签发工具CertBot-auto不再
  5. 为什么很多网站都去除oracle?
  6. 可靠型园区网组网,你该如何选择最优方案?
  7. 火星
  8. 测试一下
  9. 影响2020年代经济的8个宏观因素
  10. boost项目复盘(三)