问题
Inside OnBindViewHolder
of my RecyclerView
Adapter
, I got multiple items. One of those (ITEM_TRATAMENTOS) got a setOnClickListener which has the purpose of create an LinearLayout
when I click in an button (add_field_btn). The problem is that the only argument of getSystemService
is unresolved (Context.LAYOUT_INFLATER_SERVICE).
In ViewPagers
it works fine, but inside OnBindViewHolder, it's not the case.
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)
}
}
The expected result is to create the new line, which it works if it was on an normal activity.
回答1:
An alternative solution is to get the LayoutInflater
from parentLinearLayout
ViewGroup.
Example
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
}
Also, be aware of the consequences of adding too many views without recycling them. Probably you'd need another RecyclerView
if the number is big enough.
回答2:
Step #1: Add a LayoutInflater
parameter to the constructor of your RecyclerView.Adapter
subclass.
Step #2: When you create the RecyclerView.Adapter
, pass in a LayoutInflater
, obtained from getLayoutInflater()
on your activity.
For example, here is a RecyclerView.Adapter
named 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.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)
}
}
}
Notice that my ColorAdapter
constructor has private val inflater: LayoutInflater
as a parameter.
Here is the activity that uses that 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()
}
Since you and I are both writing in Kotlin, the getLayoutInflater()
call turns into a reference to the layoutInflater
property on the activity. So, when I create my ColorAdapter
, I use ColorAdapter(layoutInflater)
, to pass in an instance of LayoutInflater
.
来源:https://stackoverflow.com/questions/53981684/unresolved-reference-layout-inflater-service-inside-onbindviewholder