首页 > 解决方案 > recyclerview 不渲染到屏幕

问题描述

我有以下 XML 文件 -

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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_width="match_parent"
    android:layout_height="match_parent"
    android:background="#E0E0E0 "
    android:orientation="vertical"
    tools:context=".fragments.CountriesListFragment">

    <androidx.appcompat.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/white"
        app:title="Countries" />

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/fragment_countries_list_countries_recyclerview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        tools:listitem="@layout/country_viewholder" />


</LinearLayout>

和以下片段 -

class CountriesListFragment : Fragment(R.layout.fragment_countries_list) {


    private lateinit var countriesViewModel: CountriesListViewModel
    private lateinit var countriesAdapter: CountriesListAdapter
    private var countriesList = mutableListOf<CountryEntity>()

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        setHasOptionsMenu(true)
        initViewModel()
        init()
    }


    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        inflater.inflate(R.menu.country_list_menu, menu)
        super.onCreateOptionsMenu(menu, inflater)
    }

    private fun initViewModel(){
        countriesViewModel = ViewModelProvider(this).get(CountriesListViewModel::class.java)
        countriesViewModel.fetchAllCountries(object : CountriesRepository.CountryFetchCallback {
            override fun onFetchError(reason: String) {
                Toast.makeText(context, reason, Toast.LENGTH_SHORT).show()
            }
        })
    }

    private fun init() {
        countriesAdapter = CountriesListAdapter(countriesList)
        countriesRecyclerview.adapter = countriesAdapter
        countriesRecyclerview.setHasFixedSize(true)
        countriesRecyclerview.layoutManager = LinearLayoutManager(context)
        countriesViewModel.getAllCountries().observe(requireActivity(), Observer { countryList ->
            countriesList.addAll(countryList)
            countriesAdapter.notifyDataSetChanged()
        })
    }
}

编辑 -

我的适配器 -

class CountriesListAdapter(private val countriesList: List<CountryEntity>) : RecyclerView.Adapter<CountryViewHolder>() {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CountryViewHolder {
        val view = LayoutInflater.from(App.context!!).inflate(R.layout.country_viewholder, parent, false)
        return CountryViewHolder(view)
    }

    override fun getItemCount(): Int  = countriesList.size

    override fun onBindViewHolder(holder: CountryViewHolder, position: Int) {
        holder.bind(countriesList[position])
    }

}

我的查看器 xml -

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tool="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:background="@color/white"
    android:orientation="vertical">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <TextView
                android:id="@+id/country_viewholder_native_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@color/black"
                android:textSize="16sp"
                tools:text="Country native name" />

            <TextView
                android:id="@+id/country_viewholder_country_name"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@color/black"
                android:textSize="16sp"
                tools:text="Country name" />

            <TextView
                android:id="@+id/country_viewholder_area"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:textColor="@color/black"
                android:textSize="16sp"
                tools:text="Area" />

        </LinearLayout>


        <Space
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1" />

        <ImageView
            android:id="@+id/country_viewholder_country_image"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            tools:src="@mipmap/ic_launcher" />

    </LinearLayout>


</LinearLayout>

持有片段的活动 -

<?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_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".CountriesListActivity">

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:navGraph="@navigation/app_navigation" />


</androidx.constraintlayout.widget.ConstraintLayout>

thw 导航图 -

<?xml version="1.0" encoding="utf-8"?>
<navigation 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:id="@+id/app_navigation"
    app:startDestination="@id/countriesListFragment">

    <fragment
        android:id="@+id/countriesListFragment"
        android:name="com.countriesborders.fragments.CountriesListFragment"
        android:label="fragment_countries_list"
        tools:layout="@layout/fragment_countries_list">
        <action
            android:id="@+id/action_countriesListFragment_to_countryBordersFragment"
            app:destination="@id/countryBordersFragment" />
    </fragment>
    <fragment
        android:id="@+id/countryBordersFragment"
        android:name="com.countriesborders.fragments.CountryBordersFragment"
        android:label="fragment_country_borders"
        tools:layout="@layout/fragment_country_borders" />
</navigation>

由于某种原因,数据没有呈现到屏幕上。我真的不知道是什么原因造成的,但我对正在发生的事情一无所知。

我尝试将手动硬编码的值添加到列表中,但它根本没有帮助。

任何想法?

标签: androidandroid-recyclerviewandroid-adapter

解决方案


您的布局中有两个相互冲突的维度。

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:orientation="vertical">

如您所见,最内部的一个是指示系统绘制与父高度匹配的项目,但父布局说要包装其内容(最终导致高度为 0)。如果将内部的更改为 match_parent,它将起作用并显示项目。


推荐阅读