调整图像大小-折叠工具栏布局中出现闪烁问题

时间:2019-07-01 14:33:06

标签: android android-collapsingtoolbarlayout android-appbarlayout

我希望图像以折叠的工具栏布局显示,因此当我滚动下面的列表时,图像变小两倍,但不会完全消失。

到目前为止,我是通过以下代码实现的:

XML:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto">

<androidx.coordinatorlayout.widget.CoordinatorLayout android:layout_width="match_parent"
                                                     android:background="#fff"
                                                     android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout android:layout_width="match_parent"
                                                     android:id="@+id/appBar"
                                                     android:elevation="1dp"
                                                     android:layout_height="300dp">

        <com.google.android.material.appbar.CollapsingToolbarLayout android:layout_width="match_parent"
                                                                    app:expandedTitleGravity="bottom"
                                                                    android:minHeight="200dp"
                                                                    app:layout_scrollFlags="scroll|exitUntilCollapsed"
                                                                    android:layout_height="match_parent">


            <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent"
                                                               android:layout_height="wrap_content"
                                                               app:layout_collapseMode="pin"
                                                               android:layout_gravity="bottom"
                                                               android:orientation="vertical">

                <ImageView android:layout_width="200dp"
                           app:layout_constraintTop_toTopOf="parent"
                           app:layout_constraintStart_toStartOf="parent"
                           app:layout_constraintEnd_toEndOf="parent"
                           android:layout_height="200dp"
                           android:id="@+id/image"
                           android:scaleType="centerCrop"
                           android:src="@drawable/saya_no_uta"/>

                <TextView android:id="@+id/doStuff" android:layout_width="wrap_content"
                          app:layout_constraintEnd_toEndOf="parent"
                          app:layout_constraintTop_toTopOf="parent"
                          android:textColor="#fff"
                          android:layout_height="wrap_content" android:text="Do stuff"/>

                <LinearLayout
                        android:id="@+id/content"
                        android:background="#00f"
                        android:orientation="horizontal"
                        app:layout_constraintTop_toBottomOf="@id/image"
                        android:layout_width="match_parent"
                        android:layout_height="100dp">
                </LinearLayout>


            </androidx.constraintlayout.widget.ConstraintLayout>

        </com.google.android.material.appbar.CollapsingToolbarLayout>

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.core.widget.NestedScrollView android:layout_width="match_parent"
                                           app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"
                                           android:layout_height="match_parent">
        <TextView android:layout_width="match_parent"
                  android:text="@string/large_text"
                  android:layout_height="wrap_content"/>

    </androidx.core.widget.NestedScrollView>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

科特琳:

class CollapsingToolbarFragment : Fragment() {

companion object {
    const val TAG = "CollapsingToolbarLayout"
}

var originalHeight: Float = 0.0f
var lastVerticalOffset: Int = Int.MAX_VALUE

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    val binding = FragmentCollapsingToolbarBinding.inflate(inflater, container, false)
    originalHeight = convertDpToPixel(200.0f)
    binding.lifecycleOwner = viewLifecycleOwner
    binding.appBar.addOnOffsetChangedListener(AppBarLayout.OnOffsetChangedListener { appBarLayout, verticalOffset ->
        if (lastVerticalOffset == verticalOffset) {
            return@OnOffsetChangedListener
        }
        lastVerticalOffset = verticalOffset
        val totalScrollRange = appBarLayout.totalScrollRange
        Log.i("Hello", "total: $totalScrollRange, offset: $verticalOffset")
        val size = originalHeight.toInt() + verticalOffset
        binding.image.layoutParams.height = size
        binding.image.layoutParams.width = size
        binding.image.requestLayout()
    })
    return binding.root
}

fun convertDpToPixel(dp: Float): Float {
    return dp * (requireContext().resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}

}

它的工作原理与预期的一样,但是有副作用。当我快速向上或向下滚动时,我可以瞬间看到带有文本“执行任务”的textview在其位置上下浮动一小段,这确实很烦人。这可能是由于我只是手动调用 requestLayout()而已,但是我还必须通过什么其他方法在 OnOffsetChangedListener 中调整图像大小?

或者我可以采取其他方法吗?

2 个答案:

答案 0 :(得分:0)

如果有人想知道,我可以通过在ImageView上使用scaleX,scaleY和translationY属性而不是请求布局来获得更好的结果。我也将编辑TextView移到了约束布局之外。

在不同的代码库中,这是我的onOffsetChanged的样子:

override fun onOffsetChanged(appBarLayout: AppBarLayout, verticalOffset: Int) {
    if (scrollRange == -1) {
        scrollRange = binding.appBarLayout.totalScrollRange
    }

    val delta = 1.0f - abs(verticalOffset).toFloat() / scrollRange.toFloat() * 0.5f
    binding.avatar.scaleX = 0.2f + delta * 0.8f
    binding.avatar.scaleY = 0.2f + delta * 0.8f
    binding.avatar.translationY = delta * 0.5f * abs(verticalOffset)
}

答案 1 :(得分:0)

您可以编写自定义的collapsingtoolbarlayout来重写OffsetUpdateListener来更改图像大小。