mirror of
https://github.com/recloudstream/cloudstream.git
synced 2024-08-15 01:53:11 +00:00
major focus fixes
This commit is contained in:
parent
c98f35fd94
commit
c987f7581e
22 changed files with 268 additions and 139 deletions
|
@ -27,6 +27,7 @@ import com.lagradost.cloudstream3.ui.player.PlayerEventType
|
||||||
import com.lagradost.cloudstream3.ui.result.ResultFragment
|
import com.lagradost.cloudstream3.ui.result.ResultFragment
|
||||||
import com.lagradost.cloudstream3.ui.result.UiText
|
import com.lagradost.cloudstream3.ui.result.UiText
|
||||||
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.updateTv
|
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.DataStoreHelper
|
||||||
import com.lagradost.cloudstream3.utils.Event
|
import com.lagradost.cloudstream3.utils.Event
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper
|
import com.lagradost.cloudstream3.utils.UIHelper
|
||||||
|
@ -299,22 +300,29 @@ object CommonActivity {
|
||||||
view: View?,
|
view: View?,
|
||||||
direction: FocusDirection,
|
direction: FocusDirection,
|
||||||
depth: Int = 0
|
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) {
|
if (view == null || depth >= 10 || act == null) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
val nextId = when (direction) {
|
val nextId = when (direction) {
|
||||||
FocusDirection.Left -> {
|
FocusDirection.Start -> {
|
||||||
view.nextFocusLeftId
|
if (view.isRtl())
|
||||||
|
view.nextFocusRightId
|
||||||
|
else
|
||||||
|
view.nextFocusLeftId
|
||||||
}
|
}
|
||||||
|
|
||||||
FocusDirection.Up -> {
|
FocusDirection.Up -> {
|
||||||
view.nextFocusUpId
|
view.nextFocusUpId
|
||||||
}
|
}
|
||||||
|
|
||||||
FocusDirection.Right -> {
|
FocusDirection.End -> {
|
||||||
view.nextFocusRightId
|
if (view.isRtl())
|
||||||
|
view.nextFocusLeftId
|
||||||
|
else
|
||||||
|
view.nextFocusRightId
|
||||||
}
|
}
|
||||||
|
|
||||||
FocusDirection.Down -> {
|
FocusDirection.Down -> {
|
||||||
|
@ -322,27 +330,41 @@ object CommonActivity {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (nextId != -1) {
|
// if view not found then return
|
||||||
val next = act.findViewById<View?>(nextId)
|
if (nextId == -1) return null
|
||||||
//println("NAME: ${next.accessibilityClassName} | ${next?.isShown}" )
|
var next = act.findViewById<View?>(nextId) ?: return null
|
||||||
|
|
||||||
if (next?.isShown == false) {
|
// because we want closes find, aka when multiple have the same id, we go to parent
|
||||||
getNextFocus(act, next, direction, depth + 1)
|
// until the correct one is found
|
||||||
} else {
|
/*var currentLook: View = view
|
||||||
if (depth == 0) {
|
while (true) {
|
||||||
null
|
val tmpNext = currentLook.findViewById<View?>(nextId)
|
||||||
} else {
|
if (tmpNext != null) {
|
||||||
nextId
|
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 {
|
enum class FocusDirection {
|
||||||
Left,
|
Start,
|
||||||
Right,
|
End,
|
||||||
Up,
|
Up,
|
||||||
Down,
|
Down,
|
||||||
}
|
}
|
||||||
|
@ -447,17 +469,17 @@ object CommonActivity {
|
||||||
|
|
||||||
event?.keyCode?.let { keyCode ->
|
event?.keyCode?.let { keyCode ->
|
||||||
if (currentFocus == null || event.action != KeyEvent.ACTION_DOWN) return@let
|
if (currentFocus == null || event.action != KeyEvent.ACTION_DOWN) return@let
|
||||||
val next = when (keyCode) {
|
val nextView = when (keyCode) {
|
||||||
KeyEvent.KEYCODE_DPAD_LEFT -> getNextFocus(
|
KeyEvent.KEYCODE_DPAD_LEFT -> getNextFocus(
|
||||||
act,
|
act,
|
||||||
currentFocus,
|
currentFocus,
|
||||||
FocusDirection.Left
|
FocusDirection.Start
|
||||||
)
|
)
|
||||||
|
|
||||||
KeyEvent.KEYCODE_DPAD_RIGHT -> getNextFocus(
|
KeyEvent.KEYCODE_DPAD_RIGHT -> getNextFocus(
|
||||||
act,
|
act,
|
||||||
currentFocus,
|
currentFocus,
|
||||||
FocusDirection.Right
|
FocusDirection.End
|
||||||
)
|
)
|
||||||
|
|
||||||
KeyEvent.KEYCODE_DPAD_UP -> getNextFocus(
|
KeyEvent.KEYCODE_DPAD_UP -> getNextFocus(
|
||||||
|
@ -475,13 +497,10 @@ object CommonActivity {
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
if (next != null && next != -1) {
|
if (nextView != null) {
|
||||||
val nextView = act.findViewById<View?>(next)
|
nextView.requestFocus()
|
||||||
if (nextView != null) {
|
keyEventListener?.invoke(Pair(event, true))
|
||||||
nextView.requestFocus()
|
return true
|
||||||
keyEventListener?.invoke(Pair(event, true))
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER && (act.currentFocus is SearchView || act.currentFocus is SearchView.SearchAutoComplete)) {
|
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER && (act.currentFocus is SearchView || act.currentFocus is SearchView.SearchAutoComplete)) {
|
||||||
|
|
|
@ -24,7 +24,7 @@ class GrdLayoutManager(val context: Context, _spanCount: Int) :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onRequestChildFocus(
|
/*override fun onRequestChildFocus(
|
||||||
parent: RecyclerView,
|
parent: RecyclerView,
|
||||||
state: RecyclerView.State,
|
state: RecyclerView.State,
|
||||||
child: View,
|
child: View,
|
||||||
|
@ -32,13 +32,17 @@ class GrdLayoutManager(val context: Context, _spanCount: Int) :
|
||||||
): Boolean {
|
): Boolean {
|
||||||
// android.widget.FrameLayout$LayoutParams cannot be cast to androidx.recyclerview.widget.RecyclerView$LayoutParams
|
// android.widget.FrameLayout$LayoutParams cannot be cast to androidx.recyclerview.widget.RecyclerView$LayoutParams
|
||||||
return try {
|
return try {
|
||||||
val pos = maxOf(0, getPosition(focused!!) - 2)
|
if(focused != null) {
|
||||||
parent.scrollToPosition(pos)
|
// 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)
|
super.onRequestChildFocus(parent, state, child, focused)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// Allows moving right and left with focus https://gist.github.com/vganin/8930b41f55820ec49e4d
|
// Allows moving right and left with focus https://gist.github.com/vganin/8930b41f55820ec49e4d
|
||||||
override fun onInterceptFocusSearch(focused: View, direction: Int): View? {
|
override fun onInterceptFocusSearch(focused: View, direction: Int): View? {
|
||||||
|
@ -65,8 +69,17 @@ class GrdLayoutManager(val context: Context, _spanCount: Int) :
|
||||||
val spanCount = this.spanCount
|
val spanCount = this.spanCount
|
||||||
val orientation = this.orientation
|
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) {
|
if (orientation == VERTICAL) {
|
||||||
when (direction) {
|
when (correctDirection) {
|
||||||
View.FOCUS_DOWN -> {
|
View.FOCUS_DOWN -> {
|
||||||
return spanCount
|
return spanCount
|
||||||
}
|
}
|
||||||
|
@ -81,7 +94,7 @@ class GrdLayoutManager(val context: Context, _spanCount: Int) :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (orientation == HORIZONTAL) {
|
} else if (orientation == HORIZONTAL) {
|
||||||
when (direction) {
|
when (correctDirection) {
|
||||||
View.FOCUS_DOWN -> {
|
View.FOCUS_DOWN -> {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import com.lagradost.cloudstream3.databinding.HomeResultGridBinding
|
||||||
import com.lagradost.cloudstream3.databinding.HomeResultGridExpandedBinding
|
import com.lagradost.cloudstream3.databinding.HomeResultGridExpandedBinding
|
||||||
import com.lagradost.cloudstream3.ui.search.SearchClickCallback
|
import com.lagradost.cloudstream3.ui.search.SearchClickCallback
|
||||||
import com.lagradost.cloudstream3.ui.search.SearchResultBuilder
|
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.IsBottomLayout
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.toPx
|
import com.lagradost.cloudstream3.utils.UIHelper.toPx
|
||||||
|
|
||||||
|
@ -27,13 +28,17 @@ class HomeChildItemAdapter(
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
val expanded = parent.context.IsBottomLayout()
|
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 root = LayoutInflater.from(parent.context).inflate(layout, parent, false)
|
||||||
val binding = HomeResultGridBinding.bind(root)*/
|
val binding = HomeResultGridBinding.bind(root)*/
|
||||||
|
|
||||||
val inflater = LayoutInflater.from(parent.context)
|
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(
|
return CardViewHolder(
|
||||||
|
@ -42,7 +47,8 @@ class HomeChildItemAdapter(
|
||||||
itemCount,
|
itemCount,
|
||||||
nextFocusUp,
|
nextFocusUp,
|
||||||
nextFocusDown,
|
nextFocusDown,
|
||||||
isHorizontal
|
isHorizontal,
|
||||||
|
parent.isRtl()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +87,8 @@ class HomeChildItemAdapter(
|
||||||
var itemCount: Int,
|
var itemCount: Int,
|
||||||
private val nextFocusUp: Int? = null,
|
private val nextFocusUp: Int? = null,
|
||||||
private val nextFocusDown: 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) {
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
|
@ -93,7 +100,23 @@ class HomeChildItemAdapter(
|
||||||
itemCount - 1 -> false
|
itemCount - 1 -> false
|
||||||
else -> null
|
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 -> {
|
is HomeResultGridBinding -> {
|
||||||
binding.backgroundCard.apply {
|
binding.backgroundCard.apply {
|
||||||
val min = 114.toPx
|
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 -> {
|
is HomeResultGridExpandedBinding -> {
|
||||||
binding.backgroundCard.apply {
|
binding.backgroundCard.apply {
|
||||||
val min = 114.toPx
|
val min = 114.toPx
|
||||||
|
|
|
@ -177,7 +177,7 @@ open class ParentItemAdapter(
|
||||||
).apply {
|
).apply {
|
||||||
isHorizontal = info.isHorizontalImages
|
isHorizontal = info.isHorizontalImages
|
||||||
}
|
}
|
||||||
//recyclerView.setLinearListLayout()
|
recyclerView.setLinearListLayout()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +192,7 @@ open class ParentItemAdapter(
|
||||||
isHorizontal = info.isHorizontalImages
|
isHorizontal = info.isHorizontalImages
|
||||||
hasNext = expand.hasNext
|
hasNext = expand.hasNext
|
||||||
}
|
}
|
||||||
// recyclerView.setLinearListLayout()
|
recyclerView.setLinearListLayout()
|
||||||
title.text = info.name
|
title.text = info.name
|
||||||
|
|
||||||
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||||
|
|
|
@ -30,6 +30,7 @@ import com.lagradost.cloudstream3.ui.WatchType
|
||||||
import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.selectHomepage
|
import com.lagradost.cloudstream3.ui.home.HomeFragment.Companion.selectHomepage
|
||||||
import com.lagradost.cloudstream3.ui.result.ResultViewModel2
|
import com.lagradost.cloudstream3.ui.result.ResultViewModel2
|
||||||
import com.lagradost.cloudstream3.ui.result.START_ACTION_RESUME_LATEST
|
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_LOAD
|
||||||
import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_SHOW_METADATA
|
import com.lagradost.cloudstream3.ui.search.SEARCH_ACTION_SHOW_METADATA
|
||||||
import com.lagradost.cloudstream3.ui.search.SearchClickCallback
|
import com.lagradost.cloudstream3.ui.search.SearchClickCallback
|
||||||
|
@ -427,6 +428,9 @@ class HomeParentItemAdapterPreview(
|
||||||
resumeRecyclerView.adapter = resumeAdapter
|
resumeRecyclerView.adapter = resumeAdapter
|
||||||
bookmarkRecyclerView.adapter = bookmarkAdapter
|
bookmarkRecyclerView.adapter = bookmarkAdapter
|
||||||
|
|
||||||
|
resumeRecyclerView.setLinearListLayout()
|
||||||
|
bookmarkRecyclerView.setLinearListLayout()
|
||||||
|
|
||||||
for ((chip, watch) in toggleList) {
|
for ((chip, watch) in toggleList) {
|
||||||
chip.isChecked = false
|
chip.isChecked = false
|
||||||
chip.setOnCheckedChangeListener { _, isChecked ->
|
chip.setOnCheckedChangeListener { _, isChecked ->
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package com.lagradost.cloudstream3.ui.result
|
package com.lagradost.cloudstream3.ui.result
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
import androidx.recyclerview.widget.DiffUtil
|
||||||
|
@ -11,7 +12,7 @@ import com.lagradost.cloudstream3.R
|
||||||
import com.lagradost.cloudstream3.databinding.CastItemBinding
|
import com.lagradost.cloudstream3.databinding.CastItemBinding
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.setImage
|
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(
|
data class ActorMetaData(
|
||||||
var isInverted: Boolean,
|
var isInverted: Boolean,
|
||||||
val actor: ActorData,
|
val actor: ActorData,
|
||||||
|
@ -21,7 +22,7 @@ class ActorAdaptor : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
|
||||||
return CardViewHolder(
|
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
|
private class CardViewHolder
|
||||||
constructor(
|
constructor(
|
||||||
val binding: CastItemBinding,
|
val binding: CastItemBinding,
|
||||||
|
private val focusCallback : (View?) -> Unit = {}
|
||||||
) :
|
) :
|
||||||
RecyclerView.ViewHolder(binding.root) {
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
|
@ -76,6 +78,12 @@ class ActorAdaptor : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
|
||||||
Pair(actor.voiceActor?.image, actor.actor.image)
|
Pair(actor.voiceActor?.image, actor.actor.image)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
itemView.setOnFocusChangeListener { v, hasFocus ->
|
||||||
|
if(hasFocus) {
|
||||||
|
focusCallback(v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
itemView.setOnClickListener {
|
itemView.setOnClickListener {
|
||||||
callback(position)
|
callback(position)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,19 +2,16 @@ package com.lagradost.cloudstream3.ui.result
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.View.LAYOUT_DIRECTION_LTR
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.lagradost.cloudstream3.mvvm.logError
|
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) {
|
fun RecyclerView?.setLinearListLayout(isHorizontal: Boolean = true) {
|
||||||
if (this == null) return
|
if (this == null) return
|
||||||
|
|
||||||
this.layoutManager =
|
this.layoutManager =
|
||||||
this.context?.let { LinearListLayout(it).apply { if (isHorizontal) setHorizontal() else setVertical() } }
|
this.context?.let { LinearListLayout(it).apply { if (isHorizontal) setHorizontal() else setVertical() } }
|
||||||
// ?: this.layoutManager
|
// ?: this.layoutManager
|
||||||
}
|
}
|
||||||
|
|
||||||
open class LinearListLayout(context: Context?) :
|
open class LinearListLayout(context: Context?) :
|
||||||
|
@ -60,7 +57,7 @@ open class LinearListLayout(context: Context?) :
|
||||||
startSmoothScroll(linearSmoothScroller)
|
startSmoothScroll(linearSmoothScroller)
|
||||||
}*/
|
}*/
|
||||||
override fun onInterceptFocusSearch(focused: View, direction: Int): View? {
|
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) {
|
if (direction == View.FOCUS_DOWN || direction == View.FOCUS_UP) {
|
||||||
// This scrolls the recyclerview before doing focus search, which
|
// This scrolls the recyclerview before doing focus search, which
|
||||||
// allows the focus search to work better.
|
// allows the focus search to work better.
|
||||||
|
@ -70,19 +67,28 @@ open class LinearListLayout(context: Context?) :
|
||||||
(focused.parent as? RecyclerView)?.focusSearch(direction)
|
(focused.parent as? RecyclerView)?.focusSearch(direction)
|
||||||
return null
|
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 {
|
} else {
|
||||||
if (direction == View.FOCUS_RIGHT || direction == View.FOCUS_LEFT) return null
|
if (direction == View.FOCUS_RIGHT || direction == View.FOCUS_LEFT) return null
|
||||||
if (direction == View.FOCUS_DOWN) 1 else -1
|
if (direction == View.FOCUS_DOWN) 1 else -1
|
||||||
}
|
}
|
||||||
if(this.isLayoutRTL) {
|
|
||||||
dir = -dir
|
|
||||||
}
|
|
||||||
|
|
||||||
return try {
|
return try {
|
||||||
getPosition(getCorrectParent(focused))?.let { position ->
|
getPosition(getCorrectParent(focused))?.let { position ->
|
||||||
val lookfor = dir + position
|
val lookfor = dir + position
|
||||||
//clamp(dir + position, 0, recyclerView.adapter?.itemCount ?: return null)
|
//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 {
|
getViewFromPos(lookfor) ?: run {
|
||||||
scrollToPosition(lookfor)
|
scrollToPosition(lookfor)
|
||||||
null
|
null
|
||||||
|
|
|
@ -1,15 +1,12 @@
|
||||||
package com.lagradost.cloudstream3.ui.result
|
package com.lagradost.cloudstream3.ui.result
|
||||||
|
|
||||||
import android.animation.Animator
|
import android.animation.Animator
|
||||||
import android.animation.ObjectAnimator
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
import android.app.Dialog
|
import android.app.Dialog
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.view.animation.AlphaAnimation
|
|
||||||
import android.view.animation.Animation
|
|
||||||
import android.view.animation.DecelerateInterpolator
|
import android.view.animation.DecelerateInterpolator
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.view.isGone
|
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.mvvm.observeNullable
|
||||||
import com.lagradost.cloudstream3.ui.WatchType
|
import com.lagradost.cloudstream3.ui.WatchType
|
||||||
import com.lagradost.cloudstream3.ui.download.DownloadButtonSetup
|
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.ExtractorLinkGenerator
|
||||||
import com.lagradost.cloudstream3.ui.player.GeneratorPlayer
|
import com.lagradost.cloudstream3.ui.player.GeneratorPlayer
|
||||||
import com.lagradost.cloudstream3.ui.result.ResultFragment.getStoredData
|
import com.lagradost.cloudstream3.ui.result.ResultFragment.getStoredData
|
||||||
import com.lagradost.cloudstream3.ui.result.ResultFragment.updateUIEvent
|
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.SearchAdapter
|
||||||
import com.lagradost.cloudstream3.ui.search.SearchHelper
|
import com.lagradost.cloudstream3.ui.search.SearchHelper
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.getNameFull
|
import com.lagradost.cloudstream3.utils.AppUtils.getNameFull
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.html
|
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.isRtl
|
||||||
import com.lagradost.cloudstream3.utils.AppUtils.loadCache
|
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.showBottomDialog
|
||||||
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialogInstant
|
import com.lagradost.cloudstream3.utils.SingleSelectionHelper.showBottomDialogInstant
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper
|
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.dismissSafe
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
|
import com.lagradost.cloudstream3.utils.UIHelper.hideKeyboard
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.navigate
|
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.setImage
|
||||||
import com.lagradost.cloudstream3.utils.UIHelper.setImageBlur
|
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
|
|
||||||
class ResultFragmentTv : Fragment() {
|
class ResultFragmentTv : Fragment() {
|
||||||
protected lateinit var viewModel: ResultViewModel2
|
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
|
duration = 200
|
||||||
interpolator = DecelerateInterpolator()
|
interpolator = DecelerateInterpolator()
|
||||||
}
|
}
|
||||||
|
@ -214,6 +205,13 @@ class ResultFragmentTv : Fragment() {
|
||||||
binding?.apply {
|
binding?.apply {
|
||||||
episodesShadow.fade(show)
|
episodesShadow.fade(show)
|
||||||
episodeHolderTv.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 {
|
binding?.apply {
|
||||||
|
//episodesShadow.rotationX = 180.0f//if(episodesShadow.isRtl()) 180.0f else 0.0f
|
||||||
|
|
||||||
val leftListener: View.OnFocusChangeListener =
|
val leftListener: View.OnFocusChangeListener =
|
||||||
View.OnFocusChangeListener { _, hasFocus ->
|
View.OnFocusChangeListener { _, hasFocus ->
|
||||||
|
@ -264,6 +263,8 @@ class ResultFragmentTv : Fragment() {
|
||||||
toggleEpisodes(!episodeHolderTv.isVisible)
|
toggleEpisodes(!episodeHolderTv.isVisible)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resultEpisodes.onFocusChangeListener = leftListener
|
||||||
|
|
||||||
redirectToPlay.setOnFocusChangeListener { _, hasFocus ->
|
redirectToPlay.setOnFocusChangeListener { _, hasFocus ->
|
||||||
if (!hasFocus) return@setOnFocusChangeListener
|
if (!hasFocus) return@setOnFocusChangeListener
|
||||||
toggleEpisodes(false)
|
toggleEpisodes(false)
|
||||||
|
@ -306,7 +307,7 @@ class ResultFragmentTv : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resultEpisodes.setLinearListLayout(false)/*.layoutManager =
|
resultEpisodes.setLinearListLayout(isHorizontal = false)/*.layoutManager =
|
||||||
LinearListLayout(resultEpisodes.context, resultEpisodes.isRtl()).apply {
|
LinearListLayout(resultEpisodes.context, resultEpisodes.isRtl()).apply {
|
||||||
setVertical()
|
setVertical()
|
||||||
}*/
|
}*/
|
||||||
|
@ -348,7 +349,10 @@ class ResultFragmentTv : Fragment() {
|
||||||
ArrayList(),
|
ArrayList(),
|
||||||
resultRecommendationsList,
|
resultRecommendationsList,
|
||||||
) { callback ->
|
) { callback ->
|
||||||
SearchHelper.handleSearchClickCallback(callback)
|
if(callback.action == SEARCH_ACTION_FOCUSED)
|
||||||
|
toggleEpisodes(false)
|
||||||
|
else
|
||||||
|
SearchHelper.handleSearchClickCallback(callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
resultEpisodes.adapter =
|
resultEpisodes.adapter =
|
||||||
|
@ -381,7 +385,9 @@ class ResultFragmentTv : Fragment() {
|
||||||
}.apply {
|
}.apply {
|
||||||
this.orientation = RecyclerView.HORIZONTAL
|
this.orientation = RecyclerView.HORIZONTAL
|
||||||
}
|
}
|
||||||
resultCastItems.adapter = ActorAdaptor()
|
resultCastItems.adapter = ActorAdaptor {
|
||||||
|
toggleEpisodes(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
observeNullable(viewModel.resumeWatching) { resume ->
|
observeNullable(viewModel.resumeWatching) { resume ->
|
||||||
|
|
|
@ -162,15 +162,42 @@ object SearchResultBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bg.setOnClickListener {
|
bg.isFocusable = false
|
||||||
click(it)
|
bg.isFocusableInTouchMode = false
|
||||||
|
if(!isTrueTvSettings()) {
|
||||||
|
bg.setOnClickListener {
|
||||||
|
click(it)
|
||||||
|
}
|
||||||
|
bg.setOnLongClickListener {
|
||||||
|
longClick(it)
|
||||||
|
return@setOnLongClickListener true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
itemView.setOnClickListener {
|
itemView.setOnClickListener {
|
||||||
click(it)
|
click(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextFocusUp != null) {
|
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
|
bg.nextFocusUpId = nextFocusUp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,36 +205,26 @@ object SearchResultBuilder {
|
||||||
bg.nextFocusDownId = nextFocusDown
|
bg.nextFocusDownId = nextFocusDown
|
||||||
}
|
}
|
||||||
|
|
||||||
when (nextFocusBehavior) {
|
*/
|
||||||
true -> bg.nextFocusLeftId = bg.id
|
|
||||||
false -> bg.nextFocusRightId = bg.id
|
|
||||||
null -> {
|
|
||||||
bg.nextFocusRightId = -1
|
|
||||||
bg.nextFocusLeftId = -1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isTrueTvSettings()) {
|
if (isTrueTvSettings()) {
|
||||||
bg.isFocusable = true
|
// bg.isFocusable = true
|
||||||
bg.isFocusableInTouchMode = true
|
// bg.isFocusableInTouchMode = true
|
||||||
bg.touchscreenBlocksFocus = false
|
// bg.touchscreenBlocksFocus = false
|
||||||
itemView.isFocusableInTouchMode = true
|
itemView.isFocusableInTouchMode = true
|
||||||
itemView.isFocusable = true
|
itemView.isFocusable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
bg.setOnLongClickListener {
|
/**/
|
||||||
longClick(it)
|
|
||||||
return@setOnLongClickListener true
|
|
||||||
}
|
|
||||||
|
|
||||||
itemView.setOnLongClickListener {
|
itemView.setOnLongClickListener {
|
||||||
longClick(it)
|
longClick(it)
|
||||||
return@setOnLongClickListener true
|
return@setOnLongClickListener true
|
||||||
}
|
}
|
||||||
|
|
||||||
bg.setOnFocusChangeListener { view, b ->
|
/*bg.setOnFocusChangeListener { view, b ->
|
||||||
focus(view, b)
|
focus(view, b)
|
||||||
}
|
}*/
|
||||||
|
|
||||||
itemView.setOnFocusChangeListener { view, b ->
|
itemView.setOnFocusChangeListener { view, b ->
|
||||||
focus(view, b)
|
focus(view, b)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
android:viewportWidth="48"
|
android:viewportWidth="48"
|
||||||
android:viewportHeight="48"
|
android:viewportHeight="48"
|
||||||
android:tint="?attr/white"
|
android:tint="?attr/white"
|
||||||
|
android:autoMirrored="true"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
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"/>
|
<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>
|
</vector>
|
|
@ -1,5 +1,11 @@
|
||||||
<vector android:autoMirrored="true" android:height="24dp"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:tint="#FFFFFF" android:viewportHeight="24"
|
android:width="24dp"
|
||||||
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:height="24dp"
|
||||||
<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"/>
|
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>
|
</vector>
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
android:viewportWidth="48"
|
android:viewportWidth="48"
|
||||||
android:viewportHeight="48"
|
android:viewportHeight="48"
|
||||||
android:tint="?attr/white"
|
android:tint="?attr/white"
|
||||||
|
android:autoMirrored="true"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
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"/>
|
<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>
|
</vector>
|
|
@ -1,5 +1,11 @@
|
||||||
<vector android:autoMirrored="true" android:height="24dp"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:tint="?attr/white" android:viewportHeight="24"
|
android:width="24dp"
|
||||||
android:viewportWidth="24" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:height="24dp"
|
||||||
<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"/>
|
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>
|
</vector>
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
<vector android:height="24dp" android:tint="?attr/white"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
android:width="24dp"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:height="24dp"
|
||||||
<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"/>
|
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>
|
</vector>
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
<vector android:height="24dp" android:tint="?attr/white"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
android:width="24dp"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:height="24dp"
|
||||||
<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"/>
|
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>
|
</vector>
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
<vector android:height="24dp" android:tint="?attr/white"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:viewportHeight="24" android:viewportWidth="24"
|
android:width="24dp"
|
||||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
android:height="24dp"
|
||||||
<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"/>
|
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>
|
</vector>
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="850.39dp"
|
android:width="850.39dp"
|
||||||
android:height="850.39dp"
|
android:height="850.39dp"
|
||||||
android:viewportWidth="850.39"
|
android:viewportWidth="850.39"
|
||||||
android:viewportHeight="850.39">
|
android:viewportHeight="850.39">
|
||||||
<path
|
<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:fillColor="#00000000"
|
||||||
android:strokeWidth="45"
|
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:fillColor="#00000000"
|
android:strokeWidth="45"
|
||||||
android:strokeColor="#fff"/>
|
android:strokeColor="#fff" />
|
||||||
<path
|
<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
|
<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
|
<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
|
<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>
|
</vector>
|
5
app/src/main/res/drawable/outline_drawable_forced.xml
Normal file
5
app/src/main/res/drawable/outline_drawable_forced.xml
Normal 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>
|
|
@ -83,7 +83,6 @@
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:elevation="999999999dp"
|
|
||||||
android:focusable="false"
|
android:focusable="false"
|
||||||
android:focusableInTouchMode="false"
|
android:focusableInTouchMode="false"
|
||||||
android:clickable="false"
|
android:clickable="false"
|
||||||
|
|
|
@ -98,7 +98,7 @@
|
||||||
android:nextFocusLeft="@id/home_preview_hidden_prev_focus"
|
android:nextFocusLeft="@id/home_preview_hidden_prev_focus"
|
||||||
android:nextFocusRight="@id/home_preview_info_btt"
|
android:nextFocusRight="@id/home_preview_info_btt"
|
||||||
android:nextFocusUp="@id/home_preview_change_api"
|
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"
|
android:text="@string/home_play"
|
||||||
app:icon="@drawable/ic_baseline_play_arrow_24" />
|
app:icon="@drawable/ic_baseline_play_arrow_24" />
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@
|
||||||
android:nextFocusLeft="@id/home_preview_play_btt"
|
android:nextFocusLeft="@id/home_preview_play_btt"
|
||||||
android:nextFocusRight="@id/home_preview_hidden_next_focus"
|
android:nextFocusRight="@id/home_preview_hidden_next_focus"
|
||||||
android:nextFocusUp="@id/home_preview_change_api"
|
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"
|
android:text="@string/home_info"
|
||||||
app:icon="@drawable/ic_outline_info_24" />
|
app:icon="@drawable/ic_outline_info_24" />
|
||||||
|
|
||||||
|
|
|
@ -537,6 +537,7 @@ https://developer.android.com/design/ui/tv/samples/jet-fit
|
||||||
</androidx.core.widget.NestedScrollView>
|
</androidx.core.widget.NestedScrollView>
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
android:layout_gravity="end"
|
||||||
android:id="@+id/episodes_shadow"
|
android:id="@+id/episodes_shadow"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="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_width="wrap_content"
|
||||||
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="right"
|
android:layout_gravity="end"
|
||||||
android:orientation="horizontal"
|
android:orientation="horizontal"
|
||||||
android:paddingStart="@dimen/result_padding"
|
android:paddingStart="@dimen/result_padding"
|
||||||
android:paddingEnd="@dimen/result_padding"
|
android:paddingEnd="@dimen/result_padding"
|
||||||
|
|
|
@ -14,9 +14,9 @@
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
style="@style/NoCheckLabel"
|
android:id="@android:id/text1"
|
||||||
tools:text="hello"
|
style="@style/NoCheckLabel"
|
||||||
android:textStyle="normal"
|
android:textColor="?attr/textColor"
|
||||||
android:textColor="?attr/textColor"
|
android:textStyle="normal"
|
||||||
android:id="@android:id/text1" />
|
tools:text="hello" />
|
||||||
|
|
Loading…
Reference in a new issue