使用Android数据绑定在Kotlin中初始化RecyclerView会引发错误。 我究竟做错了什么?

描述

我正尝试在Kotlin中使用Android数据绑定的RecyclerView设置Android屏幕。 我有一个活动,其中包含一个片段和片段包含一个RecyclerView,我初始化与数据绑定。

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

这是我的活动:

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时,在我的recyclerview上出现错误:

java.lang.IllegalStateException:指定的子项已经有父项。 您必须先调用子对象的父对象的removeView()。

所以我的问题是:我做错了什么? 我是否正确使用数据绑定? Kotlin在数据绑定方面不够好? 任何帮助或反馈将不胜感激。

编辑:

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

06-14 21:34:44.876 3631-3631 / com.kinler.mtgutility E / AndroidRuntime:致命异常:main处理:com.kinler.mtgutility,PID:3631 java.lang.IllegalStateException:指定的子项已经有父项。 您必须先调用子对象的父对象的removeView()。 在android.support.android.view.ViewGroup.addView(ViewGroup.java:4656)android.view.ViewGroup.addView(ViewGroup.java:4716)android.view.ViewGroup.addViewInner(ViewGroup.java:4885)。 v7.widget.RecyclerView $ 5.addView(RecyclerView.java:751)在android.support.v7.widget.ChildHelper.addView(ChildHelper.java:107)在android.support.v7.widget.RecyclerView $ LayoutManager.addViewInt(RecyclerView .java:7995)at android.support.v7.widget.RecyclerView $ LayoutManager.addView(RecyclerView.java:7953)at android.support.v7.widget.RecyclerView $ LayoutManager.addView(RecyclerView.java:7941)at android。 android.support.v7.widget.LineoutManager.layoutChunk(LinearLayoutManager.java:1552)在android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1498)在android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager。 java:591)at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3691)at android.support.v7.widget.RecyclerView.dispatchLayout(R 在android.view.View.layout(View.java:19393)在android.view.ViewGroup.layout(ViewGroup)在android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3960)ecyclerView.java:3408) .java:6022)在android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)在android.widget.FrameLayout.onLayout(FrameLayout.java:261)在android.view.View.layout(View.java:19393)在android.view.android.widget.FrameLayout.onLayout(FrameLayout.java:261)android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)android.view.ViewGroup.layout(ViewGroup.java:6022)。在android.widget.LayoutLayout.setChildFrame(LinearLayout.java:1791)在android.widget.LinearLayout.layoutVertical(LinearLayout)的android.view.ViewGroup.layout(ViewGroup.java:6022)View.layout(View.java:19393) .java:1635)在android.view.View.Group.layout(ViewGroup.java:6022)android.view.View.layout(View.java:19393)android.widget.LinearLayout.onLayout(LinearLayout.java:1544)在android.widget.FrameLayout.layoutChildren(Fr (android.view.java:19393)android.view.ViewGroup.layout(ViewGroup.java:6022)android.widget.FrameLayout.onLayout(FrameLayout.java:261)在android.view.layout(View.java:19393) )在android.view.View.Group.layout(ViewGroup.java:6022)android.view.View.layout(View.java:19393)com.android.internal.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:493) android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)at android.widget.FrameLayout.onLayout(FrameLayout.java:261)at com.android.internal.policy.DecorView.onLayout(DecorView.java:736)at android.view.View.platform(View.java:19393)android.view.ViewGroup.layout(ViewGroup.java:6022)android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2480)at android.view.ViewRootImpl .performTraversals(ViewRootImpl.java:2199)at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1385)at android.view.ViewRootImpl $ TraversalRunnable.run(ViewRootImpl.java:6722)at android.view.Choreographer $ CallbackRecord。运行(C horeographer.java:886)在android.view.Choreographer.doCallbacks(Choreographer.java:698)在android.view.Choreographer.doFrame(Choreographer.java:633)在android.view.Choreographer $ FrameDisplayEventReceiver.run(Choreographer.java :872)at android.os.Handler.handleCallback(Handler.java:769)at android.os.Handler.dispatchMessage(Handler.java:98)at android.os.Looper.loop(Looper.java:164)at android .app.ActivityThread.main(ActivityThread.java:6540)at com.android.internal.os.Zygote $ MethodAndArgsCaller.run(Zygote.java:240)at com.lang.reflect.Method.invoke(Native Method) .android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

编辑2:

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

编辑3:

这是我的适配器代码:

 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 } 

和我的持有人代码:

 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) } } 

您正在使用HomeCardViewHolder(binding.homeCardTitle, binding)创建视图持有者。 itemView参数应该是根视图。 根据名称判断, homeCardTitle可能是绑定本身层次结构中的一个视图。 因此它已经有一个父母不能被添加到回收者视图。

所以实例化与HomeCardViewHolder(binding.root, binding)的视图持有人。

或者仅仅向视图持有者提供绑定。

 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) } }