feat(android): obwodka fokusu pilota, tablet bez blokady pionu na starcie
RN 0.76 nie przekazuje onFocus/onBlur do JS na Androidzie, a Android TV nie rysuje systemowego podswietlenia, wiec na Fire TV nie bylo widac, gdzie jest pilot (zgloszenie 7768ae0c). Globalny nasluch zmiany fokusu w MainActivity daje widokowi z fokusem foreground z jasna obwodka; w trybie dotykowym nic. Tablet (sw >= 600 dp) nie dostaje juz pionu w onCreate. Wymaga nowego APK. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
ca9ccf29f1
commit
bc674c2ec4
1 changed files with 42 additions and 1 deletions
|
|
@ -5,9 +5,14 @@ import android.content.Context
|
||||||
import android.content.pm.ActivityInfo
|
import android.content.pm.ActivityInfo
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.graphics.drawable.GradientDrawable
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.util.TypedValue
|
||||||
|
import android.view.View
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
import com.facebook.react.ReactActivity
|
import com.facebook.react.ReactActivity
|
||||||
import com.facebook.react.ReactActivityDelegate
|
import com.facebook.react.ReactActivityDelegate
|
||||||
|
|
@ -37,7 +42,9 @@ import expo.modules.ReactActivityDelegateWrapper
|
||||||
*/
|
*/
|
||||||
open class MainActivity : ReactActivity() {
|
open class MainActivity : ReactActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
if (!isTelevision()) {
|
// Tablet (krotszy bok >= 600 dp) zostaje bez blokady: pion na tablecie trzymanym w poziomie
|
||||||
|
// to waski pasek, a zdjecie blokady z JS (src/lib/tablet.ts) i tak przychodzi chwile pozniej.
|
||||||
|
if (!isTelevision() && resources.configuration.smallestScreenWidthDp < 600) {
|
||||||
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
|
||||||
}
|
}
|
||||||
// Set the theme to AppTheme BEFORE onCreate to support
|
// Set the theme to AppTheme BEFORE onCreate to support
|
||||||
|
|
@ -55,6 +62,40 @@ open class MainActivity : ReactActivity() {
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
Log.w("Goon", "Cast niedostepny na tym urzadzeniu: " + e.javaClass.simpleName)
|
Log.w("Goon", "Cast niedostepny na tym urzadzeniu: " + e.javaClass.simpleName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
installFocusRing()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Obwodka wokol elementu z fokusem pilota (Fire TV, Android TV, klawiatura).
|
||||||
|
//
|
||||||
|
// Pilot chodzi po zwyklych przyciskach RN, ale nic nie pokazywalo, gdzie jest fokus
|
||||||
|
// (zgloszenie 7768ae0c, Fire TV): widoki RN maja wlasne tlo bez stanu "focused", Android TV
|
||||||
|
// nie rysuje systemowego podswietlenia, a RN 0.76 na Androidzie nie przekazuje onFocus/onBlur
|
||||||
|
// do JS (sprawdzone 2026-10-15 na emulatorze: przycisk ma fokus, zdarzenie nie przychodzi).
|
||||||
|
// Dlatego natywnie: przy kazdej zmianie fokusu nowy widok dostaje foreground z obwodka,
|
||||||
|
// a poprzedni odzyskuje swoj. W trybie dotykowym (telefon) nic nie rysujemy.
|
||||||
|
private var ringView: WeakReference<View>? = null
|
||||||
|
private var ringPrevForeground: Drawable? = null
|
||||||
|
|
||||||
|
private fun installFocusRing() {
|
||||||
|
window.decorView.viewTreeObserver.addOnGlobalFocusChangeListener { _, newFocus ->
|
||||||
|
ringView?.get()?.let { it.foreground = ringPrevForeground }
|
||||||
|
ringView = null
|
||||||
|
ringPrevForeground = null
|
||||||
|
if (newFocus == null || newFocus.isInTouchMode) return@addOnGlobalFocusChangeListener
|
||||||
|
ringPrevForeground = newFocus.foreground
|
||||||
|
newFocus.foreground = makeFocusRing()
|
||||||
|
ringView = WeakReference(newFocus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun makeFocusRing(): Drawable {
|
||||||
|
val dp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1f, resources.displayMetrics)
|
||||||
|
return GradientDrawable().apply {
|
||||||
|
shape = GradientDrawable.RECTANGLE
|
||||||
|
cornerRadius = 12 * dp
|
||||||
|
setStroke((3 * dp).toInt(), 0xFFF5EDE0.toInt())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isTelevision(): Boolean {
|
private fun isTelevision(): Boolean {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue