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
This commit is contained in:
xiaji
2026-05-24 21:19:34 +08:00
parent 7dee3977de
commit 153b555d52
7 changed files with 34 additions and 54 deletions

View File

@@ -1,11 +1,11 @@
package com.videoapp.tv
import android.os.Bundle
import android.view.KeyEvent
import android.view.View
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.Button
import android.widget.ImageButton
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
@@ -15,10 +15,7 @@ import androidx.media3.ui.PlayerView
import com.videoapp.tv.data.ConfigRepository
import com.videoapp.tv.engine.Episode
import com.videoapp.tv.engine.VideoExtractor
import com.videoapp.tv.engine.WebViewPlayer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class PlayerActivity : AppCompatActivity() {
@@ -28,15 +25,14 @@ class PlayerActivity : AppCompatActivity() {
private lateinit var episodeList: android.widget.LinearLayout
private lateinit var loadingIndicator: View
private lateinit var errorText: android.widget.TextView
private lateinit var btnClose: ImageButton
private var exoPlayer: ExoPlayer? = null
private val videoExtractor = VideoExtractor()
private val configRepo by lazy { ConfigRepository(this) }
private val webViewPlayer by lazy { WebViewPlayer(this) }
private var episodes: List<Episode> = 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
}
}