Я создал макет RecyclerView, но внешний вид не соответствует ожидаемому
Я проверил layout_height на list_item.xml
, но уже wrap_content
.Но почему это выглядит не подходит.И TextView с идентификатором tv_title_list
не отображается при выполнении
Отображение снимков экрана: https://drive.google.com/open?id=1hywe6DrXth6iwO9jIgScAxhTq1Cq3mAL Для полного кода: https://github.com/riluq/AnimeApp
list_item.xml
<?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>
<variable name="topAiring" type="com.riluq.animeapp.network.TopAiring"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.card.MaterialCardView
android:id="@+id/mcv_list"
android:layout_width="65dp"
android:layout_height="90dp"
app:cardCornerRadius="5dp"
app:cardElevation="2dp"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginBottom="16dp" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="8dp"
android:layout_marginTop="16dp">
<ImageView
android:id="@+id/img_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
tools:srcCompat="@android:color/holo_blue_light"
app:imageUrl="@{topAiring.imageUrlTopAiring}"/>
</com.google.android.material.card.MaterialCardView>
<TextView
android:id="@+id/tv_title_list"
tools:text="JoJo no Kimyou na Bouken Part 5: Ougon no Kaze"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2"
app:layout_constraintStart_toEndOf="@+id/mcv_list"
android:layout_marginStart="8dp" app:layout_constraintTop_toTopOf="@+id/mcv_list"
app:layout_constraintBottom_toBottomOf="@+id/mcv_list"
android:layout_marginEnd="8dp" app:layout_constraintEnd_toStartOf="@+id/tv_rank_list"
app:textTopAiringTitle="@{topAiring.titleTopAiring}"/>
<TextView
android:id="@+id/tv_rank_list"
tools:text="#1"
android:textColor="?attr/colorSecondary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline5"
app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp"
app:layout_constraintTop_toTopOf="@+id/mcv_list"
app:textTopAiringRank="@{topAiring.rankTopAiring}"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
frag_top_airing.xml
<?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>
<variable
name="viewModel"
type="com.riluq.animeapp.topairing.TopAiringViewModel"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".topairing.TopAiringFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv_top_airing"
android:layout_width="0dp"
android:layout_height="0dp"
android:clipToPadding="false"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:listData="@{viewModel.topAiring}"
tools:itemCount="16"
tools:listitem="@layout/list_item"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
TopAiringAdapter.kt
package com.riluq.animeapp.topairing
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import com.riluq.animeapp.databinding.ListItemBinding
import com.riluq.animeapp.network.TopAiring
class TopAiringAdapter(): ListAdapter<TopAiring, TopAiringAdapter.TopAiringViewHolder>(DiffCallback) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TopAiringViewHolder {
return TopAiringViewHolder(ListItemBinding.inflate(LayoutInflater.from(parent.context)))
}
override fun onBindViewHolder(holder: TopAiringViewHolder, position: Int) {
val topAiring = getItem(position)
holder.bind(topAiring)
}
class TopAiringViewHolder(private val binding: ListItemBinding) :
RecyclerView.ViewHolder(binding.root){
fun bind(topAiring: TopAiring) {
binding.topAiring = topAiring
binding.executePendingBindings()
}
}
companion object DiffCallback: DiffUtil.ItemCallback<TopAiring>() {
override fun areItemsTheSame(oldItem: TopAiring, newItem: TopAiring): Boolean {
return oldItem == newItem
}
override fun areContentsTheSame(oldItem: TopAiring, newItem: TopAiring): Boolean {
return oldItem.idTopAiring == newItem.idTopAiring
}
}
}
TopAiringFragment.kt
package com.riluq.animeapp.topairing
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProviders
import com.riluq.animeapp.databinding.FragmentTopAiringBinding
class TopAiringFragment : Fragment() {
private val viewModel: TopAiringViewModel by lazy {
ViewModelProviders.of(this).get(TopAiringViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val binding = FragmentTopAiringBinding.inflate(inflater)
binding.lifecycleOwner = this
// Inflate the layout for this fragment
binding.viewModel = viewModel
binding.rvTopAiring.adapter = TopAiringAdapter()
return binding.root
}
}
TopAiringViewModel.kt
package com.riluq.animeapp.topairing
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.riluq.animeapp.network.JikanMoeApi
import com.riluq.animeapp.network.TopAiring
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
class TopAiringViewModel: ViewModel() {
private var viewModelJob = Job()
private val coroutineScope = CoroutineScope(viewModelJob + Dispatchers.Main)
private val _topAiring = MutableLiveData<List<TopAiring>>()
val topAiring: LiveData<List<TopAiring>>
get() = _topAiring
init {
getTopAiring()
}
private fun getTopAiring() {
coroutineScope.launch {
val getTopAiringDeffered = JikanMoeApi.retrofitService.getTopAiringAsync()
try {
val listResult = getTopAiringDeffered.await().top
if (listResult.size > 0) {
_topAiring.value = listResult
}
Log.i("TopAiringViewModel", "topAiring = ${topAiring.value?.get(0)?.titleTopAiring}")
} catch (t: Throwable) {
_topAiring.value = ArrayList()
Log.i("TopAiringViewModel", t.message.toString())
}
}
}
override fun onCleared() {
super.onCleared()
viewModelJob.cancel()
}
}
ЧтоЯ ожидал, это выглядит как эта картина: https://drive.google.com/open?id=1d1sWL0CX7gPJFvvhY13POWDAf15Hk2Pw