show loading screen while loading media fragment

* use material components for shaped images and progress indicator
This commit is contained in:
Jannik 2020-10-14 20:22:20 +02:00
parent d2728405d1
commit 5f80f1fabd
Signed by: Seil0
GPG Key ID: E8459F3723C52C24
13 changed files with 89 additions and 35 deletions

View File

@ -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'

View File

@ -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) {

View File

@ -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

View File

@ -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)
}
}

View File

@ -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)
}
}
}

View File

@ -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)
}
}

View File

@ -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<Episode>, private val context: Context) : RecyclerView.Adapter<EpisodesAdapter.MyViewHolder>() {
class EpisodeItemAdapter(private val episodes: List<Episode>, private val context: Context) : RecyclerView.Adapter<EpisodeItemAdapter.MyViewHolder>() {
var onItemClick: ((String, Int) -> Unit)? = null

View File

@ -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<Media>) : BaseAdapter(), Filterable {
class MediaItemAdapter(val context: Context, private val originalMedia: ArrayList<Media>) : BaseAdapter(), Filterable {
private var filteredMedia = originalMedia.map { it.copy() }
private val customFilter = CustomFilter()

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -15,10 +14,12 @@
android:layout_gravity="center" />
<!-- app:controller_layout_id="@layout/player_custom_control"/>-->
<ProgressBar
<com.google.android.material.progressindicator.ProgressIndicator
android:id="@+id/loading"
style="@style/Widget.MaterialComponents.ProgressIndicator.Circular.Indeterminate"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_gravity="center" />
android:layout_gravity="center"
tools:visibility="visible" />
</FrameLayout>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f5f5f5"
android:clickable="true"
android:focusable="true">
<com.google.android.material.progressindicator.ProgressIndicator
android:id="@+id/progressBar2"
style="@style/Widget.MaterialComponents.ProgressIndicator.Circular.Indeterminate"
android:layout_width="70dp"
android:layout_height="70dp"
android:layout_gravity="center"
tools:visibility="visible" />
</FrameLayout>

View File

@ -30,12 +30,13 @@
android:minHeight="220dp"
android:scaleType="centerCrop" />
<ImageView
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/image_poster"
android:layout_width="wrap_content"
android:layout_height="200dp"
android:layout_gravity="center"
android:src="@drawable/ic_launcher_background" />
app:shapeAppearance="@style/ShapeAppearance.Teapod.RoundedPoster"
app:srcCompat="@drawable/ic_launcher_background" />
</FrameLayout>

View File

@ -14,12 +14,13 @@
android:layout_height="wrap_content"
android:orientation="horizontal">
<ImageView
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/image_episode"
android:layout_width="128dp"
android:layout_height="72dp"
android:contentDescription="@string/component_poster_desc"
app:srcCompat="@color/md_disabled_text_dark_theme" />
app:srcCompat="@color/md_disabled_text_dark_theme"
app:shapeAppearance="@style/ShapeAppearance.Teapod.RoundedPoster"/>
<TextView
android:id="@+id/text_episode_title"

View File

@ -14,5 +14,10 @@
<item name="android:windowContentOverlay">@null</item>
</style>
<!-- shapes -->
<style name="ShapeAppearance.Teapod.RoundedPoster" parent="ShapeAppearance.MaterialComponents.LargeComponent">
<item name="cornerFamily">rounded</item>
<item name="cornerSize">5dp</item>
</style>
</resources>