Add actors to MediaInfoFragment
This commit is contained in:
parent
c95ea3b586
commit
4a1c4639aa
5 changed files with 137 additions and 5 deletions
|
@ -5,15 +5,13 @@ import androidx.databinding.BindingAdapter
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||||
import dev.jdtech.jellyfin.adapters.CollectionListAdapter
|
import dev.jdtech.jellyfin.adapters.*
|
||||||
import dev.jdtech.jellyfin.adapters.ServerGridAdapter
|
|
||||||
import dev.jdtech.jellyfin.adapters.ViewItemListAdapter
|
|
||||||
import dev.jdtech.jellyfin.adapters.ViewListAdapter
|
|
||||||
import dev.jdtech.jellyfin.api.JellyfinApi
|
import dev.jdtech.jellyfin.api.JellyfinApi
|
||||||
import dev.jdtech.jellyfin.database.Server
|
import dev.jdtech.jellyfin.database.Server
|
||||||
import dev.jdtech.jellyfin.models.View
|
import dev.jdtech.jellyfin.models.View
|
||||||
import dev.jdtech.jellyfin.models.ViewItem
|
import dev.jdtech.jellyfin.models.ViewItem
|
||||||
import org.jellyfin.sdk.model.api.BaseItemDto
|
import org.jellyfin.sdk.model.api.BaseItemDto
|
||||||
|
import org.jellyfin.sdk.model.api.BaseItemPerson
|
||||||
|
|
||||||
@BindingAdapter("servers")
|
@BindingAdapter("servers")
|
||||||
fun bindServers(recyclerView: RecyclerView, data: List<Server>?) {
|
fun bindServers(recyclerView: RecyclerView, data: List<Server>?) {
|
||||||
|
@ -68,3 +66,23 @@ fun bindCollectionImage(imageView: ImageView, item: BaseItemDto) {
|
||||||
|
|
||||||
imageView.contentDescription = "${item.name} image"
|
imageView.contentDescription = "${item.name} image"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@BindingAdapter("people")
|
||||||
|
fun bindPeople(recyclerView: RecyclerView, data: List<BaseItemPerson>?) {
|
||||||
|
val adapter = recyclerView.adapter as PersonListAdapter
|
||||||
|
adapter.submitList(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
@BindingAdapter("personImage")
|
||||||
|
fun bindPersonImage(imageView: ImageView, person: BaseItemPerson) {
|
||||||
|
val jellyfinApi = JellyfinApi.getInstance(imageView.context.applicationContext, "")
|
||||||
|
|
||||||
|
Glide
|
||||||
|
.with(imageView.context)
|
||||||
|
.load(jellyfinApi.api.baseUrl.plus("/items/${person.id}/Images/Primary"))
|
||||||
|
.transition(DrawableTransitionOptions.withCrossFade())
|
||||||
|
.placeholder(R.color.neutral_800)
|
||||||
|
.into(imageView)
|
||||||
|
|
||||||
|
imageView.contentDescription = "${person.name} poster"
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package dev.jdtech.jellyfin.adapters
|
||||||
|
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
|
import androidx.recyclerview.widget.ListAdapter
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import dev.jdtech.jellyfin.databinding.PersonItemBinding
|
||||||
|
import org.jellyfin.sdk.model.api.BaseItemPerson
|
||||||
|
|
||||||
|
class PersonListAdapter :ListAdapter<BaseItemPerson, PersonListAdapter.PersonViewHolder>(DiffCallback) {
|
||||||
|
class PersonViewHolder(private var binding: PersonItemBinding) :
|
||||||
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
fun bind(person: BaseItemPerson) {
|
||||||
|
binding.person = person
|
||||||
|
binding.executePendingBindings()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object DiffCallback : DiffUtil.ItemCallback<BaseItemPerson>() {
|
||||||
|
override fun areItemsTheSame(oldItem: BaseItemPerson, newItem: BaseItemPerson): Boolean {
|
||||||
|
return oldItem.id == newItem.id
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun areContentsTheSame(oldItem: BaseItemPerson, newItem: BaseItemPerson): Boolean {
|
||||||
|
return oldItem == newItem
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): PersonViewHolder {
|
||||||
|
return PersonViewHolder(
|
||||||
|
PersonItemBinding.inflate(
|
||||||
|
LayoutInflater.from(parent.context),
|
||||||
|
parent,
|
||||||
|
false
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onBindViewHolder(holder: PersonViewHolder, position: Int) {
|
||||||
|
val item = getItem(position)
|
||||||
|
holder.bind(item)
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.navigation.fragment.navArgs
|
import androidx.navigation.fragment.navArgs
|
||||||
|
import dev.jdtech.jellyfin.adapters.PersonListAdapter
|
||||||
import dev.jdtech.jellyfin.viewmodels.MediaInfoViewModel
|
import dev.jdtech.jellyfin.viewmodels.MediaInfoViewModel
|
||||||
import dev.jdtech.jellyfin.databinding.FragmentMediaInfoBinding
|
import dev.jdtech.jellyfin.databinding.FragmentMediaInfoBinding
|
||||||
import dev.jdtech.jellyfin.viewmodels.MediaInfoViewModelFactory
|
import dev.jdtech.jellyfin.viewmodels.MediaInfoViewModelFactory
|
||||||
|
@ -43,6 +44,8 @@ class MediaInfoFragment : Fragment() {
|
||||||
binding.originalTitle.visibility = View.GONE
|
binding.originalTitle.visibility = View.GONE
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
binding.peopleRecyclerView.adapter = PersonListAdapter()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -16,13 +16,13 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingHorizontal="24dp"
|
|
||||||
tools:context=".fragments.MediaInfoFragment">
|
tools:context=".fragments.MediaInfoFragment">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/original_title"
|
android:id="@+id/original_title"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="24dp"
|
||||||
android:layout_marginBottom="12dp"
|
android:layout_marginBottom="12dp"
|
||||||
android:text="@{viewModel.item.originalTitle}"
|
android:text="@{viewModel.item.originalTitle}"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1" />
|
||||||
|
@ -30,6 +30,7 @@
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="24dp"
|
||||||
android:layout_marginBottom="16dp">
|
android:layout_marginBottom="16dp">
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,6 +74,7 @@
|
||||||
android:id="@+id/info"
|
android:id="@+id/info"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="24dp"
|
||||||
android:layout_marginBottom="12dp"
|
android:layout_marginBottom="12dp"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
@ -169,6 +171,7 @@
|
||||||
android:id="@+id/description"
|
android:id="@+id/description"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="24dp"
|
||||||
android:layout_marginBottom="24dp"
|
android:layout_marginBottom="24dp"
|
||||||
android:text="@{viewModel.item.overview}"
|
android:text="@{viewModel.item.overview}"
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||||
|
@ -182,9 +185,23 @@
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="24dp"
|
||||||
|
android:layout_marginBottom="12dp"
|
||||||
android:text="@string/cast_amp_crew"
|
android:text="@string/cast_amp_crew"
|
||||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"
|
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"
|
||||||
android:textSize="18sp" />
|
android:textSize="18sp" />
|
||||||
|
|
||||||
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
|
android:id="@+id/people_recycler_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingHorizontal="16dp"
|
||||||
|
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
|
||||||
|
app:people="@{viewModel.actors}"
|
||||||
|
tools:itemCount="3"
|
||||||
|
tools:listitem="@layout/person_item" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
50
app/src/main/res/layout/person_item.xml
Normal file
50
app/src/main/res/layout/person_item.xml
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
<?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="person"
|
||||||
|
type="org.jellyfin.sdk.model.api.BaseItemPerson" />
|
||||||
|
</data>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/item_layout"
|
||||||
|
android:layout_width="110dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginHorizontal="8dp"
|
||||||
|
android:foreground="?android:attr/selectableItemBackground"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<com.google.android.material.imageview.ShapeableImageView
|
||||||
|
android:id="@+id/person_image"
|
||||||
|
android:layout_width="110dp"
|
||||||
|
android:layout_height="160dp"
|
||||||
|
android:layout_marginBottom="8dp"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
app:personImage="@{person}"
|
||||||
|
app:shapeAppearanceOverlay="@style/roundedImageView" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/person_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:text="@{person.name}"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Body1"
|
||||||
|
tools:text="Rosa Salazar" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/person_role"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:ellipsize="end"
|
||||||
|
android:maxLines="2"
|
||||||
|
android:text="@{person.role}"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Caption"
|
||||||
|
tools:text="as Alita" />
|
||||||
|
</LinearLayout>
|
||||||
|
</layout>
|
Loading…
Reference in a new issue