Android RecyclerView 项目宽度不匹配父和预览不匹配模拟器

Posted

技术标签:

【中文标题】Android RecyclerView 项目宽度不匹配父和预览不匹配模拟器【英文标题】:Android RecyclerView item width doesn't match parent and preview doesn't match emulator 【发布时间】:2021-09-18 01:13:43 【问题描述】:

这是我的回收站查看项目 xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/recyclerItem"
    app:cardElevation="10dp"
    app:cardUseCompatPadding="false"
    app:cardCornerRadius="10dp">

   <LinearLayout
       android:layout_
       android:layout_>

       <ImageView
           android:id="@+id/recyclerItemImageView"
           android:padding="8dp"
           android:src="@mipmap/ic_launcher"
           android:layout_
           android:layout_>
       </ImageView>

       <TextView
           android:id="@+id/recyclerItemTextView"
           android:layout_marginStart="4dp"
           android:textSize="18sp"
           android:textColor="@color/black"
           android:text="item"
           android:layout_
           android:layout_>
       </TextView>

   </LinearLayout>

</androidx.cardview.widget.CardView>
    

然后像这样预览给我看:

Preview

但是模拟器的结果是这样的:

Emulator result

所以回收站视图中的项目与模拟器上的父级宽度不匹配。其他xml有:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    tools:context=".MainActivity">

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragmentContainerView"
        android:layout_margin="16dp"
        android:name="com.example.databinding_practice.ListFragment"
        android:layout_
        android:layout_
        android:layout_below="@id/activityTextView"/>

    <TextView
        android:id="@+id/activityTextView"
        android:layout_margin="16dp"
        android:layout_
        android:layout_
        android:text="Hello World!"
        android:textColor="@color/black"
        android:textSize="20sp" />

</RelativeLayout>

和片段:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    tools:context=".ListFragment">


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_
        android:layout_
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
    
</androidx.constraintlayout.widget.ConstraintLayout>

适配器类和 ListFragment 如下:

RecyclerAdapter.kt:

class RecyclerAdapter(var recyclerItems: ArrayList<RecyclerItemModel>) : RecyclerView.Adapter<RecyclerAdapter.RecyclerViewHolder>() 

    class RecyclerViewHolder(val binding: RecyclerItemBinding) : RecyclerView.ViewHolder(binding.root) 

    

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder 
        val binding = RecyclerItemBinding.inflate(LayoutInflater.from(parent.context))
        return RecyclerViewHolder(binding)
    

    override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) 
        holder.binding.recyclerItemTextView.text = recyclerItems[position].text
        recyclerItems[position].imageMipmapSource?.let  holder.binding.recyclerItemImageView.setImageResource(it) 
    

    override fun getItemCount(): Int 
        return recyclerItems.size
    

ListFragment.kt:

class ListFragment : Fragment() 
    private var itemList : ArrayList<RecyclerItemModel> = arrayListOf()
    private var recyclerAdapter: RecyclerAdapter = RecyclerAdapter(arrayListOf())
    private lateinit var fragmentListBinding: FragmentListBinding

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? 
        fragmentListBinding = FragmentListBinding.inflate(layoutInflater)
        return fragmentListBinding.root
    

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
        super.onViewCreated(view, savedInstanceState)


        for (i in 0..3)
            itemList.add(RecyclerItemModel(R.mipmap.ic_launcher,"Item $i"))
        



        fragmentListBinding.recyclerView.layoutManager = LinearLayoutManager(context)
        fragmentListBinding.recyclerView.adapter = recyclerAdapter
        recyclerAdapter.recyclerItems = itemList
        recyclerAdapter.notifyDataSetChanged()
    

我哪里做错了?如果我将匹配父级替换为固定大小,例如 200 dp - 300dp ,那可以正常工作,但匹配父级不能。为什么预览和模拟器不匹配?谢谢。

【问题讨论】:

你能用布局检查器调试吗? developer.android.com/studio/debug/layout-inspector 您还需要检查您的inflate 电话(替换为inflate(LayoutInflater.from(context), this, true) 当我替换 RecyclerItemBinding.inflate(LayoutInflater.from(parent.context),parent,false) 这对我有用。非常感谢。 【参考方案1】:

在片段中,您应该在 RecyclerView 中将 layout_widthlayout_height 更改为 "0dp"

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    tools:context=".ListFragment">


    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:layout_
        android:layout_
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

【讨论】:

没有效果 :( ,问题是布局膨胀。这应该是RecyclerItemBinding.inflate(LayoutInflater.from(parent.context),parent,false)。谢谢。 有 Java 版本吗?我找不到RecyclerItemBinding @reactor 不,RecyclerItemBinding 是在项目中使用视图绑定功能时通过视图绑定生成的绑定类。这里link

以上是关于Android RecyclerView 项目宽度不匹配父和预览不匹配模拟器的主要内容,如果未能解决你的问题,请参考以下文章

在 RecyclerView 中获取一行的宽度和高度 - Android

Android recyclerview 只显示一行 宽度不适配

是否可以根据屏幕宽度使用gridLayoutManager调整recyclerview的行数和列数?

带有水平溢出的Android垂直recyclerview

水平 RecyclerView 不环绕布局

Android RecyclerView 列表加载图片宽高适配