无法在 RecyclerView 中获取 CoordinatorLayout LayoutParams

Unable to get CoordinatorLayout LayoutParams in RecyclerView

我想使用 CoordinatorLayout 实现滑动删除,所以我为 RecyclerView

的每个项目创建了简单的 xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:id="@+id/coordinatorLayout"
    android:layout_height="wrap_content">

    <TextView
        android:id="@+id/simpleModelName"
        android:layout_width="wrap_content"
        android:textSize="16sp"
        android:padding="10dp"
        android:layout_height="wrap_content" />

</android.support.design.widget.CoordinatorLayout>

和简单的适配器

open class SwipeableAdapter(val list:ArrayList<SimpleModel>) : RecyclerView.Adapter<SwipeableAdapter.ViewHolder>() {
    inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        var nameTextView: TextView
        var coordinatorLayout: CoordinatorLayout

        init {
            nameTextView = view.findViewById(R.id.simpleModelName)
            coordinatorLayout = view.findViewById(R.id.coordinatorLayout)
        }
    }

    override fun onCreateViewHolder(viewGroup: ViewGroup, i: Int): SwipeableAdapter.ViewHolder {
        val view = LayoutInflater.from(viewGroup.context).inflate(R.layout.item_simple_model, viewGroup, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(viewHolder: SwipeableAdapter.ViewHolder, position: Int) {
        viewHolder.nameTextView.text = list[position].name

        var swipe = SwipeDismissBehavior<View>()
        swipe.setSwipeDirection(SwipeDismissBehavior.SWIPE_DIRECTION_END_TO_START)
        swipe.setListener(object : SwipeDismissBehavior.OnDismissListener {
            override fun onDismiss(view: View?) {
            }

            override fun onDragStateChanged(state: Int) {
            }
        })

        Log.e("onBindViewHolder","layout "+viewHolder.coordinatorLayout.javaClass.toString())
        Log.e("onBindViewHolder","layout "+viewHolder.coordinatorLayout.layoutParams.javaClass.toString())
        val coordinatorLayoutParams = viewHolder.coordinatorLayout.layoutParams as CoordinatorLayout.LayoutParams
        coordinatorLayoutParams.behavior = swipe

    }

    override fun getItemCount(): Int {
        return list.size
    }
}

这一行有问题:

    val coordinatorLayoutParams = viewHolder.coordinatorLayout.layoutParams as CoordinatorLayout.LayoutParams

我的堆栈跟踪崩溃了:

java.lang.ClassCastException: android.support.v7.widget.RecyclerView$LayoutParams cannot be cast to android.support.design.widget.CoordinatorLayout$LayoutParams
 at app.deadmc.swipeablelayout.SwipeableAdapter.onBindViewHolder(SwipeableAdapter.kt:43)
 at app.deadmc.swipeablelayout.SwipeableAdapter.onBindViewHolder(SwipeableAdapter.kt:12)
 at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:6508)
 at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:6541)
 at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:5484)
 at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5750)
 at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5589)
 at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:5585)
 at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2231)
 at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1558)
 at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1518)
 at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:610)
 at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3719)
 at android.support.v7.widget.RecyclerView.onMeasure(RecyclerView.java:3135)
 at android.view.View.measure(View.java:19861)
 at android.support.constraint.ConstraintLayout.internalMeasureChildren(ConstraintLayout.java:934)
 at android.support.constraint.ConstraintLayout.onMeasure(ConstraintLayout.java:973)

好的,开始检查是什么问题,记录下来,发现

        Log.e("tag","layout "+viewHolder.coordinatorLayout.javaClass.toString())
        Log.e("tag","layout "+viewHolder.coordinatorLayout.layoutParams.javaClass.toString())

演出

12-29 13:46:16.310 19129-19129/? E/tag: layout class android.support.design.widget.CoordinatorLayout
12-29 13:46:16.310 19129-19129/? E/tag: layout class android.support.v7.widget.RecyclerView$LayoutParams

问题是:

我做错了什么? 为什么 CoordinatorLayout 给我 RecyclerView$LayoutParams

coordinatorLayoutRecyclerView 的直接 child,因此 LayoutParams 适合这种关系。 CoordinatorLayout 的 children 很可能有 CoordinatorLayout.LayoutParams.

但您不需要 CoordinatorLayout 即可使用 RecyclerView 实现滑动删除操作。 ItemTouchHelper and the ItemTouchHelper.Callback.onSwiped() 回调直接支持。

给定视图的布局参数旨在供包含布局使用,即父级 ViewGroup。因此,由于您的 CoordinatorLayoutRecyclerView 内,所以它是 RecyclerView.LayoutParams

具有 CoordinatorLayout.LayoutParams 的视图是 @id/simpleModelName,它将由 CoordinatorLayout 布局。

希望这能说明问题。