什么是好方法,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 - 啥是好方法?

什么是好的一次性伪随机洗牌? [关闭]

在处理 Proguard、MultiDex、测试和产品风味时,啥是好的策略?

什么是好代码?怎么写好代码?

想跳槽?先看什么是好工作

什么是好的隐形验证码? [关闭]