From 153b555d52e2a7451f846e311c56a9923b0718dd Mon Sep 17 00:00:00 2001 From: xiaji Date: Sun, 24 May 2026 21:19:34 +0800 Subject: [PATCH] refactor: convert from Android TV to phone/tablet mode - Replace Theme.Leanback with Theme.AppCompat.DayNight.NoActionBar - Remove leanback dependencies (leanback, leanback-preference) - Remove LEANBACK_LAUNCHER, leanback feature, banner from manifest - PlayerActivity: replace D-pad with touch controls (click to toggle episodes, close button) - SearchFragment: adaptive grid (3 cols phone / 5 cols tablet), remove focus-based history toggle - Fix deprecated adapterPosition -> bindingAdapterPosition --- app/build.gradle.kts | 4 -- app/src/main/AndroidManifest.xml | 8 +--- .../java/com/videoapp/tv/PlayerActivity.kt | 39 ++++++------------- .../java/com/videoapp/tv/ui/SearchFragment.kt | 9 +---- .../com/videoapp/tv/ui/SearchResultAdapter.kt | 2 +- app/src/main/res/layout/activity_player.xml | 15 ++++++- app/src/main/res/values/themes.xml | 11 +++--- 7 files changed, 34 insertions(+), 54 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 5dc8259..930726f 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -41,10 +41,6 @@ android { } dependencies { - // Leanback (TV UI) - implementation("androidx.leanback:leanback:1.0.0") - implementation("androidx.leanback:leanback-preference:1.0.0") - // AndroidX implementation("androidx.core:core-ktx:1.12.0") implementation("androidx.appcompat:appcompat:1.6.1") diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f4392bb..e8f986a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,9 +7,6 @@ - + android:exported="true"> - @@ -33,7 +28,6 @@ android:name=".PlayerActivity" android:configChanges="orientation|screenSize|keyboardHidden" android:theme="@style/Theme.VideoSearchTV.Player" - android:screenOrientation="landscape" android:exported="false" /> = emptyList() private var currentEpisodeIndex = 0 - private var isPlayerReady = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -48,13 +44,16 @@ class PlayerActivity : AppCompatActivity() { episodeList = findViewById(R.id.episode_list) loadingIndicator = findViewById(R.id.loading_indicator) errorText = findViewById(R.id.error_text) + btnClose = findViewById(R.id.btn_close) val detailUrl = intent.getStringExtra("detail_url") ?: "" val title = intent.getStringExtra("title") ?: "" + btnClose.setOnClickListener { finish() } + initExoPlayer() loadVideos(detailUrl, title) - setupFullscreenListener() + setupTouchListeners() } private fun initExoPlayer() { @@ -63,7 +62,7 @@ class PlayerActivity : AppCompatActivity() { } } - private fun loadVideos(detailUrl: String, title: String) { + private fun loadVideos(detailUrl: String, @Suppress("UNUSED_PARAMETER") title: String) { showLoading(true) val config = configRepo.getConfig() @@ -118,13 +117,10 @@ class PlayerActivity : AppCompatActivity() { val (directUrl, iframeUrl) = videoExtractor.extractFromPlayPage(ep.playUrl, config) if (directUrl != null) { - // Play with ExoPlayer playWithExoPlayer(directUrl) } else if (iframeUrl != null) { - // Play iframe in WebView playWithWebView(iframeUrl) } else { - // Fallback: load play page in WebView playWithWebView(ep.playUrl) } } @@ -189,28 +185,15 @@ class PlayerActivity : AppCompatActivity() { showLoading(false) } - private fun setupFullscreenListener() { - // Toggle episode panel visibility on dpad up/down + private fun setupTouchListeners() { var panelVisible = true playerView.setOnClickListener { panelVisible = !panelVisible episodePanel.visibility = if (panelVisible) View.VISIBLE else View.GONE } - } - - override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { - return when (keyCode) { - KeyEvent.KEYCODE_DPAD_UP -> { - episodePanel.visibility = View.VISIBLE - true - } - KeyEvent.KEYCODE_DPAD_DOWN -> { - if (episodePanel.visibility == View.VISIBLE) { - episodePanel.visibility = View.GONE - } - true - } - else -> super.onKeyDown(keyCode, event) + playerWebView.setOnClickListener { + panelVisible = !panelVisible + episodePanel.visibility = if (panelVisible) View.VISIBLE else View.GONE } } diff --git a/app/src/main/java/com/videoapp/tv/ui/SearchFragment.kt b/app/src/main/java/com/videoapp/tv/ui/SearchFragment.kt index 3ea819c..a43970f 100644 --- a/app/src/main/java/com/videoapp/tv/ui/SearchFragment.kt +++ b/app/src/main/java/com/videoapp/tv/ui/SearchFragment.kt @@ -77,7 +77,8 @@ class SearchFragment : Fragment() { } private fun setupResultsGrid() { - resultsGrid.layoutManager = GridLayoutManager(context, 4) + val spanCount = if (resources.configuration.screenWidthDp >= 600) 5 else 3 + resultsGrid.layoutManager = GridLayoutManager(context, spanCount) resultsGrid.adapter = adapter } @@ -107,12 +108,6 @@ class SearchFragment : Fragment() { showHistory(emptyList()) } } - - searchInput.setOnFocusChangeListener { _, hasFocus -> - if (hasFocus) { - historyContainer.visibility = View.VISIBLE - } - } } private fun performSearch(keyword: String) { diff --git a/app/src/main/java/com/videoapp/tv/ui/SearchResultAdapter.kt b/app/src/main/java/com/videoapp/tv/ui/SearchResultAdapter.kt index 0db7d26..fcffd01 100644 --- a/app/src/main/java/com/videoapp/tv/ui/SearchResultAdapter.kt +++ b/app/src/main/java/com/videoapp/tv/ui/SearchResultAdapter.kt @@ -41,7 +41,7 @@ class SearchResultAdapter( init { itemView.setOnClickListener { - val pos = adapterPosition + val pos = bindingAdapterPosition if (pos != RecyclerView.NO_POSITION) { onItemClick(items[pos]) } diff --git a/app/src/main/res/layout/activity_player.xml b/app/src/main/res/layout/activity_player.xml index eef8086..b5f34a9 100644 --- a/app/src/main/res/layout/activity_player.xml +++ b/app/src/main/res/layout/activity_player.xml @@ -18,7 +18,18 @@ android:layout_height="match_parent" android:visibility="gone" /> - + + - + - -