From 21caa8eb1b01ecb7fcde03a2513a6084d6c80acf Mon Sep 17 00:00:00 2001 From: Jannik Date: Sat, 3 Dec 2022 00:05:57 +0100 Subject: [PATCH 1/3] update MediaItem to suport dynamic size * this is needed for dynamic span count to correctly work * this also fixes issues with poster image cropping when the MediaItem size was < 195dp --- .../main/fragments/LibraryFragment.kt | 32 ++++++++----------- .../util/adapter/MediaItemListAdapter.kt | 2 +- app/src/main/res/layout/fragment_home.xml | 8 ++--- app/src/main/res/layout/item_media.xml | 18 +++++------ 4 files changed, 28 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/LibraryFragment.kt b/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/LibraryFragment.kt index 58f5ec0..9b14443 100644 --- a/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/LibraryFragment.kt +++ b/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/LibraryFragment.kt @@ -13,13 +13,15 @@ import org.mosad.teapod.databinding.FragmentLibraryBinding import org.mosad.teapod.parser.crunchyroll.Crunchyroll import org.mosad.teapod.util.ItemMedia import org.mosad.teapod.util.adapter.MediaItemAdapter +import org.mosad.teapod.util.adapter.MediaItemListAdapter import org.mosad.teapod.util.decoration.MediaItemDecoration import org.mosad.teapod.util.showFragment +import org.mosad.teapod.util.toItemMediaList class LibraryFragment : Fragment() { private lateinit var binding: FragmentLibraryBinding - private lateinit var adapter: MediaItemAdapter + private lateinit var adapter: MediaItemListAdapter private val itemList = arrayListOf() private val pageSize = 30 @@ -33,26 +35,23 @@ class LibraryFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + binding.recyclerMediaLibrary.addItemDecoration(MediaItemDecoration(9)) + // TODO replace with pagination3 + // https://medium.com/swlh/paging3-recyclerview-pagination-made-easy-333c7dfa8797 + binding.recyclerMediaLibrary.addOnScrollListener(PaginationScrollListener()) + // init async lifecycleScope.launch { // create and set the adapter, needs context context?.let { - val initialResults = Crunchyroll.browse(n = pageSize) - itemList.addAll(initialResults.items.map { item -> - ItemMedia(item.id, item.title, item.images.poster_wide[0][0].source) - }) + itemList.addAll(Crunchyroll.browse(n = pageSize).toItemMediaList()) nextItemIndex += pageSize - adapter = MediaItemAdapter(itemList) - adapter.onItemClick = { mediaIdStr, _ -> - activity?.showFragment(MediaFragment(mediaIdStr)) - } - + adapter = MediaItemListAdapter(MediaItemListAdapter.OnClickListener { + activity?.showFragment(MediaFragment(it.id)) + }) binding.recyclerMediaLibrary.adapter = adapter - binding.recyclerMediaLibrary.addItemDecoration(MediaItemDecoration(9)) - // TODO replace with pagination3 - // https://medium.com/swlh/paging3-recyclerview-pagination-made-easy-333c7dfa8797 - binding.recyclerMediaLibrary.addOnScrollListener(PaginationScrollListener()) + adapter.submitList(itemList) } } @@ -72,10 +71,7 @@ class LibraryFragment : Fragment() { isLoading = true lifecycleScope.launch { val firstNewItemIndex = itemList.lastIndex + 1 - val results = Crunchyroll.browse(start = nextItemIndex, n = pageSize) - itemList.addAll(results.items.map { item -> - ItemMedia(item.id, item.title, item.images.poster_wide[0][0].source) - }) + itemList.addAll(Crunchyroll.browse(start = nextItemIndex, n = pageSize).toItemMediaList()) nextItemIndex += pageSize adapter.notifyItemRangeInserted(firstNewItemIndex, pageSize) diff --git a/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemListAdapter.kt b/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemListAdapter.kt index d7763c1..af61a08 100644 --- a/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemListAdapter.kt +++ b/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemListAdapter.kt @@ -36,7 +36,7 @@ class MediaItemListAdapter(private val onClickListener: OnClickListener) : ListA fun bind(item: ItemMedia) { binding.textTitle.text = item.title - Glide.with(binding.imagePoster) + Glide.with(binding.root.context) .load(item.posterUrl) .into(binding.imagePoster) diff --git a/app/src/main/res/layout/fragment_home.xml b/app/src/main/res/layout/fragment_home.xml index 327150c..7cf23e8 100644 --- a/app/src/main/res/layout/fragment_home.xml +++ b/app/src/main/res/layout/fragment_home.xml @@ -120,7 +120,7 @@ @@ -139,7 +139,7 @@ @@ -207,7 +207,7 @@ diff --git a/app/src/main/res/layout/item_media.xml b/app/src/main/res/layout/item_media.xml index e514d56..5d13244 100644 --- a/app/src/main/res/layout/item_media.xml +++ b/app/src/main/res/layout/item_media.xml @@ -10,27 +10,27 @@ + android:layout_height="wrap_content"> + app:layout_constrainedWidth="true" + app:layout_constraintWidth_max="195dp"> + android:scaleType="fitCenter" + tools:srcCompat="@drawable/placeholder_image"/> Date: Sun, 4 Dec 2022 13:51:29 +0100 Subject: [PATCH 2/3] make MediaItem width fully dynamic, based on the parents width (50% of parent width) and update SearchFragment to use MediaItemListAdapter and remove now unused MediaItemAdapter --- .../activity/main/fragments/HomeFragment.kt | 47 +++--- .../main/fragments/LibraryFragment.kt | 1 - .../activity/main/fragments/SearchFragment.kt | 36 ++--- .../util/adapter/MediaEpisodeListAdapter.kt | 17 ++- .../teapod/util/adapter/MediaItemAdapter.kt | 44 ------ .../util/adapter/MediaItemListAdapter.kt | 17 ++- app/src/main/res/layout/item_media.xml | 135 ++++++++++-------- .../main/res/layout/item_media_shimmer.xml | 90 +++++++----- 8 files changed, 190 insertions(+), 197 deletions(-) delete mode 100644 app/src/main/java/org/mosad/teapod/util/adapter/MediaItemAdapter.kt diff --git a/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/HomeFragment.kt b/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/HomeFragment.kt index 2ceb9ab..52c6ced 100644 --- a/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/HomeFragment.kt +++ b/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/HomeFragment.kt @@ -27,6 +27,7 @@ import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.LinearLayout import androidx.activity.result.contract.ActivityResultContracts import androidx.core.view.children import androidx.core.view.isVisible @@ -44,7 +45,6 @@ import org.mosad.teapod.ui.activity.main.viewmodel.HomeViewModel import org.mosad.teapod.util.* import org.mosad.teapod.util.adapter.MediaEpisodeListAdapter import org.mosad.teapod.util.adapter.MediaItemListAdapter -import org.mosad.teapod.util.decoration.MediaItemDecoration class HomeFragment : Fragment() { @@ -64,40 +64,39 @@ class HomeFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - binding.recyclerUpNext.addItemDecoration(MediaItemDecoration(9)) - binding.recyclerWatchlist.addItemDecoration(MediaItemDecoration(9)) - binding.recyclerRecommendations.addItemDecoration(MediaItemDecoration(9)) - binding.recyclerNewTitles.addItemDecoration(MediaItemDecoration(9)) - binding.recyclerTopTen.addItemDecoration(MediaItemDecoration(9)) - binding.recyclerUpNext.adapter = MediaEpisodeListAdapter( MediaEpisodeListAdapter.OnClickListener { playerResult.launch(playerIntent(it.panel.episodeMetadata.seasonId, it.panel.id)) - } + }, + 21 ) binding.recyclerWatchlist.adapter = MediaItemListAdapter( MediaItemListAdapter.OnClickListener { activity?.showFragment(MediaFragment(it.id)) - } + }, + 21 ) binding.recyclerRecommendations.adapter = MediaItemListAdapter( MediaItemListAdapter.OnClickListener { activity?.showFragment(MediaFragment(it.id)) - } + }, + 21 ) binding.recyclerNewTitles.adapter = MediaItemListAdapter( MediaItemListAdapter.OnClickListener { activity?.showFragment(MediaFragment(it.id)) - } + }, + 21 ) binding.recyclerTopTen.adapter = MediaItemListAdapter( MediaItemListAdapter.OnClickListener { activity?.showFragment(MediaFragment(it.id)) - } + }, + 21 ) binding.textHighlightMyList.setOnClickListener { @@ -108,6 +107,13 @@ class HomeFragment : Fragment() { // TODO since this might take a few seconds show a loading animation for the watchlist button } + // set the shimmer items size as it's depending on the screen size + setShimmerLayoutItemSize(binding.shimmerLayoutUpNext) + setShimmerLayoutItemSize(binding.shimmerLayoutWatchlist) + setShimmerLayoutItemSize(binding.shimmerLayoutRecommendations) + setShimmerLayoutItemSize(binding.shimmerLayoutNewTitles) + setShimmerLayoutItemSize(binding.shimmerLayoutTopTen) + viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { model.onUiState(viewLifecycleOwner.lifecycleScope) { uiState -> @@ -169,10 +175,19 @@ class HomeFragment : Fragment() { private fun bindUiStateLoading() { // hide highlights layout binding.linearHighlight.isVisible = false - println(binding.root.childCount) - binding.root.children.filter { it is ShimmerFrameLayout }.forEach { - it as ShimmerFrameLayout - it.startShimmer() + + binding.shimmerLayoutUpNext.startShimmer() + binding.shimmerLayoutWatchlist.startShimmer() + binding.shimmerLayoutRecommendations.startShimmer() + binding.shimmerLayoutNewTitles.startShimmer() + binding.shimmerLayoutTopTen.startShimmer() + } + + private fun setShimmerLayoutItemSize(shimmerLayout: ShimmerFrameLayout) { + (shimmerLayout.children.first() as? LinearLayout)?.children?.forEach { child -> + child.layoutParams.apply { + width = (binding.root.measuredWidth / 2) - 21 + } } } diff --git a/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/LibraryFragment.kt b/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/LibraryFragment.kt index 9b14443..48a5343 100644 --- a/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/LibraryFragment.kt +++ b/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/LibraryFragment.kt @@ -12,7 +12,6 @@ import kotlinx.coroutines.launch import org.mosad.teapod.databinding.FragmentLibraryBinding import org.mosad.teapod.parser.crunchyroll.Crunchyroll import org.mosad.teapod.util.ItemMedia -import org.mosad.teapod.util.adapter.MediaItemAdapter import org.mosad.teapod.util.adapter.MediaItemListAdapter import org.mosad.teapod.util.decoration.MediaItemDecoration import org.mosad.teapod.util.showFragment diff --git a/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/SearchFragment.kt b/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/SearchFragment.kt index ca924d4..63ed666 100644 --- a/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/SearchFragment.kt +++ b/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/SearchFragment.kt @@ -9,18 +9,18 @@ import androidx.fragment.app.Fragment import androidx.lifecycle.lifecycleScope import kotlinx.coroutines.Job import kotlinx.coroutines.async -import kotlinx.coroutines.launch import org.mosad.teapod.databinding.FragmentSearchBinding import org.mosad.teapod.parser.crunchyroll.Crunchyroll import org.mosad.teapod.util.ItemMedia -import org.mosad.teapod.util.adapter.MediaItemAdapter +import org.mosad.teapod.util.adapter.MediaItemListAdapter import org.mosad.teapod.util.decoration.MediaItemDecoration import org.mosad.teapod.util.showFragment +import org.mosad.teapod.util.toItemMediaList class SearchFragment : Fragment() { private lateinit var binding: FragmentSearchBinding - private lateinit var adapter: MediaItemAdapter + private lateinit var adapter: MediaItemListAdapter private val itemList = arrayListOf() private var searchJob: Job? = null @@ -34,19 +34,13 @@ class SearchFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - lifecycleScope.launch { - // create and set the adapter, needs context - context?.let { - adapter = MediaItemAdapter(itemList) - adapter.onItemClick = { mediaIdStr, _ -> - binding.searchText.clearFocus() - activity?.showFragment(MediaFragment(mediaIdStr)) - } + binding.recyclerMediaSearch.addItemDecoration(MediaItemDecoration(9)) - binding.recyclerMediaSearch.adapter = adapter - binding.recyclerMediaSearch.addItemDecoration(MediaItemDecoration(9)) - } - } + adapter = MediaItemListAdapter(MediaItemListAdapter.OnClickListener { + binding.searchText.clearFocus() + activity?.showFragment(MediaFragment(it.id)) + }) + binding.recyclerMediaSearch.adapter = adapter initActions() } @@ -65,6 +59,9 @@ class SearchFragment : Fragment() { }) } + /** + * Search for a query string at Crunchyroll and submit the results to the adapter. + */ private fun search(query: String) { // if the query hasn't changed since the last successful search, return if (query == oldSearchQuery) return @@ -79,9 +76,9 @@ class SearchFragment : Fragment() { itemList.clear() // TODO needs clean up // TODO add top results first heading - itemList.addAll(results.items[0].items.map { item -> - ItemMedia(item.id, item.title, item.images.poster_wide[0][0].source) - }) + adapter.submitList( + results.items.firstOrNull()?.items?.toItemMediaList() ?: listOf() + ) // TODO currently only tv shows are supported, hence only the first items array // should be always present @@ -107,9 +104,6 @@ class SearchFragment : Fragment() { // }) // } - adapter.notifyDataSetChanged() - //adapter.notifyItemRangeInserted(0, itemList.size) - // after successfully searching the query term, add it as old query, to make sure we // don't search again if the query hasn't changed oldSearchQuery = query diff --git a/app/src/main/java/org/mosad/teapod/util/adapter/MediaEpisodeListAdapter.kt b/app/src/main/java/org/mosad/teapod/util/adapter/MediaEpisodeListAdapter.kt index c8a6570..1cdebdb 100644 --- a/app/src/main/java/org/mosad/teapod/util/adapter/MediaEpisodeListAdapter.kt +++ b/app/src/main/java/org/mosad/teapod/util/adapter/MediaEpisodeListAdapter.kt @@ -11,16 +11,19 @@ import org.mosad.teapod.R import org.mosad.teapod.databinding.ItemMediaBinding import org.mosad.teapod.parser.crunchyroll.ContinueWatchingItem -class MediaEpisodeListAdapter(private val onClickListener: OnClickListener) : ListAdapter(DiffCallback) { +class MediaEpisodeListAdapter(private val onClickListener: OnClickListener, private val itemOffset: Int = 0) : ListAdapter(DiffCallback) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MediaViewHolder { - return MediaViewHolder( - ItemMediaBinding.inflate( - LayoutInflater.from(parent.context), - parent, - false - ) + val binding = ItemMediaBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false ) + binding.root.layoutParams.apply { + width = (parent.measuredWidth / 2) - itemOffset + } + + return MediaViewHolder(binding) } override fun onBindViewHolder(holder: MediaViewHolder, position: Int) { diff --git a/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemAdapter.kt b/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemAdapter.kt deleted file mode 100644 index 94a4a65..0000000 --- a/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemAdapter.kt +++ /dev/null @@ -1,44 +0,0 @@ -package org.mosad.teapod.util.adapter - -import android.view.LayoutInflater -import android.view.ViewGroup -import androidx.core.view.isVisible -import androidx.recyclerview.widget.RecyclerView -import com.bumptech.glide.Glide -import org.mosad.teapod.databinding.ItemMediaBinding -import org.mosad.teapod.util.ItemMedia - -@Deprecated("Use MediaItemListAdapter instead") -class MediaItemAdapter(private val items: List) : RecyclerView.Adapter() { - - var onItemClick: ((id: String, position: Int) -> Unit)? = null - - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MediaItemAdapter.MediaViewHolder { - return MediaViewHolder(ItemMediaBinding.inflate(LayoutInflater.from(parent.context), parent, false)) - } - - override fun onBindViewHolder(holder: MediaItemAdapter.MediaViewHolder, position: Int) { - holder.binding.root.apply { - holder.binding.textTitle.text = items[position].title - Glide.with(context).load(items[position].posterUrl).into(holder.binding.imagePoster) - } - } - - override fun getItemCount(): Int { - return items.size - } - - inner class MediaViewHolder(val binding: ItemMediaBinding) : - RecyclerView.ViewHolder(binding.root) { - init { - binding.imageEpisodePlay.isVisible = false // hide the play button for media items - binding.root.setOnClickListener { - onItemClick?.invoke( - items[bindingAdapterPosition].id, - bindingAdapterPosition - ) - } - } - } - -} \ No newline at end of file diff --git a/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemListAdapter.kt b/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemListAdapter.kt index af61a08..ec3a33c 100644 --- a/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemListAdapter.kt +++ b/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemListAdapter.kt @@ -10,16 +10,19 @@ import com.bumptech.glide.Glide import org.mosad.teapod.databinding.ItemMediaBinding import org.mosad.teapod.util.ItemMedia -class MediaItemListAdapter(private val onClickListener: OnClickListener) : ListAdapter(DiffCallback) { +class MediaItemListAdapter(private val onClickListener: OnClickListener, private val itemOffset: Int = 0) : ListAdapter(DiffCallback) { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MediaViewHolder { - return MediaViewHolder( - ItemMediaBinding.inflate( - LayoutInflater.from(parent.context), - parent, - false - ) + val binding = ItemMediaBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false ) + binding.root.layoutParams.apply { + width = (parent.measuredWidth / 2) - itemOffset + } + + return MediaViewHolder(binding) } override fun onBindViewHolder(holder: MediaViewHolder, position: Int) { diff --git a/app/src/main/res/layout/item_media.xml b/app/src/main/res/layout/item_media.xml index 5d13244..7b79e54 100644 --- a/app/src/main/res/layout/item_media.xml +++ b/app/src/main/res/layout/item_media.xml @@ -1,71 +1,82 @@ - + android:layout_width="match_parent" + android:layout_height="wrap_content"> - + - + - + + + + + + + + + + android:gravity="center" + android:lines="2" + android:maxLines="2" + android:padding="3dp" + android:text="@string/text_title_ex" + android:textAlignment="center" + android:textSize="15sp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@+id/frame_image_progress" /> + - + - - - - - - - \ No newline at end of file + diff --git a/app/src/main/res/layout/item_media_shimmer.xml b/app/src/main/res/layout/item_media_shimmer.xml index 0ccdec2..1193525 100644 --- a/app/src/main/res/layout/item_media_shimmer.xml +++ b/app/src/main/res/layout/item_media_shimmer.xml @@ -1,50 +1,62 @@ - + android:layout_width="match_parent" + android:layout_height="wrap_content"> - + android:layout_height="wrap_content" + android:layout_marginStart="4dp" + android:layout_marginEnd="3dp" + android:backgroundTint="?themeSecondary" + app:cardCornerRadius="7dp" + app:cardElevation="4dp" + app:layout_constrainedWidth="true" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintWidth_default="percent" + app:layout_constraintWidth_percent="0.96"> - + + + + + + + + - + - - - - \ No newline at end of file + From ed8f3fdcda57786030abb0ded2165833a5d67059 Mon Sep 17 00:00:00 2001 From: Jannik Date: Sun, 4 Dec 2022 14:48:25 +0100 Subject: [PATCH 3/3] set spanCount according to screen width --- .../ui/activity/main/fragments/HomeFragment.kt | 14 ++++++++------ .../teapod/util/adapter/MediaEpisodeListAdapter.kt | 2 +- .../teapod/util/adapter/MediaItemListAdapter.kt | 3 ++- app/src/main/res/layout/fragment_library.xml | 2 +- app/src/main/res/layout/fragment_media_similar.xml | 2 +- app/src/main/res/layout/fragment_search.xml | 2 +- app/src/main/res/values-sw600dp/dimens.xml | 4 ++++ app/src/main/res/values-sw720dp/dimens.xml | 4 ++++ app/src/main/res/values-sw840dp/dimens.xml | 4 ++++ app/src/main/res/values/dimens.xml | 1 + 10 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 app/src/main/res/values-sw600dp/dimens.xml create mode 100644 app/src/main/res/values-sw720dp/dimens.xml create mode 100644 app/src/main/res/values-sw840dp/dimens.xml diff --git a/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/HomeFragment.kt b/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/HomeFragment.kt index 52c6ced..f38fc00 100644 --- a/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/HomeFragment.kt +++ b/app/src/main/java/org/mosad/teapod/ui/activity/main/fragments/HomeFragment.kt @@ -52,6 +52,8 @@ class HomeFragment : Fragment() { private val model: HomeViewModel by viewModels() private lateinit var binding: FragmentHomeBinding + private val itemOffset = 21 + private val playerResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { model.updateUpNextItems() } @@ -68,35 +70,35 @@ class HomeFragment : Fragment() { MediaEpisodeListAdapter.OnClickListener { playerResult.launch(playerIntent(it.panel.episodeMetadata.seasonId, it.panel.id)) }, - 21 + itemOffset ) binding.recyclerWatchlist.adapter = MediaItemListAdapter( MediaItemListAdapter.OnClickListener { activity?.showFragment(MediaFragment(it.id)) }, - 21 + itemOffset ) binding.recyclerRecommendations.adapter = MediaItemListAdapter( MediaItemListAdapter.OnClickListener { activity?.showFragment(MediaFragment(it.id)) }, - 21 + itemOffset ) binding.recyclerNewTitles.adapter = MediaItemListAdapter( MediaItemListAdapter.OnClickListener { activity?.showFragment(MediaFragment(it.id)) }, - 21 + itemOffset ) binding.recyclerTopTen.adapter = MediaItemListAdapter( MediaItemListAdapter.OnClickListener { activity?.showFragment(MediaFragment(it.id)) }, - 21 + itemOffset ) binding.textHighlightMyList.setOnClickListener { @@ -186,7 +188,7 @@ class HomeFragment : Fragment() { private fun setShimmerLayoutItemSize(shimmerLayout: ShimmerFrameLayout) { (shimmerLayout.children.first() as? LinearLayout)?.children?.forEach { child -> child.layoutParams.apply { - width = (binding.root.measuredWidth / 2) - 21 + width = (binding.root.measuredWidth / requireContext().resources.getInteger(R.integer.item_media_columns)) - itemOffset } } } diff --git a/app/src/main/java/org/mosad/teapod/util/adapter/MediaEpisodeListAdapter.kt b/app/src/main/java/org/mosad/teapod/util/adapter/MediaEpisodeListAdapter.kt index 1cdebdb..4806167 100644 --- a/app/src/main/java/org/mosad/teapod/util/adapter/MediaEpisodeListAdapter.kt +++ b/app/src/main/java/org/mosad/teapod/util/adapter/MediaEpisodeListAdapter.kt @@ -20,7 +20,7 @@ class MediaEpisodeListAdapter(private val onClickListener: OnClickListener, priv false ) binding.root.layoutParams.apply { - width = (parent.measuredWidth / 2) - itemOffset + width = (parent.measuredWidth / parent.context.resources.getInteger(R.integer.item_media_columns)) - itemOffset } return MediaViewHolder(binding) diff --git a/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemListAdapter.kt b/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemListAdapter.kt index ec3a33c..c788eb3 100644 --- a/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemListAdapter.kt +++ b/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemListAdapter.kt @@ -7,6 +7,7 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import com.bumptech.glide.Glide +import org.mosad.teapod.R import org.mosad.teapod.databinding.ItemMediaBinding import org.mosad.teapod.util.ItemMedia @@ -19,7 +20,7 @@ class MediaItemListAdapter(private val onClickListener: OnClickListener, private false ) binding.root.layoutParams.apply { - width = (parent.measuredWidth / 2) - itemOffset + width = (parent.measuredWidth / parent.context.resources.getInteger(R.integer.item_media_columns)) - itemOffset } return MediaViewHolder(binding) diff --git a/app/src/main/res/layout/fragment_library.xml b/app/src/main/res/layout/fragment_library.xml index 011314d..c5943ca 100644 --- a/app/src/main/res/layout/fragment_library.xml +++ b/app/src/main/res/layout/fragment_library.xml @@ -19,7 +19,7 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" - app:spanCount="2" + app:spanCount="@integer/item_media_columns" tools:listitem="@layout/item_media" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_media_similar.xml b/app/src/main/res/layout/fragment_media_similar.xml index 6837edb..a39f7bb 100644 --- a/app/src/main/res/layout/fragment_media_similar.xml +++ b/app/src/main/res/layout/fragment_media_similar.xml @@ -16,7 +16,7 @@ android:paddingEnd="3dp" android:paddingBottom="3dp" app:layoutManager="androidx.recyclerview.widget.GridLayoutManager" - app:spanCount="2" + app:spanCount="@integer/item_media_columns" tools:listitem="@layout/item_media" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_search.xml b/app/src/main/res/layout/fragment_search.xml index 6427560..7668031 100644 --- a/app/src/main/res/layout/fragment_search.xml +++ b/app/src/main/res/layout/fragment_search.xml @@ -35,7 +35,7 @@ app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/search_text" - app:spanCount="2" + app:spanCount="@integer/item_media_columns" tools:listitem="@layout/item_media"> diff --git a/app/src/main/res/values-sw600dp/dimens.xml b/app/src/main/res/values-sw600dp/dimens.xml new file mode 100644 index 0000000..7c028db --- /dev/null +++ b/app/src/main/res/values-sw600dp/dimens.xml @@ -0,0 +1,4 @@ + + + 3 + diff --git a/app/src/main/res/values-sw720dp/dimens.xml b/app/src/main/res/values-sw720dp/dimens.xml new file mode 100644 index 0000000..d13423c --- /dev/null +++ b/app/src/main/res/values-sw720dp/dimens.xml @@ -0,0 +1,4 @@ + + + 4 + diff --git a/app/src/main/res/values-sw840dp/dimens.xml b/app/src/main/res/values-sw840dp/dimens.xml new file mode 100644 index 0000000..e8bfe09 --- /dev/null +++ b/app/src/main/res/values-sw840dp/dimens.xml @@ -0,0 +1,4 @@ + + + 5 + diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index 45a85c7..026926f 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -2,4 +2,5 @@ 28dp 52dp + 2