use view binding wherever possible

This commit is contained in:
Jannik 2020-11-25 22:35:55 +01:00
parent 8d1c3d9a3f
commit 7df99ea0cc
Signed by: Seil0
GPG Key ID: E8459F3723C52C24
12 changed files with 108 additions and 110 deletions

View File

@ -18,6 +18,10 @@ android {
setProperty("archivesBaseName", "teapod-$versionName") setProperty("archivesBaseName", "teapod-$versionName")
} }
buildFeatures {
viewBinding true
}
buildTypes { buildTypes {
release { release {
minifyEnabled true minifyEnabled true

View File

@ -22,7 +22,7 @@
</intent-filter> </intent-filter>
</activity> </activity>
<activity <activity
android:name=".PlayerActivity" android:name=".player.PlayerActivity"
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/PlayerTheme" android:theme="@style/PlayerTheme"
android:configChanges="orientation|screenSize|layoutDirection" /> android:configChanges="orientation|screenSize|layoutDirection" />

View File

@ -30,10 +30,11 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.commit import androidx.fragment.app.commit
import com.google.android.material.bottomnavigation.BottomNavigationView import com.google.android.material.bottomnavigation.BottomNavigationView
import kotlinx.android.synthetic.main.activity_main.*
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.mosad.teapod.databinding.ActivityMainBinding
import org.mosad.teapod.parser.AoDParser import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.player.PlayerActivity
import org.mosad.teapod.preferences.EncryptedPreferences import org.mosad.teapod.preferences.EncryptedPreferences
import org.mosad.teapod.preferences.Preferences import org.mosad.teapod.preferences.Preferences
import org.mosad.teapod.ui.components.LoginDialog import org.mosad.teapod.ui.components.LoginDialog
@ -45,6 +46,7 @@ import kotlin.system.measureTimeMillis
class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemSelectedListener { class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemSelectedListener {
private lateinit var binding: ActivityMainBinding
private var activeBaseFragment: Fragment = HomeFragment() // the currently active fragment, home at the start private var activeBaseFragment: Fragment = HomeFragment() // the currently active fragment, home at the start
companion object { companion object {
@ -53,6 +55,7 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
if (!wasInitialized) { if (!wasInitialized) {
load() load()
@ -60,8 +63,8 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
theme.applyStyle(getThemeResource(), true) theme.applyStyle(getThemeResource(), true)
setContentView(R.layout.activity_main) setContentView(binding.root)
nav_view.setOnNavigationItemSelectedListener(this) binding.navView.setOnNavigationItemSelectedListener(this)
supportFragmentManager.commit { supportFragmentManager.commit {
replace(R.id.nav_host_fragment, activeBaseFragment, activeBaseFragment.javaClass.simpleName) replace(R.id.nav_host_fragment, activeBaseFragment, activeBaseFragment.javaClass.simpleName)
@ -73,7 +76,7 @@ class MainActivity : AppCompatActivity(), BottomNavigationView.OnNavigationItemS
supportFragmentManager.popBackStack() supportFragmentManager.popBackStack()
} else { } else {
if (activeBaseFragment !is HomeFragment) { if (activeBaseFragment !is HomeFragment) {
nav_view.selectedItemId = R.id.navigation_home binding.navView.selectedItemId = R.id.navigation_home
} else { } else {
super.onBackPressed() super.onBackPressed()
} }

View File

@ -1,4 +1,4 @@
package org.mosad.teapod package org.mosad.teapod.player
import android.animation.Animator import android.animation.Animator
import android.animation.AnimatorListenerAdapter import android.animation.AnimatorListenerAdapter
@ -27,7 +27,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.mosad.teapod.player.PlayerViewModel import org.mosad.teapod.R
import org.mosad.teapod.preferences.Preferences import org.mosad.teapod.preferences.Preferences
import org.mosad.teapod.util.Episode import org.mosad.teapod.util.Episode
import java.util.* import java.util.*
@ -36,14 +36,14 @@ import kotlin.concurrent.scheduleAtFixedRate
class PlayerActivity : AppCompatActivity() { class PlayerActivity : AppCompatActivity() {
private val model: PlayerViewModel by viewModels()
private lateinit var player: SimpleExoPlayer private lateinit var player: SimpleExoPlayer
private lateinit var dataSourceFactory: DataSource.Factory private lateinit var dataSourceFactory: DataSource.Factory
private lateinit var controller: StyledPlayerControlView private lateinit var controller: StyledPlayerControlView
private lateinit var gestureDetector: GestureDetectorCompat private lateinit var gestureDetector: GestureDetectorCompat
private lateinit var timerUpdates: TimerTask private lateinit var timerUpdates: TimerTask
private val model: PlayerViewModel by viewModels()
private var playWhenReady = true private var playWhenReady = true
private var currentWindow = 0 private var currentWindow = 0
private var playbackPosition: Long = 0 private var playbackPosition: Long = 0
@ -78,7 +78,7 @@ class PlayerActivity : AppCompatActivity() {
super.onStart() super.onStart()
if (Util.SDK_INT > 23) { if (Util.SDK_INT > 23) {
initPlayer() initPlayer()
if (video_view != null) video_view.onResume() video_view?.onResume()
} }
} }
@ -86,14 +86,14 @@ class PlayerActivity : AppCompatActivity() {
super.onResume() super.onResume()
if (Util.SDK_INT <= 23) { if (Util.SDK_INT <= 23) {
initPlayer() initPlayer()
if (video_view != null) video_view.onResume() video_view?.onResume()
} }
} }
override fun onPause() { override fun onPause() {
super.onPause() super.onPause()
if (Util.SDK_INT <= 23) { if (Util.SDK_INT <= 23) {
if (video_view != null) video_view.onPause() video_view?.onPause()
releasePlayer() releasePlayer()
} }
} }

View File

@ -9,10 +9,10 @@ import androidx.fragment.app.Fragment
import com.afollestad.materialdialogs.MaterialDialog import com.afollestad.materialdialogs.MaterialDialog
import com.afollestad.materialdialogs.list.listItemsSingleChoice import com.afollestad.materialdialogs.list.listItemsSingleChoice
import de.psdev.licensesdialog.LicensesDialog import de.psdev.licensesdialog.LicensesDialog
import kotlinx.android.synthetic.main.fragment_account.*
import org.mosad.teapod.BuildConfig import org.mosad.teapod.BuildConfig
import org.mosad.teapod.MainActivity import org.mosad.teapod.MainActivity
import org.mosad.teapod.R import org.mosad.teapod.R
import org.mosad.teapod.databinding.FragmentAccountBinding
import org.mosad.teapod.parser.AoDParser import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.preferences.EncryptedPreferences import org.mosad.teapod.preferences.EncryptedPreferences
import org.mosad.teapod.preferences.Preferences import org.mosad.teapod.preferences.Preferences
@ -21,44 +21,46 @@ import org.mosad.teapod.util.DataTypes.Theme
class AccountFragment : Fragment() { class AccountFragment : Fragment() {
private lateinit var binding: FragmentAccountBinding
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.fragment_account, container, false) binding = FragmentAccountBinding.inflate(inflater, container, false)
return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
text_account_login.text = EncryptedPreferences.login binding.textAccountLogin.text = EncryptedPreferences.login
text_info_about_desc.text = getString(R.string.info_about_desc, BuildConfig.VERSION_NAME, getString(R.string.build_time)) binding.textInfoAboutDesc.text = getString(R.string.info_about_desc, BuildConfig.VERSION_NAME, getString(R.string.build_time))
text_theme_selected.text = when (Preferences.theme) { binding.textThemeSelected.text = when (Preferences.theme) {
Theme.DARK -> getString(R.string.theme_dark) Theme.DARK -> getString(R.string.theme_dark)
else -> getString(R.string.theme_light) else -> getString(R.string.theme_light)
} }
switch_secondary.isChecked = Preferences.preferSecondary binding.switchSecondary.isChecked = Preferences.preferSecondary
switch_autoplay.isChecked = Preferences.autoplay binding.switchAutoplay.isChecked = Preferences.autoplay
initActions() initActions()
} }
private fun initActions() { private fun initActions() {
linear_account_login.setOnClickListener { binding.linearAccountLogin.setOnClickListener {
showLoginDialog(true) showLoginDialog(true)
} }
linear_theme.setOnClickListener { binding.linearTheme.setOnClickListener {
showThemeDialog() showThemeDialog()
} }
linear_about.setOnClickListener { binding.linearInfo.setOnClickListener {
MaterialDialog(requireContext()) MaterialDialog(requireContext())
.title(R.string.info_about) .title(R.string.info_about)
.message(R.string.info_about_dialog) .message(R.string.info_about_dialog)
.show() .show()
} }
text_licenses.setOnClickListener { binding.textLicenses.setOnClickListener {
val dialogCss = when (Preferences.theme) { val dialogCss = when (Preferences.theme) {
Theme.DARK -> R.string.license_dialog_style_dark Theme.DARK -> R.string.license_dialog_style_dark
@ -80,12 +82,12 @@ class AccountFragment : Fragment() {
.show() .show()
} }
switch_secondary.setOnClickListener { binding.switchSecondary.setOnClickListener {
Preferences.savePreferSecondary(requireContext(), switch_secondary.isChecked) Preferences.savePreferSecondary(requireContext(), binding.switchSecondary.isChecked)
} }
switch_autoplay.setOnClickListener { binding.switchAutoplay.setOnClickListener {
Preferences.saveAutoplay(requireContext(), switch_autoplay.isChecked) Preferences.saveAutoplay(requireContext(), binding.switchAutoplay.isChecked)
} }
} }

View File

@ -5,13 +5,12 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.fragment_home.*
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.mosad.teapod.MainActivity import org.mosad.teapod.MainActivity
import org.mosad.teapod.R import org.mosad.teapod.databinding.FragmentHomeBinding
import org.mosad.teapod.parser.AoDParser import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.util.StorageController import org.mosad.teapod.util.StorageController
import org.mosad.teapod.util.adapter.MediaItemAdapter import org.mosad.teapod.util.adapter.MediaItemAdapter
@ -19,15 +18,13 @@ import org.mosad.teapod.util.decoration.MediaItemDecoration
class HomeFragment : Fragment() { class HomeFragment : Fragment() {
private lateinit var binding: FragmentHomeBinding
private lateinit var adapterMyList: MediaItemAdapter private lateinit var adapterMyList: MediaItemAdapter
private lateinit var adapterNewEpisodes: MediaItemAdapter private lateinit var adapterNewEpisodes: MediaItemAdapter
override fun onCreateView( override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
inflater: LayoutInflater, binding = FragmentHomeBinding.inflate(inflater, container, false)
container: ViewGroup?, return binding.root
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_home, container, false)
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -36,13 +33,13 @@ class HomeFragment : Fragment() {
GlobalScope.launch { GlobalScope.launch {
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
context?.let { context?.let {
recycler_my_list.addItemDecoration(MediaItemDecoration(9)) binding.recyclerMyList.addItemDecoration(MediaItemDecoration(9))
updateMyListMedia() updateMyListMedia()
adapterNewEpisodes = MediaItemAdapter(AoDParser.newEpisodesList) adapterNewEpisodes = MediaItemAdapter(AoDParser.newEpisodesList)
recycler_new_episodes.adapter = adapterNewEpisodes binding.recyclerNewEpisodes.adapter = adapterNewEpisodes
recycler_new_episodes.addItemDecoration(MediaItemDecoration(9)) binding.recyclerNewEpisodes.addItemDecoration(MediaItemDecoration(9))
initActions() initActions()
} }
@ -63,7 +60,7 @@ class HomeFragment : Fragment() {
(activity as MainActivity).showMediaFragment(mediaId) (activity as MainActivity).showMediaFragment(mediaId)
} }
recycler_my_list.adapter = adapterMyList binding.recyclerMyList.adapter = adapterMyList
} }
private fun initActions() { private fun initActions() {

View File

@ -5,23 +5,24 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.fragment_library.*
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.mosad.teapod.MainActivity import org.mosad.teapod.MainActivity
import org.mosad.teapod.R import org.mosad.teapod.databinding.FragmentLibraryBinding
import org.mosad.teapod.parser.AoDParser import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.util.adapter.MediaItemAdapter import org.mosad.teapod.util.adapter.MediaItemAdapter
import org.mosad.teapod.util.decoration.MediaItemDecoration import org.mosad.teapod.util.decoration.MediaItemDecoration
class LibraryFragment : Fragment() { class LibraryFragment : Fragment() {
private lateinit var binding: FragmentLibraryBinding
private lateinit var adapter: MediaItemAdapter private lateinit var adapter: MediaItemAdapter
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.fragment_library, container, false) binding = FragmentLibraryBinding.inflate(inflater, container, false)
return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -37,8 +38,8 @@ class LibraryFragment : Fragment() {
(activity as MainActivity).showMediaFragment(mediaId) (activity as MainActivity).showMediaFragment(mediaId)
} }
recycler_media_library.adapter = adapter binding.recyclerMediaLibrary.adapter = adapter
recycler_media_library.addItemDecoration(MediaItemDecoration(9)) binding.recyclerMediaLibrary.addItemDecoration(MediaItemDecoration(9))
} }
} }

View File

@ -13,9 +13,9 @@ import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
import jp.wasabeef.glide.transformations.BlurTransformation import jp.wasabeef.glide.transformations.BlurTransformation
import kotlinx.android.synthetic.main.fragment_media.*
import org.mosad.teapod.MainActivity import org.mosad.teapod.MainActivity
import org.mosad.teapod.R import org.mosad.teapod.R
import org.mosad.teapod.databinding.FragmentMediaBinding
import org.mosad.teapod.parser.AoDParser import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.util.DataTypes.MediaType import org.mosad.teapod.util.DataTypes.MediaType
import org.mosad.teapod.util.Episode import org.mosad.teapod.util.Episode
@ -26,6 +26,7 @@ import org.mosad.teapod.util.adapter.EpisodeItemAdapter
class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) : Fragment() { class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) : Fragment() {
private lateinit var binding: FragmentMediaBinding
private lateinit var adapterRecEpisodes: EpisodeItemAdapter private lateinit var adapterRecEpisodes: EpisodeItemAdapter
private lateinit var viewManager: RecyclerView.LayoutManager private lateinit var viewManager: RecyclerView.LayoutManager
private lateinit var nextEpisode: Episode private lateinit var nextEpisode: Episode
@ -38,8 +39,9 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) :
instance = this instance = this
} }
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.fragment_media, container, false) binding = FragmentMediaBinding.inflate(inflater, container, false)
return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -60,29 +62,29 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) :
Glide.with(requireContext()).load(backdropUrl) Glide.with(requireContext()).load(backdropUrl)
.apply(RequestOptions.placeholderOf(ColorDrawable(Color.DKGRAY))) .apply(RequestOptions.placeholderOf(ColorDrawable(Color.DKGRAY)))
.apply(RequestOptions.bitmapTransform(BlurTransformation(20, 3))) .apply(RequestOptions.bitmapTransform(BlurTransformation(20, 3)))
.into(image_backdrop) .into(binding.imageBackdrop)
Glide.with(requireContext()).load(posterUrl) Glide.with(requireContext()).load(posterUrl)
.into(image_poster) .into(binding.imagePoster)
text_title.text = media.info.title binding.textTitle.text = media.info.title
text_year.text = media.info.year.toString() binding.textYear.text = media.info.year.toString()
text_age.text = media.info.age.toString() binding.textAge.text = media.info.age.toString()
text_overview.text = media.info.shortDesc binding.textOverview.text = media.info.shortDesc
if (StorageController.myList.contains(media.id)) { if (StorageController.myList.contains(media.id)) {
Glide.with(requireContext()).load(R.drawable.ic_baseline_check_24).into(image_my_list_action) Glide.with(requireContext()).load(R.drawable.ic_baseline_check_24).into(binding.imageMyListAction)
} else { } else {
Glide.with(requireContext()).load(R.drawable.ic_baseline_add_24).into(image_my_list_action) Glide.with(requireContext()).load(R.drawable.ic_baseline_add_24).into(binding.imageMyListAction)
} }
// specific gui // specific gui
if (media.type == MediaType.TVSHOW) { if (media.type == MediaType.TVSHOW) {
adapterRecEpisodes = EpisodeItemAdapter(media.episodes) adapterRecEpisodes = EpisodeItemAdapter(media.episodes)
viewManager = LinearLayoutManager(context) viewManager = LinearLayoutManager(context)
recycler_episodes.layoutManager = viewManager binding.recyclerEpisodes.layoutManager = viewManager
recycler_episodes.adapter = adapterRecEpisodes binding.recyclerEpisodes.adapter = adapterRecEpisodes
text_episodes_or_runtime.text = getString(R.string.text_episodes_count, media.info.episodesCount) binding.textEpisodesOrRuntime.text = getString(R.string.text_episodes_count, media.info.episodesCount)
// get next episode // get next episode
nextEpisode = if (media.episodes.firstOrNull{ !it.watched } != null) { nextEpisode = if (media.episodes.firstOrNull{ !it.watched } != null) {
@ -92,20 +94,20 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) :
} }
// title is the next episodes title // title is the next episodes title
text_title.text = nextEpisode.title binding.textTitle.text = nextEpisode.title
} else if (media.type == MediaType.MOVIE) { } else if (media.type == MediaType.MOVIE) {
recycler_episodes.visibility = View.GONE binding.recyclerEpisodes.visibility = View.GONE
if (tmdb.runtime > 0) { if (tmdb.runtime > 0) {
text_episodes_or_runtime.text = getString(R.string.text_runtime, tmdb.runtime) binding.textEpisodesOrRuntime.text = getString(R.string.text_runtime, tmdb.runtime)
} else { } else {
text_episodes_or_runtime.visibility = View.GONE binding.textEpisodesOrRuntime.visibility = View.GONE
} }
} }
} }
private fun initActions() { private fun initActions() {
button_play.setOnClickListener { binding.buttonPlay.setOnClickListener {
when (media.type) { when (media.type) {
MediaType.MOVIE -> playStream(media.episodes.first()) MediaType.MOVIE -> playStream(media.episodes.first())
MediaType.TVSHOW -> playEpisode(nextEpisode) MediaType.TVSHOW -> playEpisode(nextEpisode)
@ -114,13 +116,13 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) :
} }
// add or remove media from myList // add or remove media from myList
linear_my_list_action.setOnClickListener { binding.linearMyListAction.setOnClickListener {
if (StorageController.myList.contains(media.id)) { if (StorageController.myList.contains(media.id)) {
StorageController.myList.remove(media.id) StorageController.myList.remove(media.id)
Glide.with(requireContext()).load(R.drawable.ic_baseline_add_24).into(image_my_list_action) Glide.with(requireContext()).load(R.drawable.ic_baseline_add_24).into(binding.imageMyListAction)
} else { } else {
StorageController.myList.add(media.id) StorageController.myList.add(media.id)
Glide.with(requireContext()).load(R.drawable.ic_baseline_check_24).into(image_my_list_action) Glide.with(requireContext()).load(R.drawable.ic_baseline_check_24).into(binding.imageMyListAction)
} }
StorageController.saveMyList(requireContext()) StorageController.saveMyList(requireContext())
@ -153,7 +155,7 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) :
} else { } else {
media.episodes.first() media.episodes.first()
} }
text_title.text = nextEpisode.title binding.textTitle.text = nextEpisode.title
} }
private fun playStream(ep: Episode) { private fun playStream(ep: Episode) {

View File

@ -6,20 +6,21 @@ import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.SearchView import android.widget.SearchView
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import kotlinx.android.synthetic.main.fragment_search.*
import kotlinx.coroutines.* import kotlinx.coroutines.*
import org.mosad.teapod.MainActivity import org.mosad.teapod.MainActivity
import org.mosad.teapod.R import org.mosad.teapod.databinding.FragmentSearchBinding
import org.mosad.teapod.parser.AoDParser import org.mosad.teapod.parser.AoDParser
import org.mosad.teapod.util.decoration.MediaItemDecoration import org.mosad.teapod.util.decoration.MediaItemDecoration
import org.mosad.teapod.util.adapter.MediaItemAdapter import org.mosad.teapod.util.adapter.MediaItemAdapter
class SearchFragment : Fragment() { class SearchFragment : Fragment() {
private lateinit var binding: FragmentSearchBinding
private var adapter : MediaItemAdapter? = null private var adapter : MediaItemAdapter? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return inflater.inflate(R.layout.fragment_search, container, false) binding = FragmentSearchBinding.inflate(inflater, container, false)
return binding.root
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
@ -31,12 +32,12 @@ class SearchFragment : Fragment() {
context?.let { context?.let {
adapter = MediaItemAdapter(AoDParser.itemMediaList) adapter = MediaItemAdapter(AoDParser.itemMediaList)
adapter!!.onItemClick = { mediaId, _ -> adapter!!.onItemClick = { mediaId, _ ->
search_text.clearFocus() binding.searchText.clearFocus()
(activity as MainActivity).showMediaFragment(mediaId) (activity as MainActivity).showMediaFragment(mediaId)
} }
recycler_media_search.adapter = adapter binding.recyclerMediaSearch.adapter = adapter
recycler_media_search.addItemDecoration(MediaItemDecoration(9)) binding.recyclerMediaSearch.addItemDecoration(MediaItemDecoration(9))
} }
} }
} }
@ -45,7 +46,7 @@ class SearchFragment : Fragment() {
} }
private fun initActions() { private fun initActions() {
search_text.setOnQueryTextListener(object : SearchView.OnQueryTextListener { binding.searchText.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean { override fun onQueryTextSubmit(query: String?): Boolean {
adapter?.filter?.filter(query) adapter?.filter?.filter(query)
adapter?.notifyDataSetChanged() adapter?.notifyDataSetChanged()

View File

@ -1,30 +1,26 @@
package org.mosad.teapod.util.adapter package org.mosad.teapod.util.adapter
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.RequestOptions
import jp.wasabeef.glide.transformations.RoundedCornersTransformation import jp.wasabeef.glide.transformations.RoundedCornersTransformation
import kotlinx.android.synthetic.main.item_episode.view.*
import org.mosad.teapod.R import org.mosad.teapod.R
import org.mosad.teapod.databinding.ItemEpisodeBinding
import org.mosad.teapod.util.Episode import org.mosad.teapod.util.Episode
class EpisodeItemAdapter(private val episodes: List<Episode>) : RecyclerView.Adapter<EpisodeItemAdapter.EpisodeViewHolder>() { class EpisodeItemAdapter(private val episodes: List<Episode>) : RecyclerView.Adapter<EpisodeItemAdapter.EpisodeViewHolder>() {
var onItemClick: ((String, Int) -> Unit)? = null
var onImageClick: ((String, Int) -> Unit)? = null var onImageClick: ((String, Int) -> Unit)? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EpisodeViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EpisodeViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_episode, parent, false) return EpisodeViewHolder(ItemEpisodeBinding.inflate(LayoutInflater.from(parent.context), parent, false))
return EpisodeViewHolder(view)
} }
override fun onBindViewHolder(holder: EpisodeViewHolder, position: Int) { override fun onBindViewHolder(holder: EpisodeViewHolder, position: Int) {
val context = holder.view.context val context = holder.binding.root.context
val ep = episodes[position] val ep = episodes[position]
val titleText = if (ep.priStreamUrl.isEmpty() && ep.secStreamOmU) { val titleText = if (ep.priStreamUrl.isEmpty() && ep.secStreamOmU) {
@ -33,21 +29,21 @@ class EpisodeItemAdapter(private val episodes: List<Episode>) : RecyclerView.Ada
context.getString(R.string.component_episode_title, ep.number, ep.description) context.getString(R.string.component_episode_title, ep.number, ep.description)
} }
holder.view.text_episode_title.text = titleText holder.binding.textEpisodeTitle.text = titleText
holder.view.text_episode_desc.text = ep.shortDesc holder.binding.textEpisodeDesc.text = ep.shortDesc
if (episodes[position].posterUrl.isNotEmpty()) { if (episodes[position].posterUrl.isNotEmpty()) {
Glide.with(context).load(ep.posterUrl) Glide.with(context).load(ep.posterUrl)
.apply(RequestOptions.bitmapTransform(RoundedCornersTransformation(10, 0))) .apply(RequestOptions.bitmapTransform(RoundedCornersTransformation(10, 0)))
.into(holder.view.image_episode) .into(holder.binding.imageEpisode)
} }
if (ep.watched) { if (ep.watched) {
holder.view.image_watched.setImageDrawable( holder.binding.imageWatched.setImageDrawable(
ContextCompat.getDrawable(context, R.drawable.ic_baseline_check_circle_24) ContextCompat.getDrawable(context, R.drawable.ic_baseline_check_circle_24)
) )
} else { } else {
holder.view.image_watched.setImageDrawable(null) holder.binding.imageWatched.setImageDrawable(null)
} }
} }
@ -59,13 +55,9 @@ class EpisodeItemAdapter(private val episodes: List<Episode>) : RecyclerView.Ada
episodes[position].watched = watched episodes[position].watched = watched
} }
inner class EpisodeViewHolder(val view: View) : RecyclerView.ViewHolder(view) { inner class EpisodeViewHolder(val binding: ItemEpisodeBinding) : RecyclerView.ViewHolder(binding.root) {
init { init {
view.setOnClickListener { binding.imageEpisode.setOnClickListener {
onItemClick?.invoke(episodes[adapterPosition].title, adapterPosition)
}
view.image_episode.setOnClickListener {
onImageClick?.invoke(episodes[adapterPosition].title, adapterPosition) onImageClick?.invoke(episodes[adapterPosition].title, adapterPosition)
} }
} }

View File

@ -1,33 +1,29 @@
package org.mosad.teapod.util.adapter package org.mosad.teapod.util.adapter
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Filter import android.widget.Filter
import android.widget.Filterable import android.widget.Filterable
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import kotlinx.android.synthetic.main.item_media.view.* import org.mosad.teapod.databinding.ItemMediaBinding
import org.mosad.teapod.R
import org.mosad.teapod.util.ItemMedia import org.mosad.teapod.util.ItemMedia
import java.util.* import java.util.*
class MediaItemAdapter(private val media: List<ItemMedia>) : RecyclerView.Adapter<MediaItemAdapter.ViewHolder>(), Filterable { class MediaItemAdapter(private val media: List<ItemMedia>) : RecyclerView.Adapter<MediaItemAdapter.MediaViewHolder>(), Filterable {
var onItemClick: ((Int, Int) -> Unit)? = null var onItemClick: ((Int, Int) -> Unit)? = null
private val filter = MediaFilter() private val filter = MediaFilter()
private var filteredMedia = media.map { it.copy() } private var filteredMedia = media.map { it.copy() }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MediaItemAdapter.ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MediaItemAdapter.MediaViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_media, parent, false) return MediaViewHolder(ItemMediaBinding.inflate(LayoutInflater.from(parent.context), parent, false))
return ViewHolder(view)
} }
override fun onBindViewHolder(holder: MediaItemAdapter.ViewHolder, position: Int) { override fun onBindViewHolder(holder: MediaItemAdapter.MediaViewHolder, position: Int) {
holder.view.apply { holder.binding.root.apply {
text_title.text = filteredMedia[position].title holder.binding.textTitle.text = filteredMedia[position].title
Glide.with(context).load(filteredMedia[position].posterUrl).into(image_poster) Glide.with(context).load(filteredMedia[position].posterUrl).into(holder.binding.imagePoster)
} }
} }
@ -39,9 +35,9 @@ class MediaItemAdapter(private val media: List<ItemMedia>) : RecyclerView.Adapte
return filter return filter
} }
inner class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) { inner class MediaViewHolder(val binding: ItemMediaBinding) : RecyclerView.ViewHolder(binding.root) {
init { init {
view.setOnClickListener { binding.root.setOnClickListener {
onItemClick?.invoke(filteredMedia[adapterPosition].id, adapterPosition) onItemClick?.invoke(filteredMedia[adapterPosition].id, adapterPosition)
} }
} }

View File

@ -7,7 +7,7 @@
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="#000000" android:background="#000000"
android:keepScreenOn="true" android:keepScreenOn="true"
tools:context=".PlayerActivity"> tools:context=".player.PlayerActivity">
<com.google.android.exoplayer2.ui.StyledPlayerView <com.google.android.exoplayer2.ui.StyledPlayerView
android:id="@+id/video_view" android:id="@+id/video_view"