什么是好方法,InflateView/removeView 或设置 Visibility.GONE?
Posted
技术标签:
【中文标题】什么是好方法,InflateView/removeView 或设置 Visibility.GONE?【英文标题】:What's good approach, InflateView/ removeView OR setting Visibility.GONE? 【发布时间】:2020-07-26 20:40:56 【问题描述】:我有一个片段,上面有一个骨架视图。 Skeleton/Shimmering 视图仅在数据处于加载状态时显示一次,然后将其隐藏。我在 ViewPager2 中使用该片段。为了使 ViewPager2 的滚动更流畅,我试图优化布局。所以,我想更好地了解哪种方法更好。
-
在运行时膨胀或移除骨架?
将骨架保留在 XML 中并将其可见性设置为 GONE。
以下是 ShimmerLayout 的虚拟 XML,其中包含 5-7 个视图。任何想法都会很有意义。
谢谢
ShimmerLayout xml:
<com.facebook.shimmer.ShimmerFrameLayout
android:id="@+id/slEffect"
android:layout_
android:layout_
android:clickable="false"
android:paddingStart="18dp"
style="@style/ShimmerCommon"
app:shimmer_highlight_color="@color/post_detail_shimmer">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_
android:layout_
android:layout_marginTop="26dp"
android:layout_marginEnd="18dp"
android:layout_marginBottom="75dp">
<com.makeramen.roundedimageview.RoundedImageView
android:id="@+id/ivUserImage"
android:layout_
android:layout_
android:scaleType="centerCrop"
android:src="@color/post_detail_shimmer"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:riv_corner_radius="9dp" />
<com.makeramen.roundedimageview.RoundedImageView
android:id="@+id/tvUserName"
android:layout_
android:layout_
android:layout_marginStart="7.9dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="7.9dp"
android:scaleType="fitXY"
android:src="@color/post_detail_shimmer"
app:layout_constraintStart_toEndOf="@+id/ivUserImage"
app:layout_constraintTop_toTopOf="@+id/ivUserImage"
app:riv_corner_radius="8dp" />
<com.makeramen.roundedimageview.RoundedImageView
android:id="@+id/tvTime"
android:layout_
android:layout_
android:layout_marginStart="7.9dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="7.9dp"
android:scaleType="fitXY"
android:src="@color/post_detail_shimmer"
app:layout_constraintStart_toEndOf="@+id/ivUserImage"
app:layout_constraintTop_toBottomOf="@+id/tvUserName"
app:riv_corner_radius="8dp" />
<com.makeramen.roundedimageview.RoundedImageView
android:id="@+id/tvSuserName"
android:layout_
android:layout_
android:layout_marginBottom="8dp"
android:scaleType="fitXY"
android:visibility="gone"
android:src="@color/post_detail_shimmer"
app:layout_constraintBottom_toTopOf="@+id/tvSTime"
app:layout_constraintStart_toStartOf="parent"
app:riv_corner_radius="8dp" />
<com.makeramen.roundedimageview.RoundedImageView
android:id="@+id/tvSTime"
android:layout_
android:layout_
android:scaleType="fitXY"
android:src="@color/post_detail_shimmer"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:riv_corner_radius="8dp" />
<com.makeramen.roundedimageview.RoundedImageView
android:id="@+id/tvSTsime"
android:layout_
android:layout_
android:layout_below="@id/tvSuserName"
android:scaleType="fitXY"
android:visibility="gone"
android:src="@color/post_detail_shimmer"
app:layout_constraintBottom_toBottomOf="@+id/tvSuserName"
app:layout_constraintEnd_toEndOf="parent"
app:riv_corner_radius="8dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.facebook.shimmer.ShimmerFrameLayout>
【问题讨论】:
当然,通过膨胀和移除加载布局运行时是更干净的方法。有些人可能觉得这样做很难,但这是使布局层次结构清晰并优化内存的最佳方式。 我不确定,但我们可以在这种情况下使用视图切换器。 @MiniChip 我不这么认为。因为视图切换器会将两个视图都保留在内存中。 【参考方案1】:如果我假设正确,那么当您第一次加载屏幕时,所有视图都需要时间来渲染,无论它们是处于可见/不可见还是已消失状态。假设我的屏幕布局中有一个复杂的视图(假设自定义日期视图水平滑块),但我最初不需要这个视图,但是,我的屏幕打开时间会因为它的渲染而增加。对于这个 Android 有一个组件 ViewStub,你可以在你的 XML 中添加它,它是一个笨重的轻量级视图。 ViewStub 的特别之处在于它既不参与也不在布局中绘制任何内容。它的维度为零。 ViewStub 引用的布局仅在我们决定时才会膨胀并添加到 UI 中。这意味着每当 ViewStub 可见时,或调用 inflate() 方法时,布局资源都会被膨胀,然后 ViewStub 在其父级中用膨胀的资源替换自身。 ViewStub 仅存在于视图层次结构中,直到调用 setVisibility(int) 或 inflate()。膨胀的 View 使用 layout 参数添加到 ViewStub 的父级。 阅读下面的链接了解更多信息。
https://abhiandroid.com/ui/viewstub
【讨论】:
以上是关于什么是好方法,InflateView/removeView 或设置 Visibility.GONE?的主要内容,如果未能解决你的问题,请参考以下文章
在视图控制器之间传递数据 - iOS Xcode - 啥是好方法?