【问题标题】:Unresolved reference: LAYOUT_INFLATER_SERVICE inside onBindViewHolder未解决的参考:onBindViewHolder 内的 LAYOUT_INFLATER_SERVICE
【发布时间】:2018-12-30 21:46:42
【问题描述】:

在我的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)
            }
  }

预期的结果是创建新行,如果它在正常活动中,它将起作用。

【问题讨论】:

  • getSystemService() 不是Context 上的static 方法。这是一种常规(实例)方法。您需要在 Context 实例上调用它,而不是在 Context 类上。恕我直言,最好的解决方案是在您的活动上调用 getLayoutInflater(),然后通过其构造函数将 LayoutInflater 传递给 RecyclerView.Adapter
  • 如何在我的活动中调用 getLayoutInflater? @CommonsWare
  • 我假设您正在某处的活动函数中创建您的RecyclerView.Adapter。因此,在该函数中,调用 getLayoutInflater(),并将该值传递给适配器的构造函数。
  • 喜欢这个? : adapter= AdapterCaracterization( this, listSectionType = listSectionType) recyclerView.adapter = adapter layoutInflater.inflate(R.layout.used_products_field, null) 这对我没有任何意义。那么 getSystemService 呢? @CommonsWare
  • 我认为您只是缺少上下文实例。它可以以某种方式传递到这里,或者您可以在某个地方编写一个可以获取全局应用程序上下文的方法。

标签: android kotlin adapter layout-inflater


【解决方案1】:

另一种解决方案是从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

【讨论】:

    【解决方案2】:

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

    第 2 步:创建RecyclerView.Adapter 时,传入一个LayoutInflater,该LayoutInflater 是从您的活动的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 的活动:

    /*
      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() 调用会变成对活动上 layoutInflater 属性的引用。所以,当我创建ColorAdapter 时,我使用ColorAdapter(layoutInflater) 来传递LayoutInflater 的实例。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-17
      • 2016-12-14
      • 2020-05-27
      • 2019-11-16
      • 2021-01-24
      • 2023-03-25
      • 2021-08-13
      相关资源
      最近更新 更多