未解决的参考:LAYOUT_INFLATER_SERVICE inside onBindViewHolder

Unresolved reference: LAYOUT_INFLATER_SERVICE inside onBindViewHolder

在我的 RecyclerView AdapterOnBindViewHolder 中,我得到了多个项目。其中之一 (ITEM_TRATAMENTOS) 有一个 setOnClickListener,它的目的是在我单击按钮 (add_field_btn) 时创建一个 LinearLayout。问题是 getSystemService 的唯一参数未解决 (Context.LAYOUT_INFLATER_SERVICE).

ViewPagers中它工作正常,但在OnBindViewHolder中,情况并非如此。

 ITEM_TRATAMENTOS ->{
      val viewHolderTratamentos = holder as ViewHolderItemTratamentos
      holder.add_field_btn.setOnClickListener {
                    inflater = Context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
                    val rowView = inflater.inflate(R.layout.used_products_field, null)
                    // Add the new row.
                    parentLinearLayout?.addView(rowView, parentLinearLayout?.childCount!! - 1)
            }
  }

预期的结果是创建新行,如果它在正常 activity 上,它就可以工作。

第 1 步:将 LayoutInflater 参数添加到 RecyclerView.Adapter 子类的构造函数中。

第 2 步:当您创建 RecyclerView.Adapter 时,传入一个 LayoutInflater,从 activity 上的 getLayoutInflater() 获得。

例如,这里有一个名为 ColorAdapterRecyclerView.Adapter:

/*
  Copyright (c) 2018 CommonsWare, LLC

  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  use this file except in compliance with the License. You may obtain   a copy
  of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
  by applicable law or agreed to in writing, software distributed under the
  License is distributed on an "AS IS" BASIS,   WITHOUT WARRANTIES OR CONDITIONS
  OF ANY KIND, either express or implied. See the License for the specific
  language governing permissions and limitations under the License.

  Covered in detail in the book _Elements of Android Jetpack_

  https://commonsware.com/Jetpack
*/

package com.commonsware.jetpack.sampler.recyclerview

import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter

class ColorAdapter(private val inflater: LayoutInflater) :
  ListAdapter<Int, ColorViewHolder>(ColorDiffer) {

  override fun onCreateViewHolder(
    parent: ViewGroup,
    viewType: Int
  ): ColorViewHolder {
    return ColorViewHolder(inflater.inflate(R.layout.row, parent, false))
  }

  override fun onBindViewHolder(holder: ColorViewHolder, position: Int) {
    holder.bindTo(getItem(position))
  }

  private object ColorDiffer : DiffUtil.ItemCallback<Int>() {
    override fun areItemsTheSame(oldColor: Int, newColor: Int): Boolean {
      return oldColor == newColor
    }

    override fun areContentsTheSame(oldColor: Int, newColor: Int): Boolean {
      return areItemsTheSame(oldColor, newColor)
    }
  }
}

请注意,我的 ColorAdapter 构造函数将 private val inflater: LayoutInflater 作为参数。

这是使用 ColorAdapter 的 activity:

/*
  Copyright (c) 2018 CommonsWare, LLC

  Licensed under the Apache License, Version 2.0 (the "License"); you may not
  use this file except in compliance with the License. You may obtain   a copy
  of the License at http://www.apache.org/licenses/LICENSE-2.0. Unless required
  by applicable law or agreed to in writing, software distributed under the
  License is distributed on an "AS IS" BASIS,   WITHOUT WARRANTIES OR CONDITIONS
  OF ANY KIND, either express or implied. See the License for the specific
  language governing permissions and limitations under the License.

  Covered in detail in the book _Elements of Android Jetpack_

  https://commonsware.com/Jetpack
*/

package com.commonsware.jetpack.sampler.recyclerview

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.DividerItemDecoration
import androidx.recyclerview.widget.LinearLayoutManager
import kotlinx.android.synthetic.main.activity_main.*
import java.util.*

class MainActivity : AppCompatActivity() {
  private val random = Random()

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    items.apply {
      layoutManager = LinearLayoutManager(this@MainActivity)
      addItemDecoration(
        DividerItemDecoration(this@MainActivity, DividerItemDecoration.HORIZONTAL)
      )
      adapter = ColorAdapter(layoutInflater).apply {
        submitList(buildItems())
      }
    }
  }

  private fun buildItems() = generateSequence { random.nextInt() }
    .take(25)
    .toList()
}

因为你和我都在用 Kotlin 编写,所以 getLayoutInflater() 调用变成了对 activity 上的 layoutInflater 属性 的引用。因此,当我创建 ColorAdapter 时,我使用 ColorAdapter(layoutInflater) 来传递 LayoutInflater.

的实例

另一种解决方案是从 parentLinearLayout ViewGroup 获取 LayoutInflater

例子

parentLinearLayout?.apply { 
    val inflater = LayoutInflater.from(context) // context is now available in the receiver scope
    val rowView = inflater.inflate(R.layout.used_products_field, this, false)
    addView(rowView) // Add the view to the last position
}

另外,请注意添加过多视图而不回收它们的后果。如果数量足够大,您可能需要另一个 RecyclerView