【发布时间】:2021-05-24 13:22:54
【问题描述】:
我在 Kotlin 中制作了一个 Android 应用程序,我想从网络服务器获取一些信息并使用数据绑定放入一个回收器视图。我使用存储库模式,所以每次我发出获取请求时,我都会将信息保存在房间数据库中,并使用实时数据从中获取数据。出于某种原因,我的 ryclerview 没有显示任何内容,并且我没有收到任何错误。请求有效,我得到了数据,但 recyclerview 不起作用。 我的视图模型:
class HomeViewModel(application: Application) : ViewModel() {
private val availableTicketsRepo = AvailableTicketsRepository(getInstance(application))
val tickets = availableTicketsRepo.availableTickets
init {
refreshDataFromRepository()
}
private fun refreshDataFromRepository() {
viewModelScope.launch {
try {
availableTicketsRepo.refreshAvailableTickets()
} catch (ex: Exception) {
ex.message?.let { Resource.error(data = null, message = it) }
Log.i("Home", "*** Eccezione: ${ex} ***")
}
}
}
我的片段类(带有适配器和视图):
package com.example.ticketapp.ui.home
class HomeFragment : Fragment() {
private val viewModel: HomeViewModel by lazy {
val activity = requireNotNull(this.activity) {
"You can only access the viewModel after onActivityCreated()"
}
ViewModelProvider(this, HomeViewModel.Factory(activity.application))
.get(HomeViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
val binding = DataBindingUtil.inflate<FragmentHomeBinding>(
inflater,
R.layout.fragment_home,
container,
false
)
binding.lifecycleOwner = this
binding.viewModel = viewModel
binding.availableTicketsList.adapter = AvailableTicketsAdapter()
return binding.root
}
}
class AvailableTicketsAdapter() :
ListAdapter<AvailableTicket, AvailableTicketsAdapter.AvailableTicketViewHolder>(DiffCallback) {
class AvailableTicketViewHolder(private var binding: AvailableTicketItemsBinding) :
RecyclerView.ViewHolder(binding.root) {
fun bind(tickets: AvailableTicket) {
binding.ticket = tickets
binding.executePendingBindings()
}
}
companion object DiffCallback : DiffUtil.ItemCallback<AvailableTicket>() {
override fun areItemsTheSame(oldItem: AvailableTicket, newItem: AvailableTicket): Boolean {
return oldItem === newItem
}
override fun areContentsTheSame(
oldItem: AvailableTicket,
newItem: AvailableTicket
): Boolean {
return oldItem.Id == newItem.Id
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AvailableTicketViewHolder {
return AvailableTicketViewHolder(
AvailableTicketItemsBinding.inflate(
LayoutInflater.from(
parent.context
)
)
)
}
override fun onBindViewHolder(holder: AvailableTicketViewHolder, position: Int) {
val tickets = getItem(position)
holder.bind(tickets)
}
}
我的仓库:
class AvailableTicketsRepository(private val database: TicketDatabase) {
val availableTickets: LiveData<List<AvailableTicket>> =
Transformations.map(database.ticketDatabaseDao.getAvailableTickets()) {
it.asDomainModel()
}
suspend fun refreshAvailableTickets() {
withContext(Dispatchers.IO) {
val tickets = RetrofitBuilder.apiService.getAvailableTickets()
database.ticketDatabaseDao.insertAllAvailableTickets(tickets.map { it.asDataBaseModel() })
}
}
}
recylerview 中项目的 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>
<import type="android.view.View"/>
<variable
name="ticket"
type="com.example.ticketapp.model.AvailableTicket" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/titleText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLength="50"
android:text="@{ticket.title}"
android:singleLine="true"
android:textAlignment="center"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Titolo di max 50 caratteri per non uscire dalla riga" />
<TextView
android:id="@+id/customerText"
android:layout_width="160dp"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textSize="14sp"
android:text="@{ticket.customer}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titleText"
tools:text="ESEMPIO DI UN REFERENTE" />
<TextView
android:id="@+id/dateText"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:textAlignment="textEnd"
android:textSize="14sp"
android:text="@{ticket.date_Time}"
app:layout_constraintBaseline_toBaselineOf="@+id/customerText"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/titleText"
tools:text="20/01/2021 10:00:00" />
<ImageView
android:id="@+id/warningImg"
style="@style/iconImg"
android:layout_marginTop="20dp"
android:visibility="@{ticket.triangle ? View.VISIBLE : View.GONE}"
android:foregroundGravity="center"
app:layout_constraintEnd_toStartOf="@+id/dateText"
app:layout_constraintStart_toEndOf="@+id/customerText"
app:layout_constraintTop_toBottomOf="@+id/titleText"
app:srcCompat="@drawable/ic_warning" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
ryclerview的XML:
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/availableTicketsList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="10dp"
android:paddingEnd="10dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/toolbar"
tools:listitem="@layout/available_ticket_items" />
我的模型类:
@Parcelize
data class AvailableTicket (
val Id: Int,
val Title: String,
val Description: String,
val Date_Time: String,
val Customer: String,
val Field: String,
val Category: String,
val Color: String,
val Author: String,
val Triangle: Boolean,
val MyPriority: String
): Parcelable
【问题讨论】:
标签: android xml kotlin android-recyclerview