自定义可扩展/可折叠CardView

时间:2018-12-28 02:59:34

标签: android kotlin android-custom-view android-cardview

背景

我一直在尝试使用对此SO question的答案提供的解决方案作为基础来实现自己的可折叠/可扩展CardView。我一直在用Kotlin而不是Java来尝试这一点,这很可爱,因为我可以简单地将扩展功能添加到CardView类中。我编写的代码如下(从原始Java答案大致翻译成Kotlin):

Kotlin中的展开/折叠功能

fun CardView.collapse(collapsedHeight: Int) {
    val initialHeight = measuredHeight
    val distanceToCollapse = initialHeight - collapsedHeight
    val animation = object: Animation() {

        override fun applyTransformation(interpolatedTime: Float, t: Transformation?) {
            layoutParams.height = (initialHeight - (distanceToCollapse * interpolatedTime)).toInt()
            requestLayout()
        }

        override fun willChangeBounds() = true
    }

    animation.duration = distanceToCollapse.toLong()
    startAnimation(animation)
}

fun CardView.expand() {
    val initialHeight = height

    measure(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.WRAP_CONTENT)
    val targetHeight = measuredHeight

    val distanceToExpand = targetHeight - initialHeight

    val animation = object : Animation(){

        override fun applyTransformation(interpolatedTime: Float, t: Transformation?) {
            layoutParams.height = initialHeight + (distanceToExpand * interpolatedTime).toInt()
            requestLayout()
        }

        override fun willChangeBounds() = true
    }

    animation.duration = distanceToExpand.toLong()
    startAnimation(animation)
}

fun CardView.isExpanded() = layoutParams.height == FrameLayout.LayoutParams.WRAP_CONTENT

问题

collapse()函数工作正常,但是我真正的问题是expand()。视频可以更好地解决问题所在:

enter image description here

我觉得这与以下事实有关:CardView折叠后,它不再知道其包含的所有子视图的大小。但这只是我的最初理论...我的布局XML如下:

布局XML

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/cv_experience"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="@dimen/base_size"
    app:cardElevation="2dp">

    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="@dimen/base_size">

        <TextView
            android:id="@+id/tv_experience_section"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            style="@style/TextAppearance.AppCompat.Headline"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            tools:text="Experience"/>


        <android.support.v7.widget.RecyclerView
            android:id="@+id/rv_experience_companies"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toBottomOf="@id/tv_experience_section"
            app:layout_constraintStart_toStartOf="@id/tv_experience_section" />



    </android.support.constraint.ConstraintLayout>


</android.support.v7.widget.CardView>

有人会对导致此问题的原因有任何想法吗?

更新#1

经过进一步调试,我发现measuredHeight中的expand()返回了一个巨大的值:它总是在5,000左右。这可以解释为什么{{1 }}已展开。但是,我真的不知道为什么它会返回如此巨大的价值。有问题的代码如下:

CardView

0 个答案:

没有答案