show loading screen while loading media fragment
* use material components for shaped images and progress indicator
This commit is contained in:
parent
d2728405d1
commit
5f80f1fabd
@ -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'
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
16
app/src/main/java/org/mosad/teapod/util/LoadingFragment.kt
Normal file
16
app/src/main/java/org/mosad/teapod/util/LoadingFragment.kt
Normal 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)
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
@ -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()
|
@ -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>
|
17
app/src/main/res/layout/fragment_loading.xml
Normal file
17
app/src/main/res/layout/fragment_loading.xml
Normal 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>
|
@ -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>
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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>
|
Loading…
Reference in New Issue
Block a user