android TV fix

This commit is contained in:
LagradOst 2021-11-28 13:18:01 +01:00
parent 53288cfaf1
commit b13c1eac01
9 changed files with 150 additions and 25 deletions

View file

@ -145,20 +145,84 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
}
}
enum class FocusDirection {
Left,
Right,
Up,
Down,
}
private fun getNextFocus(view: View?, direction: FocusDirection, depth: Int = 0): Int? {
if (view == null || depth >= 10) {
return null
}
val nextId = when (direction) {
FocusDirection.Left -> {
view.nextFocusLeftId
}
FocusDirection.Up -> {
view.nextFocusUpId
}
FocusDirection.Right -> {
view.nextFocusRightId
}
FocusDirection.Down -> {
view.nextFocusDownId
}
}
return if (nextId != -1) {
val next = findViewById<View?>(nextId)
//println("NAME: ${next.accessibilityClassName} | ${next?.isShown}" )
if (next?.isShown == false) {
getNextFocus(next, direction, depth + 1)
} else {
if (depth == 0) {
null
} else {
nextId
}
}
} else {
null
}
}
override fun dispatchKeyEvent(event: KeyEvent?): Boolean {
event?.keyCode?.let { keyCode ->
when (event.action) {
ACTION_DOWN -> {
when (keyCode) {
KeyEvent.KEYCODE_DPAD_CENTER -> {
println("DPAD PRESSED $currentFocus")
if (currentFocus is SearchView || currentFocus is SearchView.SearchAutoComplete) {
println("current PRESSED")
showInputMethod(currentFocus?.findFocus())
if (currentFocus != null) {
val next = when (keyCode) {
KeyEvent.KEYCODE_DPAD_LEFT -> getNextFocus(currentFocus, FocusDirection.Left)
KeyEvent.KEYCODE_DPAD_RIGHT -> getNextFocus(currentFocus, FocusDirection.Right)
KeyEvent.KEYCODE_DPAD_UP -> getNextFocus(currentFocus, FocusDirection.Up)
KeyEvent.KEYCODE_DPAD_DOWN -> getNextFocus(currentFocus, FocusDirection.Down)
else -> null
}
if (next != null && next != -1) {
val nextView = findViewById<View?>(next)
if(nextView != null) {
nextView.requestFocus()
return true
}
}
when (keyCode) {
KeyEvent.KEYCODE_DPAD_CENTER -> {
println("DPAD PRESSED $currentFocus")
if (currentFocus is SearchView || currentFocus is SearchView.SearchAutoComplete) {
println("current PRESSED")
showInputMethod(currentFocus?.findFocus())
}
}
}
}
//println("Keycode: $keyCode")
//showToast(
// this,
@ -169,7 +233,7 @@ class MainActivity : AppCompatActivity(), ColorPickerDialogListener {
}
}
if(keyEventListener?.invoke(event) == true) {
if (keyEventListener?.invoke(event) == true) {
return true
}
return super.dispatchKeyEvent(event)

View file

@ -12,13 +12,19 @@ import com.lagradost.cloudstream3.ui.search.SearchResultBuilder
class HomeChildItemAdapter(
var cardList: List<SearchResponse>,
val layout: Int = R.layout.home_result_grid,
private val clickCallback: (SearchClickCallback) -> Unit
private val nextFocusUp: Int? = null,
private val nextFocusDown: Int? = null,
private val clickCallback: (SearchClickCallback) -> Unit,
) :
RecyclerView.Adapter<RecyclerView.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return CardViewHolder(
LayoutInflater.from(parent.context).inflate(layout, parent, false), clickCallback, itemCount
LayoutInflater.from(parent.context).inflate(layout, parent, false),
clickCallback,
itemCount,
nextFocusUp,
nextFocusDown
)
}
@ -39,19 +45,23 @@ class HomeChildItemAdapter(
}
class CardViewHolder
constructor(itemView: View, private val clickCallback: (SearchClickCallback) -> Unit, val itemCount: Int) :
constructor(
itemView: View, private val clickCallback: (SearchClickCallback) -> Unit, private val itemCount: Int,
private val nextFocusUp: Int? = null,
private val nextFocusDown: Int? = null,
) :
RecyclerView.ViewHolder(itemView) {
fun bind(card: SearchResponse, index: Int) {
// TV focus fixing
val nextFocusBehavior = when(index){
val nextFocusBehavior = when (index) {
0 -> true
itemCount - 1 -> false
else -> null
}
SearchResultBuilder.bind(clickCallback, card, itemView, nextFocusBehavior)
SearchResultBuilder.bind(clickCallback, card, itemView, nextFocusBehavior, nextFocusUp, nextFocusDown)
itemView.tag = index
//val ani = ScaleAnimation(0.9f, 1.0f, 0.9f, 1f)
//ani.fillAfter = true

View file

@ -35,6 +35,7 @@ import com.lagradost.cloudstream3.ui.result.START_ACTION_RESUME_LATEST
import com.lagradost.cloudstream3.ui.search.*
import com.lagradost.cloudstream3.ui.search.SearchFragment.Companion.filterSearchResponse
import com.lagradost.cloudstream3.ui.search.SearchHelper.handleSearchClickCallback
import com.lagradost.cloudstream3.ui.settings.SettingsFragment.Companion.isTvSettings
import com.lagradost.cloudstream3.utils.AppUtils
import com.lagradost.cloudstream3.utils.AppUtils.loadSearchResult
import com.lagradost.cloudstream3.utils.DataStore.getKey
@ -212,7 +213,12 @@ class HomeFragment : Fragment() {
val randomSize = items.size
home_main_poster_recyclerview.adapter =
HomeChildItemAdapter(items, R.layout.home_result_big_grid) { callback ->
HomeChildItemAdapter(
items,
R.layout.home_result_big_grid,
nextFocusUp = home_main_poster_recyclerview.nextFocusUpId,
nextFocusDown = home_main_poster_recyclerview.nextFocusDownId
) { callback ->
handleSearchClickCallback(activity, callback)
}
home_main_poster_recyclerview.post {
@ -339,7 +345,11 @@ class HomeFragment : Fragment() {
}
}
home_bookmarked_child_recyclerview.adapter = HomeChildItemAdapter(ArrayList()) { callback ->
home_bookmarked_child_recyclerview.adapter = HomeChildItemAdapter(
ArrayList(),
nextFocusUp = home_bookmarked_child_recyclerview?.nextFocusUpId,
nextFocusDown = home_bookmarked_child_recyclerview?.nextFocusDownId
) { callback ->
if (callback.action == SEARCH_ACTION_SHOW_METADATA) {
val id = callback.card.id
if (id != null) {
@ -355,7 +365,11 @@ class HomeFragment : Fragment() {
}
}
home_watch_child_recyclerview.adapter = HomeChildItemAdapter(ArrayList()) { callback ->
home_watch_child_recyclerview.adapter = HomeChildItemAdapter(
ArrayList(),
nextFocusUp = home_watch_child_recyclerview?.nextFocusUpId,
nextFocusDown = home_watch_child_recyclerview?.nextFocusDownId
) { callback ->
if (callback.action == SEARCH_ACTION_SHOW_METADATA) {
val id = callback.card.id
if (id != null) {
@ -423,6 +437,16 @@ class HomeFragment : Fragment() {
// nice profile pic on homepage
home_profile_picture_holder?.isVisible = false
context?.let { ctx ->
// just in case
if (ctx.isTvSettings()) {
home_change_api_loading?.isFocusable = true
home_change_api_loading?.isFocusableInTouchMode = true
home_change_api?.isFocusable = true
home_change_api?.isFocusableInTouchMode = true
home_bookmark_select?.isFocusable = true
home_bookmark_select?.isFocusableInTouchMode = true
}
for (syncApi in OAuth2API.OAuth2Apis) {
val login = syncApi.loginInfo(ctx)
val pic = login?.profilePicture
@ -433,5 +457,7 @@ class HomeFragment : Fragment() {
}
}
}
}
}

View file

@ -47,7 +47,12 @@ class ParentItemAdapter(
private val moreInfo: FrameLayout = itemView.home_child_more_info
fun bind(info: HomePageList) {
title.text = info.name
recyclerView.adapter = HomeChildItemAdapter(info.list, clickCallback = clickCallback)
recyclerView.adapter = HomeChildItemAdapter(
info.list,
clickCallback = clickCallback,
nextFocusUp = recyclerView.nextFocusUpId,
nextFocusDown = recyclerView.nextFocusDownId
)
(recyclerView.adapter as HomeChildItemAdapter).notifyDataSetChanged()
moreInfo.setOnClickListener {

View file

@ -1018,7 +1018,7 @@ class PlayerFragment : Fragment() {
private fun handleKeyEvent(event: KeyEvent): Boolean {
event.keyCode.let { keyCode ->
when (event.action) {
when (keyCode) {
// don't allow dpad move when hidden
KeyEvent.KEYCODE_DPAD_LEFT,
KeyEvent.KEYCODE_DPAD_DOWN,
@ -1032,6 +1032,17 @@ class PlayerFragment : Fragment() {
return true
}
}
// netflix capture back and hide ~monke
KeyEvent.KEYCODE_BACK -> {
if (isShowing) {
onClickChange()
return true
}
}
}
when (event.action) {
KeyEvent.ACTION_DOWN -> {
when (keyCode) {
KeyEvent.KEYCODE_DPAD_CENTER -> {

View file

@ -38,7 +38,7 @@ class SearchAdapter(
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is CardViewHolder -> {
holder.bind(cardList[position])
holder.bind(cardList[position], position)
}
}
}
@ -59,7 +59,7 @@ class SearchAdapter(
private val compactView = itemView.context.getGridIsCompact()
private val coverHeight: Int = if (compactView) 80.toPx else (resView.itemWidth / 0.68).roundToInt()
fun bind(card: SearchResponse) {
fun bind(card: SearchResponse, position: Int) {
if (!compactView) {
cardView.apply {
layoutParams = FrameLayout.LayoutParams(
@ -69,7 +69,7 @@ class SearchAdapter(
}
}
SearchResultBuilder.bind(clickCallback, card, itemView,)
SearchResultBuilder.bind(clickCallback, card, itemView)
}
}
}

View file

@ -22,7 +22,9 @@ object SearchResultBuilder {
clickCallback: (SearchClickCallback) -> Unit,
card: SearchResponse,
itemView: View,
nextFocusBehavior: Boolean? = null
nextFocusBehavior: Boolean? = null,
nextFocusUp: Int? = null,
nextFocusDown: Int? = null,
) {
val cardView: ImageView = itemView.imageView
val cardText: TextView? = itemView.imageText
@ -57,6 +59,14 @@ object SearchResultBuilder {
)
}
if(nextFocusUp != null) {
bg.nextFocusUpId = nextFocusUp
}
if(nextFocusDown != null) {
bg.nextFocusDownId = nextFocusDown
}
when (nextFocusBehavior) {
true -> bg.nextFocusLeftId = bg.id
false -> bg.nextFocusRightId = bg.id

View file

@ -43,6 +43,7 @@
android:layout_gravity="center_vertical"
app:iconifiedByDefault="false"
tools:ignore="RtlSymmetry">
<requestFocus/>
<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/search_loading_bar"
@ -75,7 +76,6 @@
android:layout_gravity="end|center_vertical"
app:tint="?attr/textColor"
android:contentDescription="@string/change_providers_img_des">
<requestFocus/>
</ImageView>
</FrameLayout>

View file

@ -8,8 +8,6 @@
android:layout_height="wrap_content">
<FrameLayout
android:nextFocusDown="@id/home_child_recyclerview"
android:foreground="?android:attr/selectableItemBackgroundBorderless"
android:id="@+id/home_child_more_info"
android:padding="12dp"
@ -32,6 +30,7 @@
</FrameLayout>
<androidx.recyclerview.widget.RecyclerView
android:nextFocusUp="@id/home_child_more_info"
android:paddingHorizontal="5dp"
android:clipToPadding="false"