温馨提示:本文翻译自stackoverflow.com,查看原文请点击:java - The RecyclerView is not getting the list(response)
android android-recyclerview java kotlin

java - RecyclerView没有得到列表(响应)

发布于 2020-03-27 15:50:02

我正在尝试使用Kotlin在RecyclerView中查看列表。我在片段类中编写RecyclerView ID,并在适配器中设置列表(响应),但未在RecyclerView中显示。下面的代码是写的,我不确定如何解决此问题。

有男子气概的Fragment,Adapter,xml文件和模型类的项目。

fragment_availabletender

此页面具有RecyclerView。

            <?xml version="1.0" encoding="utf-8"?>
            <layout 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">

                <!-- Data to make available to the XML via data binding. In this case,
                     the whole ViewModel, so that we can access the LiveData,
                     click handlers, and state variables. -->
                <data>
                    <variable
                        name="viewModel"
                        type= "com.bitcomm.main.ui.home.NotificationViewModel" />
                </data>

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">

                    <androidx.appcompat.widget.AppCompatSpinner
                        android:id="@+id/spinner2"
                        android:layout_width="93dp"
                        android:layout_height="39dp"
                        android:layout_alignParentRight="true"
                        android:entries="@array/array_name"
                        style="@style/spinnerItemStyle"
                        android:layout_alignParentEnd="true" />

                    <androidx.appcompat.widget.AppCompatSpinner
                        android:id="@+id/spinner1"
                        android:layout_width="93dp"
                        android:layout_height="39dp"
                        android:layout_toLeftOf="@+id/spinner2"
                        android:entries="@array/array_name1"
                        style="@style/spinnerItemStyle"
                        android:layout_toStartOf="@+id/spinner2" />

                    <androidx.recyclerview.widget.RecyclerView
                        android:id="@+id/tender_list"
                        android:layout_width="match_parent"
                        android:layout_height="match_parent"
                        android:background="#0f3b52"
                        android:color="@color/cardview_light_background"
                        android:padding="6dp"
                        android:layout_below="@+id/spinner2"
                        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
                      />
                </RelativeLayout>

模特班这堂课有模特儿

            data class TenderProperty(

                val id: String,
                // used to map img_src from the JSON to imgSrcUrl in our class
                @Json(name = "img_src") val imgSrcUrl: String,
                val type: String,
                val price: Double
            )

TenderViewModel在这里响应越来越

             private val _response = MutableLiveData<List<TenderProperty>>()

                // The external immutable LiveData for the response String
                val response: LiveData<List<TenderProperty>>
                    get() = _response

                private val _navigateToSelectedProperty = MutableLiveData<TenderProperty>()
                val navigateToSelectedProperty: LiveData<TenderProperty>
                    get() = _navigateToSelectedProperty

                // Create a Coroutine scope using a job to be able to cancel when needed
                private var viewModelJob = Job()

                // the Coroutine runs using the Main (UI) dispatcher
                private val coroutineScope = CoroutineScope(viewModelJob + Dispatchers.Main )

                /**
                 * Call getMarsRealEstateProperties() on init so we can display status immediately.
                 */
                init {
                    getTenderRealEstateProperties()
                }

                private fun getTenderRealEstateProperties() {

                    coroutineScope.launch {
                        // Get the Deferred object for our Retrofit request
                        var getPropertiesDeferred = TenderApi.retrofitService.getProperties()
                        try {
                            // this will run on a thread managed by Retrofit
                            val listResult = getPropertiesDeferred.await()

                            _sortByPrice.value=listResult.toList().sortedBy {it.price}
                            _sortById.value=listResult.toList().sortedBy {it.id}

                            _response.value = listResult
                            println("hii"+_response.value)
                            Log.d("class","_response.value")

                        } catch (e: Exception) {

                            _response.value = ArrayList()
                            Log.d("class","_response.value")
                        }
                    }
                }

                fun displayPropertyDetails(marsProperty: TenderProperty) {
                    _navigateToSelectedProperty.value = marsProperty
                }

               fun displayPropertyDetailsComplete() {
                    _navigateToSelectedProperty.value = null
                }

ListTenderAdapter这是Adapter类

            class ListTenderAdapter( private val onClickListener: OnClickListener ) :
                ListAdapter<TenderProperty,
                        ListTenderAdapter.TenderPropertyViewHolder>(DiffCallback) {


                class TenderPropertyViewHolder(private var binding:TenderListViewBinding):
                    RecyclerView.ViewHolder(binding.root) {
                    fun bind(tenderProperty: TenderProperty) {
                        binding.property = tenderProperty
                        // This is important, because it forces the data binding to execute immediately,
                        // which allows the RecyclerView to make the correct view size measurements
                        binding.executePendingBindings()
                    }
                }

                /**
                 * Allows the RecyclerView to determine which items have changed when the [List] of [MarsProperty]
                 * has been updated.
                 */
                companion object DiffCallback : DiffUtil.ItemCallback<TenderProperty>() {
                    override fun areItemsTheSame(oldItem: TenderProperty, newItem: TenderProperty): Boolean {
                        return oldItem === newItem
                    }

                    override fun areContentsTheSame(oldItem: TenderProperty, newItem: TenderProperty): Boolean {
                        return oldItem.id == newItem.id
                    }
                }

                /**
                 * Create new [RecyclerView] item views (invoked by the layout manager)
                 */
                override fun onCreateViewHolder(parent: ViewGroup,
                                                viewType: Int): TenderPropertyViewHolder {
                    return TenderPropertyViewHolder(TenderListViewBinding.inflate(LayoutInflater.from(parent.context)))
                }

                /**
                 * Replaces the contents of a view (invoked by the layout manager)
                 */
                override fun onBindViewHolder(holder: TenderPropertyViewHolder, position: Int) {
                    val tenderProperty = getItem(position)
                    holder.itemView.setOnClickListener {
                        onClickListener.onClick(tenderProperty)
                    }
                    holder.bind(tenderProperty)
                }

                /**
                 * Custom listener that handles clicks on [RecyclerView] items.  Passes the [MarsProperty]
                 * associated with the current item to the [onClick] function.
                 * @param clickListener lambda that will be called with the current [MarsProperty]
                 */
                class OnClickListener(val clickListener: (tenderProperty: TenderProperty) -> Unit) {
                    fun onClick(tenderProperty: TenderProperty) = clickListener(tenderProperty)
                }
            }

这是Fragment类

            class TenderListFragment : Fragment() {

                private val viewModel: NotificationViewModel by lazy {
                    ViewModelProviders.of(this).get(NotificationViewModel::class.java)
                }

                override fun onCreateView(
                    inflater: LayoutInflater,
                    container: ViewGroup?,
                    savedInstanceState: Bundle?
                ): View? {

                    val binding = FragmentAvailabletenderBinding.inflate(inflater)

                    binding.lifecycleOwner = this

                    binding.viewModel = viewModel

                    binding.tenderList.addItemDecoration(MarginItemDecoration(5))

                    val adapter=binding.tenderList.adapter as ListTenderAdapter
                    adapter.submitList(viewModel.response.value)
                    binding.tenderList.adapter = ListTenderAdapter(ListTenderAdapter.OnClickListener {
                        viewModel.displayPropertyDetails(it)
                    })
                    adapter.notifyDataSetChanged()
                    // binding.tenderList.layoutManager = LinearLayoutManager(activity)
                    setHasOptionsMenu(true)
                    return binding.root

                }

查看更多

查看更多

提问者
anish sethiya
被浏览
100
Rajnish suryavanshi 2020-01-31 16:20

onCreateView内的TenderListFragment类中,删除以下所有行:

binding.tenderList.addItemDecoration(MarginItemDecoration(5))

                    val adapter=binding.tenderList.adapter as ListTenderAdapter
                    adapter.submitList(viewModel.response.value)
                    binding.tenderList.adapter = ListTenderAdapter(ListTenderAdapter.OnClickListener {
                        viewModel.displayPropertyDetails(it)
                    })
                    adapter.notifyDataSetChanged()

将适配器声明为TenderListFragment中的全局变量

private lateinit var adapter : ListTenderAdapter

然后从 onCreateView()

private fun setupRecyclerView(){
     binding.tenderList.addItemDecoration(MarginItemDecoration(5))
     adapter = ListTenderAdapter(ListTenderAdapter.OnClickListener {
                    viewModel.displayPropertyDetails(it)
                })
     binding.tenderList.setAdapter(adapter)

}

再添加一个方法initViewModel(),然后从onCreateView之后调用此方法setupRecyclerView()

private fun initViewModel(){
    viewModel.response.observe(this, Observer {
       adapter.submitList(it)
    })
}