major focus fixes

This commit is contained in:
LagradOst 2023-07-28 04:18:28 +02:00
parent c98f35fd94
commit c987f7581e
22 changed files with 268 additions and 139 deletions

View File

@ -27,6 +27,7 @@ import com.lagradost.cloudstream3.ui.player.PlayerEventType
import com.lagradost.cloudstream3.ui.result.ResultFragment
import com.lagradost.cloudstream3.ui.result.UiText
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.updateTv
import com.lagradost.cloudstream3.utils.AppUtils.isRtl
import com.lagradost.cloudstream3.utils.DataStoreHelper
import com.lagradost.cloudstream3.utils.Event
import com.lagradost.cloudstream3.utils.UIHelper
@ -299,22 +300,29 @@ object CommonActivity {
view: View?,
direction: FocusDirection,
depth: Int = 0
): Int? {
): View? {
// if input is invalid let android decide + depth test to not crash if loop is found
if (view == null || depth >= 10 || act == null) {
return null
}
val nextId = when (direction) {
FocusDirection.Left -> {
view.nextFocusLeftId
FocusDirection.Start -> {
if (view.isRtl())
view.nextFocusRightId
else
view.nextFocusLeftId
}
FocusDirection.Up -> {
view.nextFocusUpId
}
FocusDirection.Right -> {
view.nextFocusRightId
FocusDirection.End -> {
if (view.isRtl())
view.nextFocusLeftId
else
view.nextFocusRightId
}
FocusDirection.Down -> {
@ -322,27 +330,41 @@ object CommonActivity {
}
}
return if (nextId != -1) {
val next = act.findViewById<View?>(nextId)
//println("NAME: ${next.accessibilityClassName} | ${next?.isShown}" )
// if view not found then return
if (nextId == -1) return null
var next = act.findViewById<View?>(nextId) ?: return null
if (next?.isShown == false) {
getNextFocus(act, next, direction, depth + 1)
} else {
if (depth == 0) {
null
} else {
nextId
}
// because we want closes find, aka when multiple have the same id, we go to parent
// until the correct one is found
/*var currentLook: View = view
while (true) {
val tmpNext = currentLook.findViewById<View?>(nextId)
if (tmpNext != null) {
next = tmpNext
break
}
} else {
null
currentLook = currentLook.parent as? View ?: break
}*/
var currentLook: View = view
while (currentLook.findViewById<View?>(nextId)?.also { next = it } == null) {
currentLook = (currentLook.parent as? View) ?: break
}
// if cant focus but visible then break and let android decide
if (!next.isFocusable && next.isShown) return null
// if not shown then continue because we will "skip" over views to get to a replacement
if (!next.isShown) return getNextFocus(act, next, direction, depth + 1)
// nothing wrong with the view found, return it
return next
}
enum class FocusDirection {
Left,
Right,
Start,
End,
Up,
Down,
}
@ -447,17 +469,17 @@ object CommonActivity {
event?.keyCode?.let { keyCode ->
if (currentFocus == null || event.action != KeyEvent.ACTION_DOWN) return@let
val next = when (keyCode) {
val nextView = when (keyCode) {
KeyEvent.KEYCODE_DPAD_LEFT -> getNextFocus(
act,
currentFocus,
FocusDirection.Left
FocusDirection.Start
)
KeyEvent.KEYCODE_DPAD_RIGHT -> getNextFocus(
act,
currentFocus,
FocusDirection.Right
FocusDirection.End
)
KeyEvent.KEYCODE_DPAD_UP -> getNextFocus(
@ -475,13 +497,10 @@ object CommonActivity {
else -> null
}
if (next != null && next != -1) {
val nextView = act.findViewById<View?>(next)
if (nextView != null) {
nextView.requestFocus()
keyEventListener?.invoke(Pair(event, true))
return true
}
if (nextView != null) {
nextView.requestFocus()
keyEventListener?.invoke(Pair(event, true))
return true
}
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER && (act.currentFocus is SearchView || act.currentFocus is SearchView.SearchAutoComplete)) {

View File

@ -24,7 +24,7 @@ class GrdLayoutManager(val context: Context, _spanCount: Int) :
}
}
override fun onRequestChildFocus(
/*override fun onRequestChildFocus(
parent: RecyclerView,
state: RecyclerView.State,
child: View,
@ -32,13 +32,17 @@ class GrdLayoutManager(val context: Context, _spanCount: Int) :
): Boolean {
// android.widget.FrameLayout$LayoutParams cannot be cast to androidx.recyclerview.widget.RecyclerView$LayoutParams
return try {
val pos = maxOf(0, getPosition(focused!!) - 2)
parent.scrollToPosition(pos)
if(focused != null) {
// val pos = maxOf(0, getPosition(focused) - 2) // IDK WHY
val pos = getPosition(focused)
if(pos >= 0) parent.scrollToPosition(pos)
}
super.onRequestChildFocus(parent, state, child, focused)
} catch (e: Exception) {
false
}
}
}*/
// Allows moving right and left with focus https://gist.github.com/vganin/8930b41f55820ec49e4d
override fun onInterceptFocusSearch(focused: View, direction: Int): View? {
@ -65,8 +69,17 @@ class GrdLayoutManager(val context: Context, _spanCount: Int) :
val spanCount = this.spanCount
val orientation = this.orientation
// fixes arabic by inverting left and right layout focus
val correctDirection = if(this.isLayoutRTL) {
when(direction) {
View.FOCUS_RIGHT -> View.FOCUS_LEFT
View.FOCUS_LEFT -> View.FOCUS_RIGHT
else -> direction
}
} else direction
if (orientation == VERTICAL) {
when (direction) {
when (correctDirection) {
View.FOCUS_DOWN -> {
return spanCount
}
@ -81,7 +94,7 @@ class GrdLayoutManager(val context: Context, _spanCount: Int) :
}
}
} else if (orientation == HORIZONTAL) {
when (direction) {
when (correctDirection) {
View.FOCUS_DOWN -> {
return 1
}

View File

@ -11,6 +11,7 @@ import com.lagradost.cloudstream3.databinding.HomeResultGridBinding
import com.lagradost.cloudstream3.databinding.HomeResultGridExpandedBinding
import com.lagradost.cloudstream3.ui.search.SearchClickCallback
import com.lagradost.cloudstream3.ui.search.SearchResultBuilder
import com.lagradost.cloudstream3.utils.AppUtils.isRtl
import com.lagradost.cloudstream3.utils.UIHelper.IsBottomLayout
import com.lagradost.cloudstream3.utils.UIHelper.toPx
@ -27,13 +28,17 @@ class HomeChildItemAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val expanded = parent.context.IsBottomLayout()
/* val layout = if (bottom) R.layout.home_result_grid_expanded else R.layout.home_result_grid
/* val layout = if (bottom) R.layout.home_result_grid_expanded else R.layout.home_result_grid
val root = LayoutInflater.from(parent.context).inflate(layout, parent, false)
val binding = HomeResultGridBinding.bind(root)*/
val root = LayoutInflater.from(parent.context).inflate(layout, parent, false)
val binding = HomeResultGridBinding.bind(root)*/
val inflater = LayoutInflater.from(parent.context)
val binding = if(expanded) HomeResultGridExpandedBinding.inflate(inflater,parent,false) else HomeResultGridBinding.inflate(inflater,parent,false)
val binding = if (expanded) HomeResultGridExpandedBinding.inflate(
inflater,
parent,
false
) else HomeResultGridBinding.inflate(inflater, parent, false)
return CardViewHolder(
@ -42,7 +47,8 @@ class HomeChildItemAdapter(
itemCount,
nextFocusUp,
nextFocusDown,
isHorizontal
isHorizontal,
parent.isRtl()
)
}
@ -81,7 +87,8 @@ class HomeChildItemAdapter(
var itemCount: Int,
private val nextFocusUp: Int? = null,
private val nextFocusDown: Int? = null,
private val isHorizontal: Boolean = false
private val isHorizontal: Boolean = false,
private val isRtl : Boolean
) :
RecyclerView.ViewHolder(binding.root) {
@ -93,7 +100,23 @@ class HomeChildItemAdapter(
itemCount - 1 -> false
else -> null
}
when(binding) {
if (position == 0) { // to fix tv
if (isRtl) {
itemView.nextFocusRightId = R.id.nav_rail_view
itemView.nextFocusLeftId = -1
}
else {
itemView.nextFocusLeftId = R.id.nav_rail_view
itemView.nextFocusRightId = -1
}
} else {
itemView.nextFocusRightId = -1
itemView.nextFocusLeftId = -1
}
when (binding) {
is HomeResultGridBinding -> {
binding.backgroundCard.apply {
val min = 114.toPx
@ -114,10 +137,9 @@ class HomeChildItemAdapter(
}
}
if (position == 0) { // to fix tv
binding.backgroundCard.nextFocusLeftId = R.id.nav_rail_view
}
}
is HomeResultGridExpandedBinding -> {
binding.backgroundCard.apply {
val min = 114.toPx

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

@ -30,6 +30,7 @@ import com.lagradost.cloudstream3.ui.WatchType
import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.selectHomepage
import com.lagradost.cloudstream3.ui.result.ResultViewModel2
import com.lagradost.cloudstream3.ui.result.START_ACTION_RESUME_LATEST
import com.lagradost.cloudstream3.ui.result.setLinearListLayout
import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_LOAD
import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_SHOW_METADATA
import com.lagradost.cloudstream3.ui.search.SearchClickCallback
@ -427,6 +428,9 @@ class HomeParentItemAdapterPreview(
resumeRecyclerView.adapter = resumeAdapter
bookmarkRecyclerView.adapter = bookmarkAdapter
resumeRecyclerView.setLinearListLayout()
bookmarkRecyclerView.setLinearListLayout()
for ((chip, watch) in toggleList) {
chip.isChecked = false
chip.setOnCheckedChangeListener { _, isChecked ->

View File

@ -1,6 +1,7 @@
package com.lagradost.cloudstream3.ui.result
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.isVisible
import androidx.recyclerview.widget.DiffUtil
@ -11,7 +12,7 @@ import com.lagradost.cloudstream3.R
import com.lagradost.cloudstream3.databinding.CastItemBinding
import com.lagradost.cloudstream3.utils.UIHelper.setImage
class ActorAdaptor : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
class ActorAdaptor(private val focusCallback : (View?) -> Unit = {}) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
data class ActorMetaData(
var isInverted: Boolean,
val actor: ActorData,
@ -21,7 +22,7 @@ class ActorAdaptor : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return CardViewHolder(
CastItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
CastItemBinding.inflate(LayoutInflater.from(parent.context), parent, false), focusCallback
)
}
@ -66,6 +67,7 @@ class ActorAdaptor : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private class CardViewHolder
constructor(
val binding: CastItemBinding,
private val focusCallback : (View?) -> Unit = {}
) :
RecyclerView.ViewHolder(binding.root) {
@ -76,6 +78,12 @@ class ActorAdaptor : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
Pair(actor.voiceActor?.image, actor.actor.image)
}
itemView.setOnFocusChangeListener { v, hasFocus ->
if(hasFocus) {
focusCallback(v)
}
}
itemView.setOnClickListener {
callback(position)
}

View File

@ -2,19 +2,16 @@ 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?) :
@ -60,7 +57,7 @@ open class LinearListLayout(context: Context?) :
startSmoothScroll(linearSmoothScroller)
}*/
override fun onInterceptFocusSearch(focused: View, direction: Int): View? {
var dir = if (orientation == HORIZONTAL) {
val 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.
@ -70,19 +67,28 @@ open class LinearListLayout(context: Context?) :
(focused.parent as? RecyclerView)?.focusSearch(direction)
return null
}
if (direction == View.FOCUS_RIGHT) 1 else -1
var ret = if (direction == View.FOCUS_RIGHT) 1 else -1
// only flip on horizontal layout
if (this.isLayoutRTL) {
ret = -ret
}
ret
} else {
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 ->
val lookfor = dir + position
//clamp(dir + position, 0, recyclerView.adapter?.itemCount ?: return null)
// refocus on the same view if going out of bounds, note that we only do it
// for out of bounds one way as we may override the start where item == -1
if (lookfor >= itemCount) {
return getViewFromPos(itemCount - 1) ?: focused
}
getViewFromPos(lookfor) ?: run {
scrollToPosition(lookfor)
null

View File

@ -1,15 +1,12 @@
package com.lagradost.cloudstream3.ui.result
import android.animation.Animator
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.app.Dialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AlphaAnimation
import android.view.animation.Animation
import android.view.animation.DecelerateInterpolator
import androidx.appcompat.app.AlertDialog
import androidx.core.view.isGone
@ -31,20 +28,17 @@ 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
import com.lagradost.cloudstream3.ui.result.ResultFragment.updateUIEvent
import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_FOCUSED
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
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialog
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialogInstant
import com.lagradost.cloudstream3.utils.UIHelper
@ -52,10 +46,7 @@ import com.lagradost.cloudstream3.utils.UIHelper.colorFromAttribute
import com.lagradost.cloudstream3.utils.UIHelper.dismissSafe
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
import com.lagradost.cloudstream3.utils.UIHelper.navigate
import com.lagradost.cloudstream3.utils.UIHelper.popCurrentPage
import com.lagradost.cloudstream3.utils.UIHelper.setImage
import com.lagradost.cloudstream3.utils.UIHelper.setImageBlur
import kotlinx.coroutines.delay
class ResultFragmentTv : Fragment() {
protected lateinit var viewModel: ResultViewModel2
@ -204,7 +195,7 @@ class ResultFragmentTv : Fragment() {
}
})
}
this.animate().translationX(if (turnVisible) 0f else 100f).apply {
this.animate().translationX(if (turnVisible) 0f else if(isRtl()) -100.0f else 100f).apply {
duration = 200
interpolator = DecelerateInterpolator()
}
@ -214,6 +205,13 @@ class ResultFragmentTv : Fragment() {
binding?.apply {
episodesShadow.fade(show)
episodeHolderTv.fade(show)
if(episodesShadow.isRtl()) {
episodesShadow.scaleX = -1.0f
episodesShadow.scaleY = -1.0f
} else {
episodesShadow.scaleX = 1.0f
episodesShadow.scaleY = 1.0f
}
}
}
@ -238,6 +236,7 @@ class ResultFragmentTv : Fragment() {
// ===== ===== =====
binding?.apply {
//episodesShadow.rotationX = 180.0f//if(episodesShadow.isRtl()) 180.0f else 0.0f
val leftListener: View.OnFocusChangeListener =
View.OnFocusChangeListener { _, hasFocus ->
@ -264,6 +263,8 @@ class ResultFragmentTv : Fragment() {
toggleEpisodes(!episodeHolderTv.isVisible)
}
// resultEpisodes.onFocusChangeListener = leftListener
redirectToPlay.setOnFocusChangeListener { _, hasFocus ->
if (!hasFocus) return@setOnFocusChangeListener
toggleEpisodes(false)
@ -306,7 +307,7 @@ class ResultFragmentTv : Fragment() {
}
}
resultEpisodes.setLinearListLayout(false)/*.layoutManager =
resultEpisodes.setLinearListLayout(isHorizontal = false)/*.layoutManager =
LinearListLayout(resultEpisodes.context, resultEpisodes.isRtl()).apply {
setVertical()
}*/
@ -348,7 +349,10 @@ class ResultFragmentTv : Fragment() {
ArrayList(),
resultRecommendationsList,
) { callback ->
SearchHelper.handleSearchClickCallback(callback)
if(callback.action == SEARCH_ACTION_FOCUSED)
toggleEpisodes(false)
else
SearchHelper.handleSearchClickCallback(callback)
}
resultEpisodes.adapter =
@ -381,7 +385,9 @@ class ResultFragmentTv : Fragment() {
}.apply {
this.orientation = RecyclerView.HORIZONTAL
}
resultCastItems.adapter = ActorAdaptor()
resultCastItems.adapter = ActorAdaptor {
toggleEpisodes(false)
}
}
observeNullable(viewModel.resumeWatching) { resume ->

View File

@ -162,15 +162,42 @@ object SearchResultBuilder {
}
}
bg.setOnClickListener {
click(it)
bg.isFocusable = false
bg.isFocusableInTouchMode = false
if(!isTrueTvSettings()) {
bg.setOnClickListener {
click(it)
}
bg.setOnLongClickListener {
longClick(it)
return@setOnLongClickListener true
}
}
//
//
//
itemView.setOnClickListener {
click(it)
}
if (nextFocusUp != null) {
itemView.nextFocusUpId = nextFocusUp
}
if (nextFocusDown != null) {
itemView.nextFocusDownId = nextFocusDown
}
/*when (nextFocusBehavior) {
true -> itemView.nextFocusLeftId = bg.id
false -> itemView.nextFocusRightId = bg.id
null -> {
bg.nextFocusRightId = -1
bg.nextFocusLeftId = -1
}
}*/
/*if (nextFocusUp != null) {
bg.nextFocusUpId = nextFocusUp
}
@ -178,36 +205,26 @@ object SearchResultBuilder {
bg.nextFocusDownId = nextFocusDown
}
when (nextFocusBehavior) {
true -> bg.nextFocusLeftId = bg.id
false -> bg.nextFocusRightId = bg.id
null -> {
bg.nextFocusRightId = -1
bg.nextFocusLeftId = -1
}
}
*/
if (isTrueTvSettings()) {
bg.isFocusable = true
bg.isFocusableInTouchMode = true
bg.touchscreenBlocksFocus = false
// bg.isFocusable = true
// bg.isFocusableInTouchMode = true
// bg.touchscreenBlocksFocus = false
itemView.isFocusableInTouchMode = true
itemView.isFocusable = true
}
bg.setOnLongClickListener {
longClick(it)
return@setOnLongClickListener true
}
/**/
itemView.setOnLongClickListener {
longClick(it)
return@setOnLongClickListener true
}
bg.setOnFocusChangeListener { view, b ->
/*bg.setOnFocusChangeListener { view, b ->
focus(view, b)
}
}*/
itemView.setOnFocusChangeListener { view, b ->
focus(view, b)

View File

@ -3,6 +3,7 @@
android:viewportWidth="48"
android:viewportHeight="48"
android:tint="?attr/white"
android:autoMirrored="true"
xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M22,39.35 L7.95,25.3Q7.65,25.05 7.525,24.725Q7.4,24.4 7.4,24Q7.4,23.65 7.525,23.325Q7.65,23 7.95,22.75L22.05,8.6Q22.6,8.1 23.325,8.125Q24.05,8.15 24.6,8.7Q25.1,9.25 25.1,10Q25.1,10.75 24.55,11.3L13.65,22.2H38.1Q38.85,22.2 39.375,22.725Q39.9,23.25 39.9,24Q39.9,24.8 39.375,25.325Q38.85,25.85 38.1,25.85H13.65L24.65,36.8Q25.15,37.35 25.125,38.075Q25.1,38.8 24.55,39.35Q24,39.9 23.25,39.9Q22.5,39.9 22,39.35Z"/>
</vector>

View File

@ -1,5 +1,11 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="#FFFFFF" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M11.67,3.87L9.9,2.1 0,12l9.9,9.9 1.77,-1.77L3.54,12z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:autoMirrored="true"
android:tint="#FFFFFF"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M11.67,3.87L9.9,2.1 0,12l9.9,9.9 1.77,-1.77L3.54,12z" />
</vector>

View File

@ -3,6 +3,7 @@
android:viewportWidth="48"
android:viewportHeight="48"
android:tint="?attr/white"
android:autoMirrored="true"
xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M22.7,39.3Q22.15,38.75 22.175,38Q22.2,37.25 22.75,36.7L33.6,25.85H9.2Q8.45,25.85 7.925,25.325Q7.4,24.8 7.4,24Q7.4,23.25 7.925,22.725Q8.45,22.2 9.2,22.2H33.6L22.75,11.35Q22.2,10.8 22.175,10.025Q22.15,9.25 22.7,8.7Q23.25,8.15 24,8.15Q24.75,8.15 25.3,8.7L39.35,22.75Q39.65,23.05 39.8,23.35Q39.95,23.65 39.95,24Q39.95,24.35 39.8,24.675Q39.65,25 39.35,25.3L25.3,39.35Q24.75,39.9 24,39.875Q23.25,39.85 22.7,39.3Z"/>
</vector>

View File

@ -1,5 +1,11 @@
<vector android:autoMirrored="true" android:height="24dp"
android:tint="?attr/white" android:viewportHeight="24"
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M13.3,17.3 L8.7,12.7Q8.55,12.55 8.488,12.375Q8.425,12.2 8.425,12Q8.425,11.8 8.488,11.625Q8.55,11.45 8.7,11.3L13.3,6.7Q13.575,6.425 14,6.425Q14.425,6.425 14.7,6.7Q14.975,6.975 14.975,7.4Q14.975,7.825 14.7,8.1L10.8,12L14.7,15.9Q14.975,16.175 14.975,16.6Q14.975,17.025 14.7,17.3Q14.425,17.575 14,17.575Q13.575,17.575 13.3,17.3Z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:autoMirrored="true"
android:tint="?attr/white"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M13.3,17.3 L8.7,12.7Q8.55,12.55 8.488,12.375Q8.425,12.2 8.425,12Q8.425,11.8 8.488,11.625Q8.55,11.45 8.7,11.3L13.3,6.7Q13.575,6.425 14,6.425Q14.425,6.425 14.7,6.7Q14.975,6.975 14.975,7.4Q14.975,7.825 14.7,8.1L10.8,12L14.7,15.9Q14.975,16.175 14.975,16.6Q14.975,17.025 14.7,17.3Q14.425,17.575 14,17.575Q13.575,17.575 13.3,17.3Z" />
</vector>

View File

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="?attr/white"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM18.92,8h-2.95c-0.32,-1.25 -0.78,-2.45 -1.38,-3.56 1.84,0.63 3.37,1.91 4.33,3.56zM12,4.04c0.83,1.2 1.48,2.53 1.91,3.96h-3.82c0.43,-1.43 1.08,-2.76 1.91,-3.96zM4.26,14C4.1,13.36 4,12.69 4,12s0.1,-1.36 0.26,-2h3.38c-0.08,0.66 -0.14,1.32 -0.14,2 0,0.68 0.06,1.34 0.14,2L4.26,14zM5.08,16h2.95c0.32,1.25 0.78,2.45 1.38,3.56 -1.84,-0.63 -3.37,-1.9 -4.33,-3.56zM8.03,8L5.08,8c0.96,-1.66 2.49,-2.93 4.33,-3.56C8.81,5.55 8.35,6.75 8.03,8zM12,19.96c-0.83,-1.2 -1.48,-2.53 -1.91,-3.96h3.82c-0.43,1.43 -1.08,2.76 -1.91,3.96zM14.34,14L9.66,14c-0.09,-0.66 -0.16,-1.32 -0.16,-2 0,-0.68 0.07,-1.35 0.16,-2h4.68c0.09,0.65 0.16,1.32 0.16,2 0,0.68 -0.07,1.34 -0.16,2zM14.59,19.56c0.6,-1.11 1.06,-2.31 1.38,-3.56h2.95c-0.96,1.65 -2.49,2.93 -4.33,3.56zM16.36,14c0.08,-0.66 0.14,-1.32 0.14,-2 0,-0.68 -0.06,-1.34 -0.14,-2h3.38c0.16,0.64 0.26,1.31 0.26,2s-0.1,1.36 -0.26,2h-3.38z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/white"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM18.92,8h-2.95c-0.32,-1.25 -0.78,-2.45 -1.38,-3.56 1.84,0.63 3.37,1.91 4.33,3.56zM12,4.04c0.83,1.2 1.48,2.53 1.91,3.96h-3.82c0.43,-1.43 1.08,-2.76 1.91,-3.96zM4.26,14C4.1,13.36 4,12.69 4,12s0.1,-1.36 0.26,-2h3.38c-0.08,0.66 -0.14,1.32 -0.14,2 0,0.68 0.06,1.34 0.14,2L4.26,14zM5.08,16h2.95c0.32,1.25 0.78,2.45 1.38,3.56 -1.84,-0.63 -3.37,-1.9 -4.33,-3.56zM8.03,8L5.08,8c0.96,-1.66 2.49,-2.93 4.33,-3.56C8.81,5.55 8.35,6.75 8.03,8zM12,19.96c-0.83,-1.2 -1.48,-2.53 -1.91,-3.96h3.82c-0.43,1.43 -1.08,2.76 -1.91,3.96zM14.34,14L9.66,14c-0.09,-0.66 -0.16,-1.32 -0.16,-2 0,-0.68 0.07,-1.35 0.16,-2h4.68c0.09,0.65 0.16,1.32 0.16,2 0,0.68 -0.07,1.34 -0.16,2zM14.59,19.56c0.6,-1.11 1.06,-2.31 1.38,-3.56h2.95c-0.96,1.65 -2.49,2.93 -4.33,3.56zM16.36,14c0.08,-0.66 0.14,-1.32 0.14,-2 0,-0.68 -0.06,-1.34 -0.14,-2h3.38c0.16,0.64 0.26,1.31 0.26,2s-0.1,1.36 -0.26,2h-3.38z" />
</vector>

View File

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="?attr/white"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/white"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,8c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM12,10c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2zM12,16c-1.1,0 -2,0.9 -2,2s0.9,2 2,2 2,-0.9 2,-2 -0.9,-2 -2,-2z" />
</vector>

View File

@ -1,5 +1,10 @@
<vector android:height="24dp" android:tint="?attr/white"
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M7.58,4.08L6.15,2.65C3.75,4.48 2.17,7.3 2.03,10.5h2c0.15,-2.65 1.51,-4.97 3.55,-6.42zM19.97,10.5h2c-0.15,-3.2 -1.73,-6.02 -4.12,-7.85l-1.42,1.43c2.02,1.45 3.39,3.77 3.54,6.42zM18,11c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2v-5zM12,22c0.14,0 0.27,-0.01 0.4,-0.04 0.65,-0.14 1.18,-0.58 1.44,-1.18 0.1,-0.24 0.15,-0.5 0.15,-0.78h-4c0.01,1.1 0.9,2 2.01,2z"/>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/white"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M7.58,4.08L6.15,2.65C3.75,4.48 2.17,7.3 2.03,10.5h2c0.15,-2.65 1.51,-4.97 3.55,-6.42zM19.97,10.5h2c-0.15,-3.2 -1.73,-6.02 -4.12,-7.85l-1.42,1.43c2.02,1.45 3.39,3.77 3.54,6.42zM18,11c0,-3.07 -1.64,-5.64 -4.5,-6.32L13.5,4c0,-0.83 -0.67,-1.5 -1.5,-1.5s-1.5,0.67 -1.5,1.5v0.68C7.63,5.36 6,7.92 6,11v5l-2,2v1h16v-1l-2,-2v-5zM12,22c0.14,0 0.27,-0.01 0.4,-0.04 0.65,-0.14 1.18,-0.58 1.44,-1.18 0.1,-0.24 0.15,-0.5 0.15,-0.78h-4c0.01,1.1 0.9,2 2.01,2z" />
</vector>

View File

@ -1,23 +1,23 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="850.39dp"
android:height="850.39dp"
android:viewportWidth="850.39"
android:viewportHeight="850.39">
android:width="850.39dp"
android:height="850.39dp"
android:viewportWidth="850.39"
android:viewportHeight="850.39">
<path
android:pathData="M143.05,279.28A317.41,317.41 0,0 0,106.3 428c0,176.13 142.77,318.9 318.9,318.9S744.09,604.16 744.09,428 601.32,109.14 425.2,109.14q-14.15,0 -28,1.2"
android:strokeWidth="45"
android:fillColor="#00000000"
android:strokeColor="#fff"/>
android:fillColor="#00000000"
android:pathData="M143.05,279.28A317.41,317.41 0,0 0,106.3 428c0,176.13 142.77,318.9 318.9,318.9S744.09,604.16 744.09,428 601.32,109.14 425.2,109.14q-14.15,0 -28,1.2"
android:strokeWidth="45"
android:strokeColor="#fff" />
<path
android:pathData="M483.083,223.108l-111.666,-111.666l25.442,-25.442l111.666,111.666z"
android:fillColor="#fff"/>
android:fillColor="#fff"
android:pathData="M483.083,223.108l-111.666,-111.666l25.442,-25.442l111.666,111.666z" />
<path
android:pathData="M371.421,111.662l111.666,-111.666l25.442,25.442l-111.666,111.666z"
android:fillColor="#fff"/>
android:fillColor="#fff"
android:pathData="M371.421,111.662l111.666,-111.666l25.442,25.442l-111.666,111.666z" />
<path
android:pathData="M398.087,223.272l-111.666,-111.666l25.442,-25.442l111.666,111.666z"
android:fillColor="#fff"/>
android:fillColor="#fff"
android:pathData="M398.087,223.272l-111.666,-111.666l25.442,-25.442l111.666,111.666z" />
<path
android:pathData="M286.427,111.826l111.666,-111.666l25.442,25.442l-111.666,111.666z"
android:fillColor="#fff"/>
android:fillColor="#fff"
android:pathData="M286.427,111.826l111.666,-111.666l25.442,25.442l-111.666,111.666z" />
</vector>

View File

@ -0,0 +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"/> <!-- focused -->
</selector>

View File

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

View File

@ -98,7 +98,7 @@
android:nextFocusLeft="@id/home_preview_hidden_prev_focus"
android:nextFocusRight="@id/home_preview_info_btt"
android:nextFocusUp="@id/home_preview_change_api"
android:nextFocusDown="@id/home_watch_parent_item_title"
android:nextFocusDown="@id/home_watch_child_recyclerview"
android:text="@string/home_play"
app:icon="@drawable/ic_baseline_play_arrow_24" />
@ -111,7 +111,7 @@
android:nextFocusLeft="@id/home_preview_play_btt"
android:nextFocusRight="@id/home_preview_hidden_next_focus"
android:nextFocusUp="@id/home_preview_change_api"
android:nextFocusDown="@id/home_watch_parent_item_title"
android:nextFocusDown="@id/home_watch_child_recyclerview"
android:text="@string/home_info"
app:icon="@drawable/ic_outline_info_24" />

View File

@ -537,6 +537,7 @@ https://developer.android.com/design/ui/tv/samples/jet-fit
</androidx.core.widget.NestedScrollView>
<ImageView
android:layout_gravity="end"
android:id="@+id/episodes_shadow"
android:layout_width="match_parent"
android:layout_height="match_parent"
@ -553,7 +554,7 @@ https://developer.android.com/design/ui/tv/samples/jet-fit
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:layout_gravity="end"
android:orientation="horizontal"
android:paddingStart="@dimen/result_padding"
android:paddingEnd="@dimen/result_padding"

View File

@ -14,9 +14,9 @@
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
style="@style/NoCheckLabel"
tools:text="hello"
android:textStyle="normal"
android:textColor="?attr/textColor"
android:id="@android:id/text1" />
xmlns:tools="http://schemas.android.com/tools"
android:id="@android:id/text1"
style="@style/NoCheckLabel"
android:textColor="?attr/textColor"
android:textStyle="normal"
tools:text="hello" />