英文:
Unable to center recyclerview item
问题
以下是您要翻译的内容:
在为了使我的RecyclerView适配器更加动态,我通过编程方式将宽度设置为特定百分比。但我现在无法将项目居中,似乎在XML中硬编码边距适用于RecyclerView项可以解决问题,但这不是理想的解决方法。似乎"android:gravity"不是RecyclerView上可用的属性。任何地方都似乎不起作用。我尝试在我的"ViewHolder.from(parent).apply"中编程方式添加填充,但出现错误"Val cannot be reassigned"。
我已经没有更多的想法了,有什么帮助吗?我在RecyclerView项中使用ConstraintLayout。
```kotlin
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder.from(parent).apply {
val targetWidth = parent.measuredWidth * 0.9
itemView.layoutParams.width = targetWidth.toInt()
}
}
我的适配器代码
package com.example.recyclerview_2.view
import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.view.marginEnd
import androidx.core.view.marginStart
import androidx.recyclerview.widget.AsyncDifferConfig
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.recyclerview_2.R
import com.example.recyclerview_2.databinding.RecyclerviewItemBinding
import com.example.recyclerview_2.model.models.Bill
import com.example.recyclerview_2.utils.Format
import kotlin.reflect.KFunction1
private const val TAG = "Adapter"
class Adapter(private val itemClickListener: KFunction1<Bill, Unit>) : ListAdapter<Bill, Adapter.ViewHolder>(AsyncDifferConfig.Builder<Bill>(DiffCallBack()).build()) {
class ViewHolder(val binding: RecyclerviewItemBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(data: Bill, itemClickListener: () -> Unit){
binding.billName.text = data.name.replaceFirstChar {
it.uppercase()
}
binding.billAmt.text = Format.addTrailingZeros(data.amount) + "$"
binding.dateDue = data.dateDue
if(data.reoccurring){
binding.reoccurring = data.reoccurringInterval
}else{
binding.billReoccuring.text = "Bill is not reoccurring"
}
itemView.setOnClickListener {
Log.d("Clicked","${data._id}")
itemClickListener()
}
}
companion object{
fun from(parent: ViewGroup): ViewHolder {
var layoutInflater = LayoutInflater.from(parent.context)
var binding = RecyclerviewItemBinding.inflate(layoutInflater, parent, false)
return ViewHolder(binding)
}
}
}
private class DiffCallBack : DiffUtil.ItemCallback<Bill>(){
override fun areItemsTheSame(oldItem: Bill, newItem: Bill): Boolean = oldItem._id == newItem._id
override fun areContentsTheSame(oldItem: Bill, newItem: Bill): Boolean = oldItem == newItem
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder.from(parent).apply {
val targetWidth = parent.measuredWidth * 0.9
itemView.layoutParams.width = targetWidth.toInt()
}
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = currentList[position]
holder.bind(item, { itemClickListener(item) })
}
override fun getItemCount(): Int {
return currentList.size
}
}
[![图片1][1]][1]
[![图片2][2]][2]
[1]: https://i.stack.imgur.com/fJFVH.png
[2]: https://i.stack.imgur.com/ikO4W.png
<details>
<summary>英文:</summary>
In order to make my recyclerview adapter more dynamic I programmatically have set the width to be a certain percentage. But I cannot now center the items, appears hardcoding margin in the XML for the recyclerview item works, but this is not ideal. Appears "android:gravity" is not an available attribute on recyclerview. android:layout_gravity anywhere doesnt seem to work. I though that I would try in my "ViewHolder.from(parent).apply to programmatically add padding but I get an error "Val cannot be reassigned"
[![picture1][1]][1]
Im out of ideas at this point, any help? Im using constraintLayout for my recyclerview item.
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder.from(parent).apply {
val targetWidth = parent.measuredWidth * .9
itemView.layoutParams.width = targetWidth.toInt()
}
}
My Adapter code
package com.example.recyclerview_2.view
import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.TextView
import androidx.core.view.marginEnd
import androidx.core.view.marginStart
import androidx.recyclerview.widget.AsyncDifferConfig
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.example.recyclerview_2.R
import com.example.recyclerview_2.databinding.RecyclerviewItemBinding
import com.example.recyclerview_2.model.models.Bill
import com.example.recyclerview_2.utils.Format
import kotlin.reflect.KFunction1
private const val TAG = "Adapter"
class Adapter(private val itemClickListener: KFunction1<Bill, Unit>) : ListAdapter<Bill, Adapter.ViewHolder>(AsyncDifferConfig.Builder<Bill>(DiffCallBack()).build()) {
//When a inner keyword is used here you cannot create a companion object
//When the 'inner' keyword is used members of the outer class are all accessible
class ViewHolder(val binding: RecyclerviewItemBinding) : RecyclerView.ViewHolder(binding.root) {
fun bind(data: Bill, itemClickListener: () -> Unit){
binding.billName.text = data.name.replaceFirstChar {
it.uppercase()
}
binding.billAmt.text = Format.addTrailingZeros(data.amount) + "$"
binding.dateDue = data.dateDue
if(data.reoccurring){
binding.reoccurring = data.reoccurringInterval
}else{
binding.billReoccuring.text = "Bill is not reoccurring"
}
itemView.setOnClickListener {
Log.d("ClickED","${data._id}")
itemClickListener()
}
}
companion object{
fun from(parent: ViewGroup): ViewHolder {
var layoutInflater = LayoutInflater.from(parent.context)
var binding = RecyclerviewItemBinding.inflate(layoutInflater, parent, false)
return ViewHolder(binding)
}
}
}
private class DiffCallBack : DiffUtil.ItemCallback<Bill>(){
override fun areItemsTheSame(oldItem: Bill, newItem: Bill): Boolean = oldItem._id == newItem._id
override fun areContentsTheSame(oldItem: Bill, newItem: Bill): Boolean = oldItem == newItem
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder.from(parent).apply {
val targetWidth = parent.measuredWidth * .9
itemView.layoutParams.width = targetWidth.toInt()
}
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = currentList[position]
holder.bind(item, { itemClickListener(item) })
}
override fun getItemCount(): Int {
return currentList.size
}
}
[![picture2][2]][2]
[1]: https://i.stack.imgur.com/fJFVH.png
[2]: https://i.stack.imgur.com/ikO4W.png
</details>
# 答案1
**得分**: 1
`LayoutManager` 是负责管理 `RecyclerView` 中的项视图排列方式的部分。你可能应该只设计你的项布局(为 `ViewHolder` 填充的布局)以使其内容居中,即主要布局的宽度设置为 `wrap_content`,然后将*其中的内容*按照你的要求排列。这样做还可以提供更大的灵活性,因为这并不意味着*所有内容*都必须居中。
如果你希望内容占据宽度的 90%,你可以使用 `ConstraintLayout`,并在 5% 和 95% 处添加 [`Guideline`s][1] 并将内容约束到它。你还可以在主要布局内嵌套另一个布局,并使用 `layout_constraintWidth_percent` 将其宽度设置为 *0.9*(父布局宽度的 90%) - 个人认为这更有限制性(而不是具有一个扁平的布局),但这取决于你。
请记住,如果需要带有背景的“内容区域”,你可以添加普通的 `View`,并将其置于其他视图的后面 - 它们*不需要*在另一个布局内部!
[1]: https://developer.android.com/develop/ui/views/layout/constraint-layout#constrain-to-a-guideline
<details>
<summary>英文:</summary>
The `LayoutManager` is what handles how item views are arranged in the `RecyclerView`. You should probably just design your item layout (the one you inflate for the `ViewHolder`) to have its contents centred, i.e. the main layout with width `wrap_content`, then the stuff *inside that* arranged how you want it. This also gives you more flexibility, since it doesn't mean *everything* has to be centred.
If you want your content to take up 90% of the width, you could use a `ConstraintLayout` with [`Guideline`s][1] at 5% and 95% and constrain stuff to that. You could also nest another layout inside that main layout, and constrain its width with `layout_constraintWidth_percent` set to *0.9* (90% of the parent's width) - personally I feel like that's more limiting (instead of having one flat layout) but it's up to you.
Remember you can add plain `View`s if you need a *"content area"* with a background, and stick that behind the other views - they don't *need* to be inside another layout!
[1]: https://developer.android.com/develop/ui/views/layout/constraint-layout#constrain-to-a-guideline
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论