提问者:小点点

在静态编程语言中使用Android数据绑定初始化RecyclerView会引发错误。我做错了什么?


我试图设置一个静态编程语言的Android屏幕,使用android数据绑定的RecyclerView。我有一个包含片段的活动,该片段包含我用数据绑定初始化的RecyclerView。

问题是,当我尝试设置回收视图的布局管理器时,应用程序会抛出一个IllegalStateException,抱怨指定的子视图(我假设这意味着Recycler视图或LayoutManager)已经有一个父视图,并且我需要运行RemoveView()。我尝试从Recycler视图中删除所有视图,但无济于事。

class HomeActivity : BaseActivity() {

    private lateinit var mBinding: ActivityHomeBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_home)

        if(savedInstanceState != null){
            return
        }

        val fragment = HomeFragment.newInstance()
        supportFragmentManager.beginTransaction().add(R.id.home_fragment_container, fragment).commit()
    }
}
class HomeFragment : BaseFragment() {

    private lateinit var mBinding: FragmentHomeBinding
    private lateinit var mRecyclerView: RecyclerView

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val testList = listOf("TEST TITLE")
        mBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_home, container, false)
        mRecyclerView = mBinding.homeRecyclerview
        mRecyclerView.adapter = HomeOptionsAdapter(testList, View.OnClickListener { Log.d("[onCreateView]:", "I've been clicked") })
        mRecyclerView.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
        return mBinding.root
    }

    companion object {
        fun newInstance(): HomeFragment {
            val fragment = HomeFragment()
            return fragment
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<layout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="joseph.kinler.mtgutility.fragments.HomeFragment">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/home_recyclerview"
            android:scrollbars="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>

    </FrameLayout>
</layout>

当我尝试运行它时,当我尝试设置LayoutManager时,我在我的回收器视图上得到一个错误:

java. lang.IllegalStateException:指定的孩子已经有一个父级。您必须先在孩子的父级上调用RemoveView()。

所以我的问题是:我做错了什么?我是否错误地使用了数据绑定?静态编程语言是否不能很好地处理数据绑定?任何帮助或反馈都将不胜感激。

以下是错误的完整堆栈跟踪:

昨晚我用日志做了更多的调试,看起来我的回收器视图正在正确初始化,适配器正在运行,它将创建一个ViewHolder并在抛出错误之前绑定它。我仍然不确定确切的错误发生在哪里,但我计划将日志语句添加到我的应用程序流中的更多位置,以找出问题发生的地方。

这是我的适配器代码:

class HomeOptionsAdapter(val items:List<String>, val itemListener: View.OnClickListener): RecyclerView.Adapter<HomeCardViewHolder>() {

    private val TAG = HomeOptionsAdapter::class.java.simpleName

    override fun onBindViewHolder(viewHolder: HomeCardViewHolder, position: Int) = viewHolder.bind(items[position], itemListener)

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HomeCardViewHolder {
        Log.d(TAG, "[onCreateViewHolder]")
        val inflater = LayoutInflater.from(parent.context)
        val binding = HomeCardBinding.inflate(inflater, parent, false)
        return HomeCardViewHolder(binding.homeCardTitle, binding)
    }

    override fun getItemCount(): Int = items.size
}

和我的View Holder代码:

class HomeCardViewHolder constructor(itemView: View, binding: HomeCardBinding): RecyclerView.ViewHolder(itemView) {

    private val TAG = HomeCardViewHolder::class.java.simpleName
    private var mBinding: HomeCardBinding

    init {
        mBinding = binding
    }

    fun bind(title: String, listener: View.OnClickListener) {
        Log.d(TAG, "[bind]")
        mBinding.homeCardTitle.text = title
        Log.d(TAG, title)
        mBinding.homeCardTitle.setOnClickListener(listener)
    }
}

共1个答案

匿名用户

您正在使用HomeCardViewHolder(bind. homCardTitle,绑定)创建视图持有者。不过,itemView参数应该是根视图。从名称来看,homCardTitle可能是绑定本身层次结构中的一个视图。因此它已经有一个父视图,不能添加到回收器视图中。

因此,请改为使用HomeCardViewHolder(bing. root,绑定)实例化视图持有者。

或者只给视图持有者单独提供绑定。

class HomeCardViewHolder constructor(val binding: HomeCardBinding): RecyclerView.ViewHolder(binding.root) {

    private val TAG = HomeCardViewHolder::class.java.simpleName

    fun bind(title: String, listener: View.OnClickListener) {
        Log.d(TAG, "[bind]")
        binding.homeCardTitle.text = title
        Log.d(TAG, title)
        binding.homeCardTitle.setOnClickListener(listener)
    }
}