From 5f80f1fabd39b607f7dbf2a69e558993804e898c Mon Sep 17 00:00:00 2001 From: Jannik Date: Wed, 14 Oct 2020 20:22:20 +0200 Subject: [PATCH] show loading screen while loading media fragment * use material components for shaped images and progress indicator --- app/build.gradle | 2 +- .../java/org/mosad/teapod/MainActivity.kt | 25 +++++++++++++++---- .../java/org/mosad/teapod/ui/MediaFragment.kt | 9 +++---- .../teapod/ui/library/LibraryFragment.kt | 9 +++---- .../mosad/teapod/ui/search/SearchFragment.kt | 14 +++++------ .../org/mosad/teapod/util/LoadingFragment.kt | 16 ++++++++++++ .../EpisodeItemAdapter.kt} | 5 ++-- .../MediaItemAdapter.kt} | 5 ++-- app/src/main/res/layout/activity_player.xml | 7 +++--- app/src/main/res/layout/fragment_loading.xml | 17 +++++++++++++ app/src/main/res/layout/fragment_media.xml | 5 ++-- app/src/main/res/layout/item_episode.xml | 5 ++-- app/src/main/res/values/styles.xml | 5 ++++ 13 files changed, 89 insertions(+), 35 deletions(-) create mode 100644 app/src/main/java/org/mosad/teapod/util/LoadingFragment.kt rename app/src/main/java/org/mosad/teapod/util/{EpisodesAdapter.kt => adapter/EpisodeItemAdapter.kt} (89%) rename app/src/main/java/org/mosad/teapod/util/{CustomAdapter.kt => adapter/MediaItemAdapter.kt} (91%) create mode 100644 app/src/main/res/layout/fragment_loading.xml diff --git a/app/build.gradle b/app/build.gradle index bb8d40a..e271d2a 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -46,7 +46,7 @@ dependencies { implementation 'androidx.security:security-crypto:1.1.0-alpha02' implementation 'androidx.legacy:legacy-support-v4:1.0.0' - implementation 'com.google.android.material:material:1.2.1' + implementation 'com.google.android.material:material:1.3.0-alpha03' implementation 'com.google.code.gson:gson:2.8.6' implementation 'com.google.android.exoplayer:exoplayer-core:2.12.0' implementation 'com.google.android.exoplayer:exoplayer-hls:2.12.0' diff --git a/app/src/main/java/org/mosad/teapod/MainActivity.kt b/app/src/main/java/org/mosad/teapod/MainActivity.kt index 0e1bff1..2190538 100644 --- a/app/src/main/java/org/mosad/teapod/MainActivity.kt +++ b/app/src/main/java/org/mosad/teapod/MainActivity.kt @@ -32,6 +32,7 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.commit import kotlinx.android.synthetic.main.activity_main.* import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.async import kotlinx.coroutines.launch import org.mosad.teapod.parser.AoDParser import org.mosad.teapod.preferences.EncryptedPreferences @@ -41,8 +42,7 @@ import org.mosad.teapod.ui.components.LoginDialog import org.mosad.teapod.ui.home.HomeFragment import org.mosad.teapod.ui.library.LibraryFragment import org.mosad.teapod.ui.search.SearchFragment -import org.mosad.teapod.util.Media -import org.mosad.teapod.util.TMDBApiController +import org.mosad.teapod.util.* class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemSelectedListener { @@ -70,6 +70,10 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS } override fun onNavigationItemSelected(item: MenuItem): Boolean { + if (supportFragmentManager.backStackEntryCount > 0) { + supportFragmentManager.popBackStack() + } + val ret = when (item.itemId) { R.id.navigation_home -> { activeFragment = HomeFragment() @@ -109,11 +113,18 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS } /** - * TODO show loading fragment + * show the media fragment for the selected media + * while loading show the loading fragment */ - fun showDetailFragment(media: Media) = GlobalScope.launch { - media.episodes = AoDParser().loadStreams(media) // load the streams for the selected media + fun showMediaFragment(media: Media) = GlobalScope.launch { + val loadingFragment = LoadingFragment() + supportFragmentManager.commit { + add(R.id.nav_host_fragment, loadingFragment, "MediaFragment") + show(loadingFragment) + } + // load the streams for the selected media + media.episodes = AoDParser().loadStreams(media) val tmdb = TMDBApiController().search(media.title, media.type) val mediaFragment = MediaFragment(media, tmdb) @@ -122,6 +133,10 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS addToBackStack(null) show(mediaFragment) } + + supportFragmentManager.commit { + remove(loadingFragment) + } } fun startPlayer(streamUrl: String) { diff --git a/app/src/main/java/org/mosad/teapod/ui/MediaFragment.kt b/app/src/main/java/org/mosad/teapod/ui/MediaFragment.kt index 9849ea3..46d0d3e 100644 --- a/app/src/main/java/org/mosad/teapod/ui/MediaFragment.kt +++ b/app/src/main/java/org/mosad/teapod/ui/MediaFragment.kt @@ -19,13 +19,13 @@ import org.mosad.teapod.MainActivity import org.mosad.teapod.R import org.mosad.teapod.parser.AoDParser import org.mosad.teapod.util.DataTypes.MediaType -import org.mosad.teapod.util.EpisodesAdapter +import org.mosad.teapod.util.adapter.EpisodeItemAdapter import org.mosad.teapod.util.Media import org.mosad.teapod.util.TMDBResponse class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) : Fragment() { - private lateinit var adapterRecEpisodes: EpisodesAdapter + private lateinit var adapterRecEpisodes: EpisodeItemAdapter private lateinit var viewManager: RecyclerView.LayoutManager @@ -55,17 +55,16 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) : .into(image_backdrop) Glide.with(requireContext()).load(posterUrl) - .apply(RequestOptions.bitmapTransform(RoundedCornersTransformation(posterCornerRadius, 0))) .into(image_poster) text_title.text = media.title text_year.text = media.info.year.toString() text_age.text = media.info.age.toString() - text_overview.text = media.info.shortDesc //if (tmdb.overview.isNotEmpty()) tmdb.overview else media.shortDesc + text_overview.text = media.info.shortDesc // specific gui if (media.type == MediaType.TVSHOW) { - adapterRecEpisodes = EpisodesAdapter(media.episodes, requireContext()) + adapterRecEpisodes = EpisodeItemAdapter(media.episodes, requireContext()) viewManager = LinearLayoutManager(context) recycler_episodes.layoutManager = viewManager recycler_episodes.adapter = adapterRecEpisodes diff --git a/app/src/main/java/org/mosad/teapod/ui/library/LibraryFragment.kt b/app/src/main/java/org/mosad/teapod/ui/library/LibraryFragment.kt index 139726f..bd2f0b8 100644 --- a/app/src/main/java/org/mosad/teapod/ui/library/LibraryFragment.kt +++ b/app/src/main/java/org/mosad/teapod/ui/library/LibraryFragment.kt @@ -6,17 +6,16 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import kotlinx.android.synthetic.main.fragment_library.* -import kotlinx.android.synthetic.main.item_media.view.* import kotlinx.coroutines.* import org.mosad.teapod.MainActivity import org.mosad.teapod.R import org.mosad.teapod.parser.AoDParser -import org.mosad.teapod.util.CustomAdapter +import org.mosad.teapod.util.adapter.MediaItemAdapter import org.mosad.teapod.util.Media class LibraryFragment : Fragment() { - private lateinit var adapter : CustomAdapter + private lateinit var adapter : MediaItemAdapter override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_library, container, false) @@ -33,7 +32,7 @@ class LibraryFragment : Fragment() { // create and set the adapter, needs context withContext(Dispatchers.Main) { context?.let { - adapter = CustomAdapter(it, AoDParser.mediaList) + adapter = MediaItemAdapter(it, AoDParser.mediaList) grid_media_library.adapter = adapter } } @@ -47,7 +46,7 @@ class LibraryFragment : Fragment() { val media = adapter.getItem(position) as Media println("selected item is: ${media.title}") - (activity as MainActivity).showDetailFragment(media) + (activity as MainActivity).showMediaFragment(media) } } diff --git a/app/src/main/java/org/mosad/teapod/ui/search/SearchFragment.kt b/app/src/main/java/org/mosad/teapod/ui/search/SearchFragment.kt index dd82f6b..5e32581 100644 --- a/app/src/main/java/org/mosad/teapod/ui/search/SearchFragment.kt +++ b/app/src/main/java/org/mosad/teapod/ui/search/SearchFragment.kt @@ -11,12 +11,12 @@ import kotlinx.coroutines.* import org.mosad.teapod.MainActivity import org.mosad.teapod.R import org.mosad.teapod.parser.AoDParser -import org.mosad.teapod.util.CustomAdapter +import org.mosad.teapod.util.adapter.MediaItemAdapter import org.mosad.teapod.util.Media class SearchFragment : Fragment() { - private var adapter : CustomAdapter? = null + private var adapter : MediaItemAdapter? = null override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { return inflater.inflate(R.layout.fragment_search, container, false) @@ -33,7 +33,7 @@ class SearchFragment : Fragment() { // create and set the adapter, needs context withContext(Dispatchers.Main) { context?.let { - adapter = CustomAdapter(it, AoDParser.mediaList) + adapter = MediaItemAdapter(it, AoDParser.mediaList) grid_media_search.adapter = adapter } } @@ -60,12 +60,10 @@ class SearchFragment : Fragment() { grid_media_search.setOnItemClickListener { _, _, position, _ -> search_text.clearFocus() // remove focus from the SearchView - runBlocking { - val media = adapter?.getItem(position) as Media - println("selected item is: ${media.title}") + val media = adapter?.getItem(position) as Media + println("selected item is: ${media.title}") - (activity as MainActivity).showDetailFragment(media).join() - } + (activity as MainActivity).showMediaFragment(media) } } } \ No newline at end of file diff --git a/app/src/main/java/org/mosad/teapod/util/LoadingFragment.kt b/app/src/main/java/org/mosad/teapod/util/LoadingFragment.kt new file mode 100644 index 0000000..00a3473 --- /dev/null +++ b/app/src/main/java/org/mosad/teapod/util/LoadingFragment.kt @@ -0,0 +1,16 @@ +package org.mosad.teapod.util + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import org.mosad.teapod.R + +class LoadingFragment : Fragment() { + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.fragment_loading, container, false) + } + +} \ No newline at end of file diff --git a/app/src/main/java/org/mosad/teapod/util/EpisodesAdapter.kt b/app/src/main/java/org/mosad/teapod/util/adapter/EpisodeItemAdapter.kt similarity index 89% rename from app/src/main/java/org/mosad/teapod/util/EpisodesAdapter.kt rename to app/src/main/java/org/mosad/teapod/util/adapter/EpisodeItemAdapter.kt index 0bce94d..903a264 100644 --- a/app/src/main/java/org/mosad/teapod/util/EpisodesAdapter.kt +++ b/app/src/main/java/org/mosad/teapod/util/adapter/EpisodeItemAdapter.kt @@ -1,4 +1,4 @@ -package org.mosad.teapod.util +package org.mosad.teapod.util.adapter import android.content.Context import android.view.LayoutInflater @@ -10,8 +10,9 @@ import com.bumptech.glide.request.RequestOptions import jp.wasabeef.glide.transformations.RoundedCornersTransformation import kotlinx.android.synthetic.main.item_episode.view.* import org.mosad.teapod.R +import org.mosad.teapod.util.Episode -class EpisodesAdapter(private val episodes: List, private val context: Context) : RecyclerView.Adapter() { +class EpisodeItemAdapter(private val episodes: List, private val context: Context) : RecyclerView.Adapter() { var onItemClick: ((String, Int) -> Unit)? = null diff --git a/app/src/main/java/org/mosad/teapod/util/CustomAdapter.kt b/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemAdapter.kt similarity index 91% rename from app/src/main/java/org/mosad/teapod/util/CustomAdapter.kt rename to app/src/main/java/org/mosad/teapod/util/adapter/MediaItemAdapter.kt index a8b38f4..14f9043 100644 --- a/app/src/main/java/org/mosad/teapod/util/CustomAdapter.kt +++ b/app/src/main/java/org/mosad/teapod/util/adapter/MediaItemAdapter.kt @@ -1,4 +1,4 @@ -package org.mosad.teapod.util +package org.mosad.teapod.util.adapter import android.content.Context import android.view.LayoutInflater @@ -7,9 +7,10 @@ import android.view.ViewGroup import android.widget.* import com.bumptech.glide.Glide import org.mosad.teapod.R +import org.mosad.teapod.util.Media import java.util.* -class CustomAdapter(val context: Context, private val originalMedia: ArrayList) : BaseAdapter(), Filterable { +class MediaItemAdapter(val context: Context, private val originalMedia: ArrayList) : BaseAdapter(), Filterable { private var filteredMedia = originalMedia.map { it.copy() } private val customFilter = CustomFilter() diff --git a/app/src/main/res/layout/activity_player.xml b/app/src/main/res/layout/activity_player.xml index 1d48ecd..c156d6b 100644 --- a/app/src/main/res/layout/activity_player.xml +++ b/app/src/main/res/layout/activity_player.xml @@ -1,6 +1,5 @@ - + android:layout_gravity="center" + tools:visibility="visible" /> \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_loading.xml b/app/src/main/res/layout/fragment_loading.xml new file mode 100644 index 0000000..51d0003 --- /dev/null +++ b/app/src/main/res/layout/fragment_loading.xml @@ -0,0 +1,17 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_media.xml b/app/src/main/res/layout/fragment_media.xml index 66def21..40f6e9d 100644 --- a/app/src/main/res/layout/fragment_media.xml +++ b/app/src/main/res/layout/fragment_media.xml @@ -30,12 +30,13 @@ android:minHeight="220dp" android:scaleType="centerCrop" /> - + app:shapeAppearance="@style/ShapeAppearance.Teapod.RoundedPoster" + app:srcCompat="@drawable/ic_launcher_background" /> diff --git a/app/src/main/res/layout/item_episode.xml b/app/src/main/res/layout/item_episode.xml index b51beb7..457a2cd 100644 --- a/app/src/main/res/layout/item_episode.xml +++ b/app/src/main/res/layout/item_episode.xml @@ -14,12 +14,13 @@ android:layout_height="wrap_content" android:orientation="horizontal"> - + app:srcCompat="@color/md_disabled_text_dark_theme" + app:shapeAppearance="@style/ShapeAppearance.Teapod.RoundedPoster"/> @null + + \ No newline at end of file