focus fix + rtl fix

This commit is contained in:
LagradOst 2023-07-27 21:47:42 +02:00
parent a1824c86a3
commit c98f35fd94
13 changed files with 284 additions and 126 deletions

View File

@ -13,16 +13,15 @@ import android.os.Bundle
import android.util.AttributeSet
import android.util.Log
import android.view.*
import android.view.animation.Animation
import android.view.animation.AnimationSet
import android.widget.LinearLayout
import android.widget.Toast
import androidx.activity.result.ActivityResultLauncher
import androidx.annotation.IdRes
import androidx.annotation.MainThread
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.doOnLayout
import androidx.core.animation.addListener
import androidx.core.view.ViewCompat
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.fragment.app.FragmentActivity
@ -35,22 +34,12 @@ import androidx.navigation.NavOptions
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupWithNavController
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.transition.ChangeBounds
import androidx.transition.ChangeTransform
import androidx.transition.Scene
import androidx.transition.TransitionManager
import androidx.transition.TransitionManager.beginDelayedTransition
import androidx.transition.TransitionSet
import com.fasterxml.jackson.databind.DeserializationFeature
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.google.android.gms.cast.framework.*
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.button.MaterialButton
import com.google.android.material.navigationrail.NavigationRailView
import com.google.android.material.snackbar.Snackbar
import com.jaredrummler.android.colorpicker.ColorPickerDialogListener
@ -108,6 +97,7 @@ import com.lagradost.cloudstream3.ui.setup.SetupFragmentExtensions
import com.lagradost.cloudstream3.utils.*
import com.lagradost.cloudstream3.utils.AppUtils.html
import com.lagradost.cloudstream3.utils.AppUtils.isCastApiAvailable
import com.lagradost.cloudstream3.utils.AppUtils.isLtr
import com.lagradost.cloudstream3.utils.AppUtils.isNetworkAvailable
import com.lagradost.cloudstream3.utils.AppUtils.loadCache
import com.lagradost.cloudstream3.utils.AppUtils.loadRepository
@ -131,6 +121,7 @@ import com.lagradost.cloudstream3.utils.UIHelper.getResourceColor
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
import com.lagradost.cloudstream3.utils.UIHelper.navigate
import com.lagradost.cloudstream3.utils.UIHelper.requestRW
import com.lagradost.cloudstream3.utils.UIHelper.toPx
import com.lagradost.nicehttp.Requests
import com.lagradost.nicehttp.ResponseParser
import kotlinx.coroutines.sync.Mutex
@ -140,6 +131,7 @@ import java.lang.ref.WeakReference
import java.net.URI
import java.net.URLDecoder
import java.nio.charset.Charset
import kotlin.math.absoluteValue
import kotlin.reflect.KClass
import kotlin.system.exitProcess
@ -472,13 +464,24 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
binding?.navHostFragment?.apply {
val params = layoutParams as ConstraintLayout.LayoutParams
val push = if (!dontPush && isTvSettings()) resources.getDimensionPixelSize(R.dimen.navbar_width) else 0
if(!this.isLtr()) {
params.setMargins(
params.leftMargin,
params.topMargin,
push,
params.bottomMargin
)
} else {
params.setMargins(
push,
params.topMargin,
params.rightMargin,
params.bottomMargin
)
}
params.setMargins(
if (!dontPush && isTvSettings()) resources.getDimensionPixelSize(R.dimen.navbar_width) else 0,
params.topMargin,
params.rightMargin,
params.bottomMargin
)
layoutParams = params
}
@ -572,9 +575,22 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
}
override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
CommonActivity.dispatchKeyEvent(this, event)?.let {
return it
val start = System.currentTimeMillis()
try {
val response = CommonActivity.dispatchKeyEvent(this, event)
if (response != null)
return response
} finally {
debugAssert({
val end = System.currentTimeMillis()
val delta = end - start
delta > 100
}) {
"Took over 100ms to navigate, smth is VERY wrong"
}
}
return super.dispatchKeyEvent(event)
}
@ -745,85 +761,186 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
}
private var binding: ActivityMainBinding? = null
private var focusOutline: WeakReference<View> = WeakReference(null)
private var lastFocus: WeakReference<View> = WeakReference(null)
private val layoutListener: View.OnLayoutChangeListener =
View.OnLayoutChangeListener { v, _, _, _, _, _, _, _, _ ->
updateFocusView(
v
)
}
private val attachListener : View.OnAttachStateChangeListener = object : View.OnAttachStateChangeListener {
override fun onViewAttachedToWindow(v: View) {
updateFocusView(v)
}
override fun onViewDetachedFromWindow(v: View) {
// removes the focus view but not the listener as updateFocusView(null) will remove the listener
focusOutline.get()?.isVisible = false
}
}
private fun updateFocusView(newFocus: View?) {
val focusOutline = focusOutline.get() ?: return
lastFocus.get()?.removeOnLayoutChangeListener(layoutListener)
lastFocus.get()?.removeOnAttachStateChangeListener(attachListener)
val wasGone = focusOutline.isGone
val visible =
newFocus != null && newFocus.measuredHeight > 0 && newFocus.measuredWidth > 0 && newFocus.isShown && newFocus.tag != "tv_no_focus_tag"
focusOutline.isVisible = visible
if (newFocus != null) {
lastFocus = WeakReference(newFocus)
val out = IntArray(2)
newFocus.getLocationInWindow(out)
val (x, y) = out
// out of bounds = 0,0
if(x == 0 && y == 0) {
focusOutline.isVisible = false
}
/*(newFocus.parent as? RecyclerView)?.let { recycle ->
println("PARET IS RECYLE")
val position = recycle.getChildAdapterPosition(newFocus)
recycle.scrollToPosition(position)
(recycle.layoutManager as? GridLayoutManager)?.let {
if(it.orientation == LinearLayout.HORIZONTAL) {
println("SCROLL")
}
}
}*/
newFocus.addOnLayoutChangeListener(layoutListener)
newFocus.addOnAttachStateChangeListener(attachListener)
// val set = AnimationSet(true)
if(!wasGone) {
(focusOutline.parent as? ViewGroup)?.let {
TransitionManager.endTransitions(it)
TransitionManager.beginDelayedTransition(
it,
TransitionSet().addTransition(ChangeBounds())
.addTransition(ChangeTransform())
.setDuration(100)
object TvFocus {
data class FocusTarget(
val width: Int,
val height: Int,
val x: Float,
val y: Float,
) {
companion object {
fun lerp(a: FocusTarget, b: FocusTarget, lerp: Float): FocusTarget {
val ilerp = 1 - lerp
return FocusTarget(
width = (a.width * ilerp + b.width * lerp).toInt(),
height = (a.height * ilerp + b.height * lerp).toInt(),
x = a.x * ilerp + b.x * lerp,
y = a.y * ilerp + b.y * lerp
)
}
}
// ObjectAnimator.ofFloat(focusOutline, "translationX",focusOutline.translationX, x.toFloat()
}
var last: FocusTarget = FocusTarget(0, 0, 0.0f, 0.0f)
var current: FocusTarget = FocusTarget(0, 0, 0.0f, 0.0f)
focusOutline.layoutParams = focusOutline.layoutParams?.apply {
width = newFocus.measuredWidth
height = newFocus.measuredHeight
var focusOutline: WeakReference<View> = WeakReference(null)
var lastFocus: WeakReference<View> = WeakReference(null)
private val layoutListener: View.OnLayoutChangeListener =
View.OnLayoutChangeListener { v, _, _, _, _, _, _, _, _ ->
updateFocusView(
v, same = true
)
}
private val attachListener: View.OnAttachStateChangeListener =
object : View.OnAttachStateChangeListener {
override fun onViewAttachedToWindow(v: View) {
updateFocusView(v)
}
override fun onViewDetachedFromWindow(v: View) {
// removes the focus view but not the listener as updateFocusView(null) will remove the listener
focusOutline.get()?.isVisible = false
}
}
private fun setTargetPosition(target: FocusTarget) {
focusOutline.get()?.apply {
layoutParams = layoutParams?.apply {
width = target.width
height = target.height
}
translationX = target.x
translationY = target.y
}
}
private var animator: ValueAnimator? = null
@MainThread
fun updateFocusView(newFocus: View?, same: Boolean = false) {
val focusOutline = focusOutline.get() ?: return
lastFocus.get()?.apply {
removeOnLayoutChangeListener(layoutListener)
removeOnAttachStateChangeListener(attachListener)
}
val wasGone = focusOutline.isGone
val visible =
newFocus != null && newFocus.measuredHeight > 0 && newFocus.measuredWidth > 0 && newFocus.isShown && newFocus.tag != "tv_no_focus_tag"
focusOutline.isVisible = visible
if (newFocus != null) {
lastFocus = WeakReference(newFocus)
val out = IntArray(2)
newFocus.getLocationInWindow(out)
val (screenX, screenY) = out
var (x,y) = screenX.toFloat() to screenY.toFloat()
val (currentX, currentY) = focusOutline.translationX to focusOutline.translationY
// println(">><<< $x $y $currentX $currentY")
if(!newFocus.isLtr()) {
x = x - focusOutline.rootView.width + newFocus.measuredWidth
}
// out of bounds = 0,0
if (screenX == 0 && screenY == 0) {
focusOutline.isVisible = false
}
newFocus.addOnLayoutChangeListener(layoutListener)
newFocus.addOnAttachStateChangeListener(attachListener)
val start = FocusTarget(
x = currentX,
y = currentY,
width = focusOutline.measuredWidth,
height = focusOutline.measuredHeight
)
val end = FocusTarget(
x = x,
y = y,
width = newFocus.measuredWidth,
height = newFocus.measuredHeight
)
// if they are the same within then snap, aka scrolling
val deltaMin = 50.toPx
if (start.width == end.width && start.height == end.height && (start.x - end.x).absoluteValue < deltaMin && (start.y - end.y).absoluteValue < deltaMin) {
animator?.cancel()
last = start
current = end
setTargetPosition(end)
return
}
// if running then "reuse"
if (animator?.isRunning == true) {
current = end
return
} else {
animator?.cancel()
}
last = start
current = end
// if previously gone, then tp
if (wasGone) {
setTargetPosition(current)
return
}
// animate between a and b
animator = ValueAnimator.ofFloat(0.0f, 1.0f).apply {
startDelay = 0
duration = 100
addUpdateListener { animation ->
val animatedValue = animation.animatedValue as Float
val target = FocusTarget.lerp(last, current, minOf(animatedValue, 1.0f))
setTargetPosition(target)
}
start()
}
// post check
if (!same) {
newFocus.postDelayed({
updateFocusView(lastFocus.get(), same = true)
}, 200)
}
/*
the following is working, but somewhat bad code code
if (!wasGone) {
(focusOutline.parent as? ViewGroup)?.let {
TransitionManager.endTransitions(it)
TransitionManager.beginDelayedTransition(
it,
TransitionSet().addTransition(ChangeBounds())
.addTransition(ChangeTransform())
.setDuration(100)
)
}
}
focusOutline.layoutParams = focusOutline.layoutParams?.apply {
width = newFocus.measuredWidth
height = newFocus.measuredHeight
}
focusOutline.translationX = x.toFloat()
focusOutline.translationY = y.toFloat()*/
}
focusOutline.translationX = x.toFloat()
focusOutline.translationY = y.toFloat()
}
}
override fun onCreate(savedInstanceState: Bundle?) {
app.initClient(this)
val settingsManager = PreferenceManager.getDefaultSharedPreferences(this)
@ -872,13 +989,13 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
if (isTvSettings()) {
val newLocalBinding = ActivityMainTvBinding.inflate(layoutInflater, null, false)
setContentView(newLocalBinding.root)
focusOutline = WeakReference(newLocalBinding.focusOutline)
TvFocus.focusOutline = WeakReference(newLocalBinding.focusOutline)
newLocalBinding.root.viewTreeObserver.addOnGlobalFocusChangeListener { _, newFocus ->
// println("refocus $oldFocus -> $newFocus")
updateFocusView(newFocus)
TvFocus.updateFocusView(newFocus)
}
newLocalBinding.root.viewTreeObserver.addOnScrollChangedListener {
updateFocusView(lastFocus.get())
TvFocus.updateFocusView(TvFocus.lastFocus.get(), same = true)
}
ActivityMainBinding.bind(newLocalBinding.root) // this may crash
@ -1230,16 +1347,21 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
}*/
if (BuildConfig.DEBUG) {
var providersAndroidManifestString = "Current androidmanifest should be:\n"
for (api in allProviders) {
providersAndroidManifestString += "<data android:scheme=\"https\" android:host=\"${
api.mainUrl.removePrefix(
"https://"
)
}\" android:pathPrefix=\"/\"/>\n"
try {
var providersAndroidManifestString = "Current androidmanifest should be:\n"
for (api in allProviders) {
providersAndroidManifestString += "<data android:scheme=\"https\" android:host=\"${
api.mainUrl.removePrefix(
"https://"
)
}\" android:pathPrefix=\"/\"/>\n"
}
println(providersAndroidManifestString)
} catch (t: Throwable) {
logError(t)
}
println(providersAndroidManifestString)
}
handleAppIntent(intent)

View File

@ -177,7 +177,7 @@ open class ParentItemAdapter(
).apply {
isHorizontal = info.isHorizontalImages
}
recyclerView.setLinearListLayout()
//recyclerView.setLinearListLayout()
}
}
@ -192,7 +192,7 @@ open class ParentItemAdapter(
isHorizontal = info.isHorizontalImages
hasNext = expand.hasNext
}
recyclerView.setLinearListLayout()
// recyclerView.setLinearListLayout()
title.text = info.name
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {

View File

@ -19,6 +19,7 @@ import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTrueT
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
import com.lagradost.cloudstream3.utils.AppUtils.html
import com.lagradost.cloudstream3.utils.UIHelper.setImage
import com.lagradost.cloudstream3.utils.UIHelper.toPx
import com.lagradost.cloudstream3.utils.VideoDownloadHelper
import java.util.*
@ -48,7 +49,8 @@ const val ACTION_PLAY_EPISODE_IN_WEB_VIDEO = 16
const val ACTION_PLAY_EPISODE_IN_MPV = 17
const val ACTION_MARK_AS_WATCHED = 18
const val TV_EP_SIZE_LARGE = 400
const val TV_EP_SIZE_SMALL = 300
data class EpisodeClickEvent(val action: Int, val data: ResultEpisode)
class EpisodeAdapter(
@ -172,7 +174,7 @@ class EpisodeAdapter(
localCard = card
val setWidth =
if (isTvSettings()) ViewGroup.LayoutParams.WRAP_CONTENT else ViewGroup.LayoutParams.MATCH_PARENT
if (isTvSettings()) TV_EP_SIZE_LARGE.toPx else ViewGroup.LayoutParams.MATCH_PARENT
binding.episodeLinHolder.layoutParams.width = setWidth
binding.episodeHolderLarge.layoutParams.width = setWidth
@ -293,7 +295,7 @@ class EpisodeAdapter(
binding.episodeHolder.layoutParams.apply {
width =
if (isTvSettings()) ViewGroup.LayoutParams.WRAP_CONTENT else ViewGroup.LayoutParams.MATCH_PARENT
if (isTvSettings()) TV_EP_SIZE_SMALL.toPx else ViewGroup.LayoutParams.MATCH_PARENT
}
binding.apply {

View File

@ -2,15 +2,19 @@ package com.lagradost.cloudstream3.ui.result
import android.content.Context
import android.view.View
import android.view.View.LAYOUT_DIRECTION_LTR
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.lagradost.cloudstream3.mvvm.logError
import com.lagradost.cloudstream3.utils.AppUtils.isLtr
import com.lagradost.cloudstream3.utils.AppUtils.isRtl
fun RecyclerView?.setLinearListLayout(isHorizontal: Boolean = true) {
if (this == null) return
this.layoutManager =
this.context?.let { LinearListLayout(it).apply { if (isHorizontal) setHorizontal() else setVertical() } }
?: this.layoutManager
// ?: this.layoutManager
}
open class LinearListLayout(context: Context?) :
@ -56,7 +60,7 @@ open class LinearListLayout(context: Context?) :
startSmoothScroll(linearSmoothScroller)
}*/
override fun onInterceptFocusSearch(focused: View, direction: Int): View? {
val dir = if (orientation == HORIZONTAL) {
var dir = if (orientation == HORIZONTAL) {
if (direction == View.FOCUS_DOWN || direction == View.FOCUS_UP) {
// This scrolls the recyclerview before doing focus search, which
// allows the focus search to work better.
@ -71,6 +75,9 @@ open class LinearListLayout(context: Context?) :
if (direction == View.FOCUS_RIGHT || direction == View.FOCUS_LEFT) return null
if (direction == View.FOCUS_DOWN) 1 else -1
}
if(this.isLayoutRTL) {
dir = -dir
}
return try {
getPosition(getCorrectParent(focused))?.let { position ->

View File

@ -62,6 +62,8 @@ import com.lagradost.cloudstream3.ui.search.SearchHelper
import com.lagradost.cloudstream3.utils.AppUtils.getNameFull
import com.lagradost.cloudstream3.utils.AppUtils.html
import com.lagradost.cloudstream3.utils.AppUtils.isCastApiAvailable
import com.lagradost.cloudstream3.utils.AppUtils.isLtr
import com.lagradost.cloudstream3.utils.AppUtils.isRtl
import com.lagradost.cloudstream3.utils.AppUtils.loadCache
import com.lagradost.cloudstream3.utils.AppUtils.openBrowser
import com.lagradost.cloudstream3.utils.ExtractorLink

View File

@ -14,6 +14,7 @@ import android.view.animation.DecelerateInterpolator
import androidx.appcompat.app.AlertDialog
import androidx.core.view.isGone
import androidx.core.view.isVisible
import androidx.core.widget.NestedScrollView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.RecyclerView
@ -30,6 +31,7 @@ import com.lagradost.cloudstream3.mvvm.observe
import com.lagradost.cloudstream3.mvvm.observeNullable
import com.lagradost.cloudstream3.ui.WatchType
import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup
import com.lagradost.cloudstream3.ui.player.CSPlayerEvent
import com.lagradost.cloudstream3.ui.player.ExtractorLinkGenerator
import com.lagradost.cloudstream3.ui.player.GeneratorPlayer
import com.lagradost.cloudstream3.ui.result.ResultFragment.getStoredData
@ -38,6 +40,8 @@ import com.lagradost.cloudstream3.ui.search.SearchAdapter
import com.lagradost.cloudstream3.ui.search.SearchHelper
import com.lagradost.cloudstream3.utils.AppUtils.getNameFull
import com.lagradost.cloudstream3.utils.AppUtils.html
import com.lagradost.cloudstream3.utils.AppUtils.isLtr
import com.lagradost.cloudstream3.utils.AppUtils.isRtl
import com.lagradost.cloudstream3.utils.AppUtils.loadCache
import com.lagradost.cloudstream3.utils.Coroutines.ioSafe
import com.lagradost.cloudstream3.utils.Coroutines.main
@ -254,6 +258,12 @@ class ResultFragmentTv : Fragment() {
resultEpisodesShow.onFocusChangeListener = rightListener
resultDescription.onFocusChangeListener = leftListener
resultBookmarkButton.onFocusChangeListener = leftListener
resultEpisodesShow.setOnClickListener {
// toggle, to make it more touch accessable just in case someone thinks that a
// tv layout is better but is using a touch device
toggleEpisodes(!episodeHolderTv.isVisible)
}
redirectToPlay.setOnFocusChangeListener { _, hasFocus ->
if (!hasFocus) return@setOnFocusChangeListener
toggleEpisodes(false)
@ -272,6 +282,12 @@ class ResultFragmentTv : Fragment() {
}
}
}
// parallax on background
resultFinishLoading.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { _, _, scrollY, _, oldScrollY ->
backgroundPosterHolder.translationY = -scrollY.toFloat() * 0.8f
})
redirectToEpisodes.setOnFocusChangeListener { _, hasFocus ->
if (!hasFocus) return@setOnFocusChangeListener
toggleEpisodes(true)
@ -290,10 +306,10 @@ class ResultFragmentTv : Fragment() {
}
}
resultEpisodes.layoutManager =
LinearListLayout(resultEpisodes.context).apply {
resultEpisodes.setLinearListLayout(false)/*.layoutManager =
LinearListLayout(resultEpisodes.context, resultEpisodes.isRtl()).apply {
setVertical()
}
}*/
resultReloadConnectionerror.setOnClickListener {
viewModel.load(

View File

@ -20,6 +20,9 @@ import android.os.*
import android.provider.MediaStore
import android.text.Spanned
import android.util.Log
import android.view.View
import android.view.View.LAYOUT_DIRECTION_LTR
import android.view.View.LAYOUT_DIRECTION_RTL
import android.view.animation.DecelerateInterpolator
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
@ -90,6 +93,9 @@ object AppUtils {
return if (layoutManager == null || adapter == null) false else layoutManager.findLastCompletelyVisibleItemPosition() < adapter.itemCount - 7 // bit more than 1 to make it more seamless
}
fun View.isLtr() = this.layoutDirection == LAYOUT_DIRECTION_LTR
fun View.isRtl() = this.layoutDirection == LAYOUT_DIRECTION_RTL
fun BottomSheetDialog?.ownHide() {
this?.hide()
}

View File

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:drawable="@drawable/outline_less" /> <!-- focused -->
<!--<item android:state_focused="true" android:drawable="@drawable/outline_less" />--> <!-- focused -->
</selector>

View File

@ -83,6 +83,7 @@
android:layout_height="match_parent">
<ImageView
android:elevation="999999999dp"
android:focusable="false"
android:focusableInTouchMode="false"
android:clickable="false"

View File

@ -126,6 +126,7 @@ https://developer.android.com/design/ui/tv/samples/jet-fit
<FrameLayout
android:id="@+id/background_poster_holder"
android:layout_width="match_parent"
android:layout_height="200dp"
android:visibility="visible">
@ -152,12 +153,12 @@ https://developer.android.com/design/ui/tv/samples/jet-fit
<androidx.core.widget.NestedScrollView
android:id="@+id/result_finish_loading"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/result_finish_loading"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
@ -415,6 +416,7 @@ https://developer.android.com/design/ui/tv/samples/jet-fit
<com.google.android.material.chip.ChipGroup
android:id="@+id/result_tag"
style="@style/ChipParent"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
@ -479,8 +481,8 @@ https://developer.android.com/design/ui/tv/samples/jet-fit
android:fadingEdge="horizontal"
android:focusable="false"
android:focusableInTouchMode="false"
android:nextFocusUp="@id/result_back"
android:nextFocusDown="@id/result_play_movie"
android:nextFocusUp="@id/result_episodes_show"
android:nextFocusDown="@id/result_recommendations_filter_selection"
android:orientation="horizontal"
android:paddingTop="5dp"
android:requiresFadingEdge="horizontal"
@ -502,9 +504,9 @@ https://developer.android.com/design/ui/tv/samples/jet-fit
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:nextFocusUp="@id/result_episodes"
android:nextFocusUp="@id/result_cast_items"
android:nextFocusDown="@id/result_recommendations_list"
android:orientation="horizontal"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:itemCount="2"
@ -525,7 +527,6 @@ https://developer.android.com/design/ui/tv/samples/jet-fit
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/primaryBlackBackground"
android:clipToPadding="false"
android:descendantFocusability="afterDescendants"
android:nextFocusUp="@id/result_recommendations_filter_selection"

View File

@ -122,18 +122,17 @@
tools:listitem="@layout/homepage_parent" />
<FrameLayout
android:background="?attr/primaryBlackBackground"
android:id="@+id/search_history_holder"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:paddingStart="@dimen/navbar_width"
android:layout_marginStart="@dimen/navbar_width"
android:id="@+id/search_history_recycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/primaryBlackBackground"
android:descendantFocusability="afterDescendants"
android:nextFocusLeft="@id/nav_rail_view"
android:visibility="visible"
@ -141,6 +140,7 @@
tools:listitem="@layout/search_history_item" />
<com.google.android.material.button.MaterialButton
android:layout_marginStart="@dimen/navbar_width"
android:id="@+id/search_clear_call_history"
style="@style/BlackButton"
android:layout_gravity="bottom"

View File

@ -6,10 +6,11 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/outline_drawable_less"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
android:nextFocusRight="@id/home_history_remove"
android:orientation="horizontal">
<!-- android:foreground="?android:attr/selectableItemBackgroundBorderless"
-->
<TextView
android:id="@+id/home_history_title"
android:layout_width="wrap_content"
@ -29,7 +30,6 @@
android:layout_gravity="center_vertical|end"
android:background="@drawable/outline_drawable_less"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
android:nextFocusLeft="@id/home_history_tab"
android:padding="10dp"

View File

@ -104,7 +104,7 @@
</style>
<style name="ChipParent">
<item name="chipSpacingVertical">5dp</item>
<item name="chipSpacingVertical">-5dp</item>
<item name="chipSpacingHorizontal">5dp</item>
<item name="textColor">?attr/textColor</item>
</style>