未解决的参考:LAYOUT_INFLATER_SERVICE inside onBindViewHolder
Unresolved reference: LAYOUT_INFLATER_SERVICE inside onBindViewHolder
在我的 RecyclerView
Adapter
的 OnBindViewHolder
中,我得到了多个项目。其中之一 (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()
获得。
例如,这里有一个名为 ColorAdapter
的 RecyclerView.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
。
在我的 RecyclerView
Adapter
的 OnBindViewHolder
中,我得到了多个项目。其中之一 (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()
获得。
例如,这里有一个名为 ColorAdapter
的 RecyclerView.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
。