Netflix 2025 UI/UX modernization: colors, themes, card animations, Glide TV optimization
This commit is contained in:
@@ -63,6 +63,9 @@ dependencies {
|
||||
implementation 'androidx.tv:tv-material:1.0.0-alpha10'
|
||||
implementation 'com.google.android.material:material:1.11.0'
|
||||
|
||||
// LeakCanary for memory leak detection (TV-optimized with Toast notifications)
|
||||
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.14'
|
||||
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.7.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0'
|
||||
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.7.0'
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.example.tvmon
|
||||
|
||||
import android.app.Application
|
||||
import android.util.Log
|
||||
import com.example.tvmon.di.appModules
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.android.ext.koin.androidLogger
|
||||
@@ -8,14 +9,20 @@ import org.koin.core.context.startKoin
|
||||
import org.koin.core.logger.Level
|
||||
|
||||
class TvmonApplication : Application() {
|
||||
|
||||
|
||||
companion object {
|
||||
private const val TAG = "TvmonApplication"
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
||||
|
||||
startKoin {
|
||||
androidLogger(Level.ERROR)
|
||||
androidContext(this@TvmonApplication)
|
||||
modules(appModules)
|
||||
}
|
||||
|
||||
Log.d(TAG, "TvmonApplication initialized")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,17 +3,30 @@ package com.example.tvmon
|
||||
import android.content.Context
|
||||
import com.bumptech.glide.GlideBuilder
|
||||
import com.bumptech.glide.annotation.GlideModule
|
||||
import com.bumptech.glide.load.DecodeFormat
|
||||
import com.bumptech.glide.load.engine.cache.InternalCacheDiskCacheFactory
|
||||
import com.bumptech.glide.load.engine.cache.LruResourceCache
|
||||
import com.bumptech.glide.module.AppGlideModule
|
||||
import com.bumptech.glide.request.RequestOptions
|
||||
|
||||
@GlideModule
|
||||
class TvmonGlideModule : AppGlideModule() {
|
||||
override fun applyOptions(context: Context, builder: GlideBuilder) {
|
||||
val memoryCacheSizeBytes = 1024 * 1024 * 50
|
||||
// TV-optimized memory cache: 30MB (lower than phone due to limited RAM)
|
||||
val memoryCacheSizeBytes = 1024 * 1024 * 30
|
||||
builder.setMemoryCache(LruResourceCache(memoryCacheSizeBytes.toLong()))
|
||||
|
||||
val diskCacheSizeBytes = 1024L * 1024L * 200L
|
||||
|
||||
// Disk cache: 150MB
|
||||
val diskCacheSizeBytes = 1024L * 1024L * 150L
|
||||
builder.setDiskCache(InternalCacheDiskCacheFactory(context, "image_cache", diskCacheSizeBytes))
|
||||
|
||||
// Use RGB_565 for lower memory usage (good quality for TV)
|
||||
builder.setDefaultRequestOptions(
|
||||
RequestOptions()
|
||||
.format(DecodeFormat.PREFER_RGB_565)
|
||||
.disallowHardwareConfig() // Avoid hardware bitmaps that can cause issues on TV
|
||||
)
|
||||
}
|
||||
|
||||
override fun isManifestParsingEnabled(): Boolean = false
|
||||
}
|
||||
@@ -86,7 +86,7 @@ class DetailsFragment : DetailsSupportFragment() {
|
||||
Log.w(TAG, "setupDetails: Setting up details UI")
|
||||
val presenterSelector = ClassPresenterSelector()
|
||||
val detailsPresenter = FullWidthDetailsOverviewRowPresenter(DetailsDescriptionPresenter())
|
||||
detailsPresenter.actionsBackgroundColor = ContextCompat.getColor(requireContext(), R.color.primary)
|
||||
detailsPresenter.actionsBackgroundColor = ContextCompat.getColor(requireContext(), R.color.accent)
|
||||
detailsPresenter.backgroundColor = ContextCompat.getColor(requireContext(), R.color.detail_background)
|
||||
presenterSelector.addClassPresenter(DetailsOverviewRow::class.java, detailsPresenter)
|
||||
presenterSelector.addClassPresenter(ListRow::class.java, ListRowPresenter())
|
||||
|
||||
@@ -46,26 +46,26 @@ class MainFragment : BrowseSupportFragment(), OnItemViewClickedListener, OnItemV
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupUI() {
|
||||
private fun setupUI() {
|
||||
Log.w(TAG, "setupUI: Setting up UI")
|
||||
headersState = HEADERS_ENABLED
|
||||
title = getString(R.string.browse_title)
|
||||
brandColor = ContextCompat.getColor(requireContext(), R.color.primary)
|
||||
searchAffordanceColor = ContextCompat.getColor(requireContext(), R.color.search_opaque)
|
||||
brandColor = ContextCompat.getColor(requireContext(), R.color.accent)
|
||||
searchAffordanceColor = ContextCompat.getColor(requireContext(), R.color.accent)
|
||||
|
||||
adapter = rowsAdapter
|
||||
onItemViewClickedListener = this
|
||||
onItemViewSelectedListener = this
|
||||
|
||||
setOnSearchClickedListener {
|
||||
val activity = requireActivity() as? MainActivity
|
||||
activity?.showSearchDialog { query ->
|
||||
val intent = Intent(requireContext(), com.example.tvmon.ui.search.SearchActivity::class.java).apply {
|
||||
putExtra("initial_query", query)
|
||||
setOnSearchClickedListener {
|
||||
val activity = requireActivity() as? MainActivity
|
||||
activity?.showSearchDialog { query ->
|
||||
val intent = Intent(requireContext(), com.example.tvmon.ui.search.SearchActivity::class.java).apply {
|
||||
putExtra("initial_query", query)
|
||||
}
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
startActivity(intent)
|
||||
}
|
||||
}
|
||||
Log.w(TAG, "setupUI: UI setup complete, adapter set")
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.example.tvmon.ui.presenter
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.OvershootInterpolator
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.leanback.widget.ImageCardView
|
||||
import androidx.leanback.widget.Presenter
|
||||
import com.bumptech.glide.Glide
|
||||
@@ -11,107 +13,150 @@ import com.example.tvmon.data.model.Category
|
||||
|
||||
class ContentCardPresenter : Presenter() {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {
|
||||
val cardView = ImageCardView(parent.context).apply {
|
||||
isFocusable = true
|
||||
isFocusableInTouchMode = true
|
||||
setBackgroundColor(parent.context.getColor(R.color.default_background))
|
||||
companion object {
|
||||
private const val FOCUS_SCALE = 1.08f
|
||||
private const val FOCUS_TRANSLATION_Z = 8f
|
||||
private const val ANIMATION_DURATION = 150L
|
||||
}
|
||||
return ViewHolder(cardView)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(viewHolder: ViewHolder, item: Any) {
|
||||
val content = item as Content
|
||||
val cardView = viewHolder.view as ImageCardView
|
||||
val res = cardView.context.resources
|
||||
|
||||
cardView.titleText = content.title
|
||||
cardView.contentText = null
|
||||
|
||||
val width = res.getDimensionPixelSize(R.dimen.card_width)
|
||||
val height = res.getDimensionPixelSize(R.dimen.card_height)
|
||||
cardView.setMainImageDimensions(width, height)
|
||||
|
||||
if (content.thumbnail.isNotBlank()) {
|
||||
Glide.with(cardView.context)
|
||||
.load(content.thumbnail)
|
||||
.error(R.drawable.default_background)
|
||||
.placeholder(R.drawable.default_background)
|
||||
.centerCrop()
|
||||
.into(cardView.mainImageView)
|
||||
} else {
|
||||
cardView.mainImageView.setImageResource(R.drawable.default_background)
|
||||
override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {
|
||||
val cardView = ImageCardView(parent.context).apply {
|
||||
isFocusable = true
|
||||
isFocusableInTouchMode = true
|
||||
setBackgroundColor(ContextCompat.getColor(context, R.color.default_background))
|
||||
setOnFocusChangeListener { view, hasFocus ->
|
||||
animateFocus(view, hasFocus)
|
||||
}
|
||||
}
|
||||
return ViewHolder(cardView)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onUnbindViewHolder(viewHolder: ViewHolder) {
|
||||
val cardView = viewHolder.view as ImageCardView
|
||||
cardView.badgeImage = null
|
||||
cardView.mainImage = null
|
||||
}
|
||||
private fun animateFocus(view: View, hasFocus: Boolean) {
|
||||
if (hasFocus) {
|
||||
view.animate()
|
||||
.scaleX(FOCUS_SCALE)
|
||||
.scaleY(FOCUS_SCALE)
|
||||
.translationZ(FOCUS_TRANSLATION_Z)
|
||||
.setDuration(ANIMATION_DURATION)
|
||||
.setInterpolator(OvershootInterpolator(1.2f))
|
||||
.start()
|
||||
view.setBackgroundColor(ContextCompat.getColor(view.context, R.color.focused_bg))
|
||||
} else {
|
||||
view.animate()
|
||||
.scaleX(1.0f)
|
||||
.scaleY(1.0f)
|
||||
.translationZ(0f)
|
||||
.setDuration(ANIMATION_DURATION)
|
||||
.setInterpolator(OvershootInterpolator(1.2f))
|
||||
.start()
|
||||
view.setBackgroundColor(ContextCompat.getColor(view.context, R.color.default_background))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(viewHolder: ViewHolder, item: Any) {
|
||||
val content = item as Content
|
||||
val cardView = viewHolder.view as ImageCardView
|
||||
val res = cardView.context.resources
|
||||
|
||||
cardView.titleText = content.title
|
||||
cardView.contentText = null
|
||||
|
||||
val width = res.getDimensionPixelSize(R.dimen.card_width)
|
||||
val height = res.getDimensionPixelSize(R.dimen.card_height)
|
||||
cardView.setMainImageDimensions(width, height)
|
||||
|
||||
if (content.thumbnail.isNotBlank()) {
|
||||
Glide.with(cardView.context)
|
||||
.load(content.thumbnail)
|
||||
.error(R.drawable.default_background)
|
||||
.placeholder(R.drawable.default_background)
|
||||
.centerCrop()
|
||||
.into(cardView.mainImageView)
|
||||
} else {
|
||||
cardView.mainImageView.setImageResource(R.drawable.default_background)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onUnbindViewHolder(viewHolder: ViewHolder) {
|
||||
val cardView = viewHolder.view as ImageCardView
|
||||
cardView.badgeImage = null
|
||||
cardView.mainImage = null
|
||||
}
|
||||
}
|
||||
|
||||
class SearchCardPresenter : Presenter() {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {
|
||||
val cardView = ImageCardView(parent.context).apply {
|
||||
isFocusable = true
|
||||
isFocusableInTouchMode = true
|
||||
setBackgroundColor(parent.context.getColor(R.color.default_background))
|
||||
cardType = ImageCardView.CARD_TYPE_INFO_UNDER
|
||||
infoVisibility = View.VISIBLE
|
||||
companion object {
|
||||
private const val FOCUS_SCALE = 1.1f
|
||||
private const val FOCUS_TRANSLATION_Z = 10f
|
||||
private const val ANIMATION_DURATION = 100L
|
||||
}
|
||||
|
||||
cardView.setOnFocusChangeListener { v, hasFocus ->
|
||||
if (hasFocus) {
|
||||
v.animate()
|
||||
.scaleX(1.1f)
|
||||
.scaleY(1.1f)
|
||||
.translationZ(10f)
|
||||
.setDuration(100)
|
||||
.start()
|
||||
} else {
|
||||
v.animate()
|
||||
.scaleX(1.0f)
|
||||
.scaleY(1.0f)
|
||||
.translationZ(0f)
|
||||
.setDuration(100)
|
||||
.start()
|
||||
}
|
||||
override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {
|
||||
val cardView = ImageCardView(parent.context).apply {
|
||||
isFocusable = true
|
||||
isFocusableInTouchMode = true
|
||||
setBackgroundColor(ContextCompat.getColor(context, R.color.default_background))
|
||||
cardType = ImageCardView.CARD_TYPE_INFO_UNDER
|
||||
infoVisibility = View.VISIBLE
|
||||
setOnFocusChangeListener { view, hasFocus ->
|
||||
animateFocus(view, hasFocus)
|
||||
}
|
||||
}
|
||||
return ViewHolder(cardView)
|
||||
}
|
||||
|
||||
return ViewHolder(cardView)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(viewHolder: ViewHolder, item: Any) {
|
||||
val content = item as Content
|
||||
val cardView = viewHolder.view as ImageCardView
|
||||
val res = cardView.context.resources
|
||||
|
||||
cardView.titleText = content.title
|
||||
cardView.contentText = content.category
|
||||
|
||||
val width = res.getDimensionPixelSize(R.dimen.card_width)
|
||||
val height = res.getDimensionPixelSize(R.dimen.card_height)
|
||||
cardView.setMainImageDimensions(width, height)
|
||||
|
||||
if (content.thumbnail.isNotBlank()) {
|
||||
Glide.with(cardView.context)
|
||||
.load(content.thumbnail)
|
||||
.error(R.drawable.default_background)
|
||||
.placeholder(R.drawable.default_background)
|
||||
.centerCrop()
|
||||
.into(cardView.mainImageView)
|
||||
} else {
|
||||
cardView.mainImageView.setImageResource(R.drawable.default_background)
|
||||
private fun animateFocus(view: View, hasFocus: Boolean) {
|
||||
if (hasFocus) {
|
||||
view.animate()
|
||||
.scaleX(FOCUS_SCALE)
|
||||
.scaleY(FOCUS_SCALE)
|
||||
.translationZ(FOCUS_TRANSLATION_Z)
|
||||
.setDuration(ANIMATION_DURATION)
|
||||
.setInterpolator(OvershootInterpolator(1.2f))
|
||||
.start()
|
||||
view.setBackgroundColor(ContextCompat.getColor(view.context, R.color.focused_bg))
|
||||
} else {
|
||||
view.animate()
|
||||
.scaleX(1.0f)
|
||||
.scaleY(1.0f)
|
||||
.translationZ(0f)
|
||||
.setDuration(ANIMATION_DURATION)
|
||||
.setInterpolator(OvershootInterpolator(1.2f))
|
||||
.start()
|
||||
view.setBackgroundColor(ContextCompat.getColor(view.context, R.color.default_background))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onUnbindViewHolder(viewHolder: ViewHolder) {
|
||||
val cardView = viewHolder.view as ImageCardView
|
||||
cardView.badgeImage = null
|
||||
cardView.mainImage = null
|
||||
}
|
||||
override fun onBindViewHolder(viewHolder: ViewHolder, item: Any) {
|
||||
val content = item as Content
|
||||
val cardView = viewHolder.view as ImageCardView
|
||||
val res = cardView.context.resources
|
||||
|
||||
cardView.titleText = content.title
|
||||
cardView.contentText = content.category
|
||||
|
||||
val width = res.getDimensionPixelSize(R.dimen.card_width)
|
||||
val height = res.getDimensionPixelSize(R.dimen.card_height)
|
||||
cardView.setMainImageDimensions(width, height)
|
||||
|
||||
if (content.thumbnail.isNotBlank()) {
|
||||
Glide.with(cardView.context)
|
||||
.load(content.thumbnail)
|
||||
.error(R.drawable.default_background)
|
||||
.placeholder(R.drawable.default_background)
|
||||
.centerCrop()
|
||||
.into(cardView.mainImageView)
|
||||
} else {
|
||||
cardView.mainImageView.setImageResource(R.drawable.default_background)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onUnbindViewHolder(viewHolder: ViewHolder) {
|
||||
val cardView = viewHolder.view as ImageCardView
|
||||
cardView.badgeImage = null
|
||||
cardView.mainImage = null
|
||||
}
|
||||
}
|
||||
|
||||
class CategoryCardPresenter : Presenter() {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package com.example.tvmon.ui.presenter
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.OvershootInterpolator
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.leanback.widget.ImageCardView
|
||||
import androidx.leanback.widget.Presenter
|
||||
import com.example.tvmon.R
|
||||
@@ -10,31 +13,62 @@ class EpisodePresenter(
|
||||
private val watchedEpisodeUrl: String? = null
|
||||
) : Presenter() {
|
||||
|
||||
companion object {
|
||||
private const val FOCUS_SCALE = 1.08f
|
||||
private const val FOCUS_TRANSLATION_Z = 8f
|
||||
private const val ANIMATION_DURATION = 150L
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup): ViewHolder {
|
||||
val cardView = ImageCardView(parent.context).apply {
|
||||
isFocusable = true
|
||||
isFocusableInTouchMode = true
|
||||
setBackgroundColor(parent.context.getColor(R.color.default_background))
|
||||
setBackgroundColor(ContextCompat.getColor(context, R.color.default_background))
|
||||
setOnFocusChangeListener { view, hasFocus ->
|
||||
animateFocus(view, hasFocus)
|
||||
}
|
||||
}
|
||||
return ViewHolder(cardView)
|
||||
}
|
||||
|
||||
private fun animateFocus(view: View, hasFocus: Boolean) {
|
||||
if (hasFocus) {
|
||||
view.animate()
|
||||
.scaleX(FOCUS_SCALE)
|
||||
.scaleY(FOCUS_SCALE)
|
||||
.translationZ(FOCUS_TRANSLATION_Z)
|
||||
.setDuration(ANIMATION_DURATION)
|
||||
.setInterpolator(OvershootInterpolator(1.2f))
|
||||
.start()
|
||||
view.setBackgroundColor(ContextCompat.getColor(view.context, R.color.focused_bg))
|
||||
} else {
|
||||
view.animate()
|
||||
.scaleX(1.0f)
|
||||
.scaleY(1.0f)
|
||||
.translationZ(0f)
|
||||
.setDuration(ANIMATION_DURATION)
|
||||
.setInterpolator(OvershootInterpolator(1.2f))
|
||||
.start()
|
||||
view.setBackgroundColor(ContextCompat.getColor(view.context, R.color.default_background))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(viewHolder: ViewHolder, item: Any) {
|
||||
val episode = item as Episode
|
||||
val cardView = viewHolder.view as ImageCardView
|
||||
val res = cardView.context.resources
|
||||
val ctx = cardView.context
|
||||
|
||||
cardView.titleText = episode.number
|
||||
cardView.contentText = episode.title
|
||||
|
||||
if (episode.url == watchedEpisodeUrl) {
|
||||
cardView.setBackgroundColor(res.getColor(R.color.accent))
|
||||
cardView.setBackgroundColor(ContextCompat.getColor(ctx, R.color.accent))
|
||||
} else {
|
||||
cardView.setBackgroundColor(res.getColor(R.color.default_background))
|
||||
cardView.setBackgroundColor(ContextCompat.getColor(ctx, R.color.default_background))
|
||||
}
|
||||
|
||||
val width = res.getDimensionPixelSize(R.dimen.episode_card_width)
|
||||
val height = res.getDimensionPixelSize(R.dimen.episode_card_height)
|
||||
val width = ctx.resources.getDimensionPixelSize(R.dimen.episode_card_width)
|
||||
val height = ctx.resources.getDimensionPixelSize(R.dimen.episode_card_height)
|
||||
cardView.setMainImageDimensions(width, height)
|
||||
|
||||
cardView.mainImageView.setImageResource(R.drawable.episode_placeholder)
|
||||
|
||||
@@ -1,10 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="primary">#1F1F1F</color>
|
||||
<!-- Netflix 2025 Color Scheme -->
|
||||
<color name="primary">#000000</color>
|
||||
<color name="primary_dark">#000000</color>
|
||||
<color name="accent">#FF6B6B</color>
|
||||
<color name="default_background">#282828</color>
|
||||
<color name="category_background">#3A3A3A</color>
|
||||
<color name="detail_background">#1F1F1F</color>
|
||||
<color name="accent">#E50914</color>
|
||||
<color name="netflix_red">#E50914</color>
|
||||
<color name="netflix_black">#000000</color>
|
||||
<color name="netflix_dark_gray">#141414</color>
|
||||
<color name="netflix_medium_gray">#333333</color>
|
||||
<color name="netflix_light_gray">#666666</color>
|
||||
<color name="default_background">#141414</color>
|
||||
<color name="category_background">#1F1F1F</color>
|
||||
<color name="detail_background">#000000</color>
|
||||
<color name="search_opaque">#AAFFFFFF</color>
|
||||
<color name="focused_card_border">#FFFFFF</color>
|
||||
<color name="card_overlay">#B3000000</color>
|
||||
<color name="focused_bg">#333333</color>
|
||||
<color name="card_focused_bg">#2A2A2A</color>
|
||||
</resources>
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<dimen name="card_width">180dp</dimen>
|
||||
<dimen name="card_height">240dp</dimen>
|
||||
|
||||
<!-- Netflix-style larger cards -->
|
||||
<dimen name="card_width">200dp</dimen>
|
||||
<dimen name="card_height">280dp</dimen>
|
||||
|
||||
<dimen name="category_card_width">240dp</dimen>
|
||||
<dimen name="category_card_height">160dp</dimen>
|
||||
|
||||
<dimen name="episode_card_width">200dp</dimen>
|
||||
<dimen name="episode_card_height">120dp</dimen>
|
||||
|
||||
|
||||
<dimen name="episode_card_width">220dp</dimen>
|
||||
<dimen name="episode_card_height">130dp</dimen>
|
||||
|
||||
<dimen name="cast_card_width">120dp</dimen>
|
||||
<dimen name="cast_card_height">160dp</dimen>
|
||||
|
||||
<!-- Netflix-style spacing -->
|
||||
<dimen name="row_vertical_spacing">28dp</dimen>
|
||||
<dimen name="card_horizontal_spacing">12dp</dimen>
|
||||
<dimen name="screen_margin">48dp</dimen>
|
||||
</resources>
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- Netflix 2025 Theme - Dark cinematic style -->
|
||||
<style name="Theme.Tvmon" parent="Theme.Leanback">
|
||||
<item name="android:colorPrimary">@color/primary</item>
|
||||
<item name="android:colorPrimaryDark">@color/primary_dark</item>
|
||||
<item name="android:colorAccent">@color/accent</item>
|
||||
<item name="android:windowBackground">@color/default_background</item>
|
||||
<item name="android:windowBackground">@color/netflix_black</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Tvmon.Playback" parent="Theme.Leanback">
|
||||
@@ -17,6 +18,6 @@
|
||||
<item name="android:colorPrimary">@color/primary</item>
|
||||
<item name="android:colorPrimaryDark">@color/primary_dark</item>
|
||||
<item name="android:colorAccent">@color/accent</item>
|
||||
<item name="android:windowBackground">@color/default_background</item>
|
||||
<item name="android:windowBackground">@color/netflix_black</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user