Android骨架屏简介及实现方式

在移动应用开发中,用户加载过程的等待时间往往会给用户带来不好的体验。为了提高用户体验,可以使用骨架屏技术,在加载数据的过程中展示一个近似内容的页面,让用户感觉应用在快速加载数据。

什么是骨架屏

骨架屏(Skeleton Screen)是指在数据加载完成前,展示一些界面的占位图,让用户感受到应用正在加载数据。骨架屏一般由应用的布局结构和基本元素组成,不包含真实数据。

骨架屏的优点有:

  • 提高用户体验:用户能够感觉到应用正在加载数据,减轻等待的焦虑感。
  • 提供参考:骨架屏可以显示出应用的布局结构,让用户了解后续数据加载后的页面结构。

实现方式

骨架屏的实现方式有多种,下面介绍几种常用的方法。

1. 使用ViewStub

ViewStub是一个轻量级的View,可以在布局文件中定义,但默认情况下不会被加载,只有在需要显示的时候才会加载并替换为实际内容。

首先,在布局文件中定义骨架屏的ViewStub,例如:

<androidx.constraintlayout.widget.ConstraintLayout
    ...
    >

    <!-- 骨架屏 -->
    <ViewStub
        android:id="@+id/skeleton_view_stub"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:inflatedId="@+id/skeleton_layout"
        android:layout="@layout/skeleton_layout"
        />

    <!-- 实际内容 -->
    <LinearLayout
        android:id="@+id/content_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone"
        >
        ...
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

然后,在需要显示骨架屏的时候,使用以下代码加载并显示骨架屏:

val skeletonViewStub = findViewById<ViewStub>(R.id.skeleton_view_stub)
skeletonViewStub.inflate()

加载实际内容时,将骨架屏隐藏,显示实际内容:

val skeletonView = findViewById<View>(R.id.skeleton_layout)
skeletonView.visibility = View.GONE

val contentLayout = findViewById<View>(R.id.content_layout)
contentLayout.visibility = View.VISIBLE

2. 使用第三方库

除了使用ViewStub,还可以使用一些第三方库来实现骨架屏。其中比较常用的库有ShimmerSkeleton等。

Shimmer库为例,首先在项目的build.gradle文件中添加依赖:

dependencies {
    implementation 'com.facebook.shimmer:shimmer:0.5.0'
}

然后,在布局文件中添加一个ShimmerFrameLayout,用于展示骨架屏:

<com.facebook.shimmer.ShimmerFrameLayout
    android:id="@+id/shimmer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

    <!-- 骨架屏内容 -->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        ... >

        <!-- 骨架屏元素 -->
        <View
            android:layout_width="200dp"
            android:layout_height="20dp"
            ... />

        ...

    </LinearLayout>

</com.facebook.shimmer.ShimmerFrameLayout>

最后,通过以下代码启动骨架屏动画:

val shimmerLayout = findViewById<ShimmerFrameLayout>(R.id.shimmer_layout)
shimmerLayout.startShimmer()

加载实际内容时,停止骨架屏动画:

val shimmerLayout = findViewById<ShimmerFrameLayout>(R.id.shimmer_layout)
shimmerLayout.stopShimmer()
shimmerLayout.visibility = View.GONE

val contentLayout = findViewById<View>(R.id.content_layout)
contentLayout.visibility = View.VISIBLE

总结

骨架屏是一种提高用户体