Android 提升使用者體驗之骨架屏

denko發表於2019-03-10

前幾天公司app做優化,提出了不要菊花圖,原因是使用者進入介面的時候彈出對話方塊壓迫感太強並且在ios端由於沒有返回按鈕要等請求完才能操作,很坑爹。恰巧那天又看到《玉剛說》的公眾號推了一篇骨架屏的文章,看了一下並且自己嘗試了一下其他的接入總結一下坑點。

關於這方面的第三方庫

一個封裝了Recycview的遮罩控制元件,使用起來比下面的要方便。

一個封裝了遮罩層的庫

一個使佈局閃爍的庫,很多第三方庫都依賴於它


遮罩庫

僅僅支援圖片跟文字,設定值時會去除遮罩。具體實現可以看看原始碼,

遮罩控制元件,支援多種控制元件,但是需要巢狀多層會影響一點效能

實現方法

-c

如效果圖,實現的思想有兩種。一種是寫多一個遮罩佈局,請求成功後再替換。這個也是上面第三方庫的實現方法另一種是遮罩控制元件巢狀在原佈局裡,顯示成功後呼叫方法隱藏。無論那種方式最好叫設計師給好一個遮罩item的原型尺寸,否則遇到複雜佈局時自己很難調節大小。

最簡單的方法

只需要把RecyclerView換成ShimmerRecyclerView呼叫顯示、隱藏方法即可。這種方法也需要寫一個遮罩佈局,否則是預設的。

  • 接入
repositories {
    jcenter()
    maven { url "https://jitpack.io" }
}

dependencies {
    implementation 'com.github.sharish:ShimmerRecyclerView:v1.3'
}
複製程式碼
  • 使用
<com.cooltechworks.views.shimmer.ShimmerRecyclerView
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/shimmer_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:shimmer_demo_child_count="10"
        app:shimmer_demo_grid_child_count="2"
        app:shimmer_demo_layout="@layout/layout_demo_grid"
        app:shimmer_demo_layout_manager_type="grid"
        app:shimmer_demo_angle="20"
        />
複製程式碼

呼叫對應的顯示隱藏方法

shimmerRecycler.showShimmerAdapter();

shimmerRecycler.hideShimmerAdapter();
複製程式碼

Skeleton+佈局

這種方法比較自由,除了RecyclerView以外還能用在其他佈局上

  • 接入
repositories {
    jcenter()
    maven { url "https://jitpack.io" }
}

dependencies {
    implementation 'com.github.sharish:ShimmerRecyclerView:v1.3'
}
複製程式碼
  • 使用
    RecyclerView:
skeletonScreen = Skeleton.bind(recyclerView)
                              .adapter(adapter)
                              .load(R.layout.item_skeleton_news)
                              .show();
複製程式碼

其他View:

skeletonScreen = Skeleton.bind(rootView)
                              .load(R.layout.layout_img_skeleton)
                              .show();
複製程式碼

提供的方法

.shimmer(true)      // whether show shimmer animation.                      default is true
.count(10)          // the recycler view item count.                        default is 10
.color(color)       // the shimmer color.                                   default is #a2878787
.angle(20)          // the shimmer angle.                                   default is 20;
.duration(1000)     // the shimmer animation duration.                      default is 1000;
.frozen(false)      // whether frozen recyclerView during skeleton showing  default is true; 
複製程式碼

消失時呼叫

skeletonScreen.hide()
複製程式碼

遮罩控制元件

上面的方法都要寫一個佈局,如果不想寫多一個佈局的可以使用遮罩控制元件

  1. github.com/elye/loader…
    -c

在setText或者給src設值時自動去除遮罩。可以設定預設遮罩的百分比長度還可以設定帶一點點的閃爍動畫等等。但是隻有文字跟圖片控制元件可用,以及不能根據文字長度來設定遮罩,因為setText之後會自動消失,所以在某些比較複雜的佈局裡如果沒有設計師提供尺寸圖是做不出效果的。

  • 接入
dependencies {
    implementation 'com.elyeproj.libraries:loaderviewlibrary:1.5.0'
}
複製程式碼
  • 使用
<com.elyeproj.loaderviewlibrary.LoaderImageView
     android:layout_width="100dp"
     android:layout_height="100dp" />
複製程式碼
<com.elyeproj.loaderviewlibrary.LoaderTextView
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     app:width_weight="0.4" 
     app:height_weight="0.8"
     app:use_gradient="true"
      app:corners="16"
       app:custom_color="@android:color/holo_green_dark" />
複製程式碼

如果需要重新載入

myLoaderTextView.resetLoader();
複製程式碼

2.github.com/rasoulmiri/…

-c

除了上圖的效果外還支援其他效果,並且支援任意佈局,因為它的使用方法是在原有佈局上包裹一層。這種方式的好處是,可以不用設計師出遮罩圖,套一層佈局在外面後設定包裹內容即可,只是會比較耗費一點渲染效能。

  • 接入
allprojects {
    repositories {
	    ...
	    maven { url 'https://jitpack.io' }
    }
}
複製程式碼
dependencies {
      compile 'com.github.rasoulmiri:Skeleton:v1.0.9'
}
複製程式碼
  • 使用
<io.rmiri.skeleton.SkeletonGroup
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

         <io.rmiri.skeleton.SkeletonView ...>
            <View ... />
        </io.rmiri.skeleton.SkeletonView>

        <io.rmiri.skeleton.SkeletonView ...>
            <View ... />
        </io.rmiri.skeleton.SkeletonView>

</io.rmiri.skeleton.SkeletonGroup>
複製程式碼

支援動畫監聽

skeletonGroup.setSkeletonListener(new SkeletonGroup.SkeletonListener() {
      @Override
      public void onStartAnimation() {
	...
      }

      @Override
      public void onFinishAnimation() {
	...
      }
 });
複製程式碼

建議閱讀

骨架屏 (Skeleton Screen) 在 Android 中的應用


Android 提升使用者體驗之骨架屏

最開始堅持的地方,記錄學習與生活的點點滴滴

相關文章