redesign library and search fragment
* library/search now use a grid view with 2 columns * media is now represented as card * media details: poster and episodes have now rounded corners
This commit is contained in:
parent
87f9235b8a
commit
d2728405d1
|
@ -13,6 +13,7 @@ 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 jp.wasabeef.glide.transformations.RoundedCornersTransformation
|
||||||
import kotlinx.android.synthetic.main.fragment_media.*
|
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
|
||||||
|
@ -46,6 +47,7 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) :
|
||||||
// generic gui
|
// generic gui
|
||||||
val backdropUrl = if (tmdb.backdropUrl.isNotEmpty()) tmdb.backdropUrl else media.info.posterLink
|
val backdropUrl = if (tmdb.backdropUrl.isNotEmpty()) tmdb.backdropUrl else media.info.posterLink
|
||||||
val posterUrl = if (tmdb.posterUrl.isNotEmpty()) tmdb.posterUrl else media.info.posterLink
|
val posterUrl = if (tmdb.posterUrl.isNotEmpty()) tmdb.posterUrl else media.info.posterLink
|
||||||
|
val posterCornerRadius = if (tmdb.posterUrl.isNotEmpty()) 60 else 30
|
||||||
|
|
||||||
Glide.with(requireContext()).load(backdropUrl)
|
Glide.with(requireContext()).load(backdropUrl)
|
||||||
.apply(RequestOptions.placeholderOf(ColorDrawable(Color.DKGRAY)))
|
.apply(RequestOptions.placeholderOf(ColorDrawable(Color.DKGRAY)))
|
||||||
|
@ -53,6 +55,7 @@ class MediaFragment(private val media: Media, private val tmdb: TMDBResponse) :
|
||||||
.into(image_backdrop)
|
.into(image_backdrop)
|
||||||
|
|
||||||
Glide.with(requireContext()).load(posterUrl)
|
Glide.with(requireContext()).load(posterUrl)
|
||||||
|
.apply(RequestOptions.bitmapTransform(RoundedCornersTransformation(posterCornerRadius, 0)))
|
||||||
.into(image_poster)
|
.into(image_poster)
|
||||||
|
|
||||||
text_title.text = media.title
|
text_title.text = media.title
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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.android.synthetic.main.fragment_library.*
|
||||||
|
import kotlinx.android.synthetic.main.item_media.view.*
|
||||||
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.R
|
||||||
|
@ -33,7 +34,7 @@ class LibraryFragment : Fragment() {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
context?.let {
|
context?.let {
|
||||||
adapter = CustomAdapter(it, AoDParser.mediaList)
|
adapter = CustomAdapter(it, AoDParser.mediaList)
|
||||||
list_library.adapter = adapter
|
grid_media_library.adapter = adapter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,12 +43,11 @@ class LibraryFragment : Fragment() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initActions() {
|
private fun initActions() {
|
||||||
list_library.setOnItemClickListener { _, _, position, _ ->
|
grid_media_library.setOnItemClickListener { _, _, position, _ ->
|
||||||
val media = adapter.getItem(position) as Media
|
val media = adapter.getItem(position) as Media
|
||||||
println("selected item is: ${media.title}")
|
println("selected item is: ${media.title}")
|
||||||
|
|
||||||
val mainActivity = activity as MainActivity
|
(activity as MainActivity).showDetailFragment(media)
|
||||||
mainActivity.showDetailFragment(media)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ class SearchFragment : Fragment() {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
context?.let {
|
context?.let {
|
||||||
adapter = CustomAdapter(it, AoDParser.mediaList)
|
adapter = CustomAdapter(it, AoDParser.mediaList)
|
||||||
list_search.adapter = adapter
|
grid_media_search.adapter = adapter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ class SearchFragment : Fragment() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
list_search.setOnItemClickListener { _, _, position, _ ->
|
grid_media_search.setOnItemClickListener { _, _, position, _ ->
|
||||||
search_text.clearFocus() // remove focus from the SearchView
|
search_text.clearFocus() // remove focus from the SearchView
|
||||||
|
|
||||||
runBlocking {
|
runBlocking {
|
||||||
|
|
|
@ -15,7 +15,7 @@ class CustomAdapter(val context: Context, private val originalMedia: ArrayList<M
|
||||||
private val customFilter = CustomFilter()
|
private val customFilter = CustomFilter()
|
||||||
|
|
||||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
||||||
val view = convertView ?: LayoutInflater.from(context).inflate(R.layout.linear_media, parent, false)
|
val view = convertView ?: LayoutInflater.from(context).inflate(R.layout.item_media, parent, false)
|
||||||
|
|
||||||
val textTitle = view.findViewById<TextView>(R.id.text_title)
|
val textTitle = view.findViewById<TextView>(R.id.text_title)
|
||||||
val imagePoster = view.findViewById<ImageView>(R.id.image_poster)
|
val imagePoster = view.findViewById<ImageView>(R.id.image_poster)
|
||||||
|
|
|
@ -6,7 +6,9 @@ import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
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.component_episode.view.*
|
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.R
|
||||||
|
|
||||||
class EpisodesAdapter(private val episodes: List<Episode>, private val context: Context) : RecyclerView.Adapter<EpisodesAdapter.MyViewHolder>() {
|
class EpisodesAdapter(private val episodes: List<Episode>, private val context: Context) : RecyclerView.Adapter<EpisodesAdapter.MyViewHolder>() {
|
||||||
|
@ -14,7 +16,7 @@ class EpisodesAdapter(private val episodes: List<Episode>, private val context:
|
||||||
var onItemClick: ((String, Int) -> Unit)? = null
|
var onItemClick: ((String, Int) -> Unit)? = null
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
|
||||||
val view = LayoutInflater.from(parent.context).inflate(R.layout.component_episode, parent, false)
|
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_episode, parent, false)
|
||||||
|
|
||||||
return MyViewHolder(view)
|
return MyViewHolder(view)
|
||||||
}
|
}
|
||||||
|
@ -28,7 +30,9 @@ class EpisodesAdapter(private val episodes: List<Episode>, private val context:
|
||||||
holder.view.text_episode_desc.text = episodes[position].shortDesc
|
holder.view.text_episode_desc.text = episodes[position].shortDesc
|
||||||
|
|
||||||
if (episodes[position].posterLink.isNotEmpty()) {
|
if (episodes[position].posterLink.isNotEmpty()) {
|
||||||
Glide.with(context).load(episodes[position].posterLink).into(holder.view.image_episode)
|
Glide.with(context).load(episodes[position].posterLink)
|
||||||
|
.apply(RequestOptions.bitmapTransform(RoundedCornersTransformation(10, 0)))
|
||||||
|
.into(holder.view.image_episode)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!episodes[position].watched) {
|
if (!episodes[position].watched) {
|
||||||
|
|
|
@ -7,13 +7,16 @@
|
||||||
android:background="#f5f5f5"
|
android:background="#f5f5f5"
|
||||||
tools:context=".ui.library.LibraryFragment">
|
tools:context=".ui.library.LibraryFragment">
|
||||||
|
|
||||||
<ListView
|
<GridView
|
||||||
android:id="@+id/list_library"
|
android:id="@+id/grid_media_library"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
android:clipToPadding="false"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
android:horizontalSpacing="7dp"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
android:numColumns="2"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
android:padding="5dp"
|
||||||
|
android:verticalSpacing="7dp"
|
||||||
|
tools:layout_editor_absoluteX="5dp"
|
||||||
|
tools:layout_editor_absoluteY="5dp" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -33,9 +33,8 @@
|
||||||
<ImageView
|
<ImageView
|
||||||
android:id="@+id/image_poster"
|
android:id="@+id/image_poster"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="200dp"
|
||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:minHeight="200dp"
|
|
||||||
android:src="@drawable/ic_launcher_background" />
|
android:src="@drawable/ic_launcher_background" />
|
||||||
|
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|
|
@ -10,11 +10,8 @@
|
||||||
<SearchView
|
<SearchView
|
||||||
android:id="@+id/search_text"
|
android:id="@+id/search_text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="48dp"
|
android:layout_height="0dp"
|
||||||
android:iconifiedByDefault="false"
|
android:iconifiedByDefault="false"
|
||||||
android:paddingStart="5dp"
|
|
||||||
android:paddingTop="5dp"
|
|
||||||
android:paddingEnd="5dp"
|
|
||||||
android:paddingBottom="5dp"
|
android:paddingBottom="5dp"
|
||||||
android:queryHint="@string/search_hint"
|
android:queryHint="@string/search_hint"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
@ -23,13 +20,16 @@
|
||||||
|
|
||||||
</SearchView>
|
</SearchView>
|
||||||
|
|
||||||
<ListView
|
<GridView
|
||||||
android:id="@+id/list_search"
|
android:id="@+id/grid_media_search"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:horizontalSpacing="7dp"
|
||||||
|
android:numColumns="2"
|
||||||
|
android:padding="5dp"
|
||||||
|
android:verticalSpacing="7dp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/search_text" />
|
app:layout_constraintTop_toBottomOf="@+id/search_text" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -19,7 +19,7 @@
|
||||||
android:layout_width="128dp"
|
android:layout_width="128dp"
|
||||||
android:layout_height="72dp"
|
android:layout_height="72dp"
|
||||||
android:contentDescription="@string/component_poster_desc"
|
android:contentDescription="@string/component_poster_desc"
|
||||||
app:srcCompat="@drawable/ic_baseline_account_box_24" />
|
app:srcCompat="@color/md_disabled_text_dark_theme" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text_episode_title"
|
android:id="@+id/text_episode_title"
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<com.google.android.material.card.MaterialCardView 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"
|
||||||
|
app:cardCornerRadius="7dp"
|
||||||
|
app:cardElevation="4dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image_poster"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="112.5dp"
|
||||||
|
android:contentDescription="@string/media_poster_desc"
|
||||||
|
android:maxWidth="200dp"
|
||||||
|
android:scaleType="fitXY"
|
||||||
|
app:srcCompat="@color/md_disabled_text_dark_theme" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/text_title"
|
||||||
|
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" />
|
||||||
|
</LinearLayout>
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
|
@ -1,29 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout 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:id="@+id/linear_media"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:paddingStart="7dp"
|
|
||||||
android:paddingTop="3dp"
|
|
||||||
android:paddingEnd="7dp"
|
|
||||||
android:paddingBottom="5dp">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/text_title"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:text="TextView"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:textSize="18sp"
|
|
||||||
android:textStyle="bold" />
|
|
||||||
|
|
||||||
<ImageView
|
|
||||||
android:id="@+id/image_poster"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:minHeight="223dp"
|
|
||||||
tools:srcCompat="@drawable/ic_launcher_background" />
|
|
||||||
</LinearLayout>
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
<!-- search fragment -->
|
<!-- search fragment -->
|
||||||
<string name="search_hint">Search for movies and series</string>
|
<string name="search_hint">Search for movies and series</string>
|
||||||
|
<string name="media_poster_desc" translatable="false">poster</string>
|
||||||
|
|
||||||
<!-- media fragment -->
|
<!-- media fragment -->
|
||||||
<string name="button_play">Play</string>
|
<string name="button_play">Play</string>
|
||||||
|
|
Loading…
Reference in New Issue