number selection

This commit is contained in:
Li ZongYing 2024-01-18 21:42:06 +08:00
parent e1ee909071
commit ba95ce5374
10 changed files with 261 additions and 24 deletions

View File

@ -14,6 +14,15 @@
## 更新日志 ## 更新日志
### v1.4.5(高版本专用)
* 数字选台配置
### v1.4.4(通用版)
* 优化图标显示
* 增加换台反转
### v1.3.3 ### v1.3.3
* 部分错误会提示用户 * 部分错误会提示用户

View File

@ -9,7 +9,7 @@
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@drawable/logo"
android:label="@string/app_name" android:label="@string/app_name"
android:supportsRtl="true" android:supportsRtl="true"
android:theme="@style/Theme.MyTV"> android:theme="@style/Theme.MyTV">

View File

@ -0,0 +1,74 @@
package com.lizongying.mytv
import android.os.Bundle
import android.os.Handler
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.lizongying.mytv.databinding.ChannelBinding
import com.lizongying.mytv.models.TVViewModel
class ChannelFragment : Fragment() {
private var _binding: ChannelBinding? = null
private val binding get() = _binding!!
private val handler = Handler()
private val delay: Long = 3000
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = ChannelBinding.inflate(inflater, container, false)
(activity as MainActivity).fragmentReady()
return binding.root
}
fun show(tvViewModel: TVViewModel) {
binding.channelContent.text = tvViewModel.id.value.toString()
handler.removeCallbacks(removeRunnable)
view?.visibility = View.VISIBLE
handler.postDelayed(removeRunnable, delay)
}
fun show(channel: String) {
if (binding.channelContent.text == "") {
binding.channelContent.text = channel
handler.removeCallbacks(removeRunnable)
view?.visibility = View.VISIBLE
handler.postDelayed(removeRunnable, delay)
} else {
val ch = "${binding.channelContent.text}$channel".toInt()
Log.i(TAG, "channel $ch")
(activity as MainActivity).play(ch)
binding.channelContent.text = ""
view?.visibility = View.GONE
}
}
override fun onResume() {
super.onResume()
handler.postDelayed(removeRunnable, delay)
}
override fun onPause() {
super.onPause()
handler.removeCallbacks(removeRunnable)
}
private val removeRunnable = Runnable {
binding.channelContent.text = ""
view?.visibility = View.GONE
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
companion object {
private const val TAG = "ChannelFragment"
}
}

View File

@ -27,6 +27,7 @@ class MainActivity : FragmentActivity() {
var playerFragment = PlayerFragment() var playerFragment = PlayerFragment()
private val mainFragment = MainFragment() private val mainFragment = MainFragment()
private val infoFragment = InfoFragment() private val infoFragment = InfoFragment()
private val channelFragment = ChannelFragment()
private var doubleBackToExitPressedOnce = false private var doubleBackToExitPressedOnce = false
@ -34,9 +35,14 @@ class MainActivity : FragmentActivity() {
private val handler = Handler() private val handler = Handler()
private val delay: Long = 4000 private val delay: Long = 4000
private val delayHideHelp: Long = 10000
private lateinit var sharedPref: SharedPreferences private lateinit var sharedPref: SharedPreferences
private var channelReversal = false private var channelReversal = false
private var channelNum = true
private var versionName = ""
private lateinit var dialogFragment: MyDialogFragment
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -50,19 +56,28 @@ class MainActivity : FragmentActivity() {
supportFragmentManager.beginTransaction() supportFragmentManager.beginTransaction()
.add(R.id.main_browse_fragment, playerFragment) .add(R.id.main_browse_fragment, playerFragment)
.add(R.id.main_browse_fragment, infoFragment) .add(R.id.main_browse_fragment, infoFragment)
.add(R.id.main_browse_fragment, channelFragment)
.add(R.id.main_browse_fragment, mainFragment) .add(R.id.main_browse_fragment, mainFragment)
.hide(infoFragment) .hide(infoFragment)
.hide(channelFragment)
.commit() .commit()
mainFragment.view?.requestFocus() mainFragment.view?.requestFocus()
} }
gestureDetector = GestureDetector(this, GestureListener()) gestureDetector = GestureDetector(this, GestureListener())
sharedPref = getPreferences(Context.MODE_PRIVATE) sharedPref = getPreferences(Context.MODE_PRIVATE)
channelReversal = sharedPref.getBoolean(CHANNEL_REVERSAL, false) channelReversal = sharedPref.getBoolean(CHANNEL_REVERSAL, channelReversal)
channelNum = sharedPref.getBoolean(CHANNEL_NUM, channelNum)
versionName = getPackageInfo().versionName
dialogFragment = MyDialogFragment(versionName, channelReversal, channelNum)
} }
fun showInfoFragment(tvViewModel: TVViewModel) { fun showInfoFragment(tvViewModel: TVViewModel) {
infoFragment.show(tvViewModel) infoFragment.show(tvViewModel)
if (channelNum) {
channelFragment.show(tvViewModel)
}
} }
fun play(tvViewModel: TVViewModel) { fun play(tvViewModel: TVViewModel) {
@ -70,6 +85,10 @@ class MainActivity : FragmentActivity() {
mainFragment.view?.requestFocus() mainFragment.view?.requestFocus()
} }
fun play(itemPosition: Int) {
mainFragment.play(itemPosition)
}
fun prev() { fun prev() {
mainFragment.prev() mainFragment.prev()
} }
@ -79,11 +98,11 @@ class MainActivity : FragmentActivity() {
} }
private fun prevSource() { private fun prevSource() {
mainFragment.prevSource() // mainFragment.prevSource()
} }
private fun nextSource() { private fun nextSource() {
mainFragment.nextSource() // mainFragment.nextSource()
} }
fun switchMainFragment() { fun switchMainFragment() {
@ -182,14 +201,34 @@ class MainActivity : FragmentActivity() {
this.channelReversal = channelReversal this.channelReversal = channelReversal
} }
fun saveChannelNum(channelNum: Boolean) {
with(sharedPref.edit()) {
putBoolean(CHANNEL_NUM, channelNum)
apply()
}
this.channelNum = channelNum
}
private fun showHelp() { private fun showHelp() {
if (!mainFragment.isHidden) { if (!mainFragment.isHidden) {
return return
} }
val versionName = getPackageInfo().versionName Log.i(TAG, "dialogFragment ${dialogFragment.isVisible}")
val dialogFragment = MyDialogFragment(versionName, channelReversal) if (!dialogFragment.isVisible) {
dialogFragment.show(supportFragmentManager, "settings_dialog") dialogFragment.show(supportFragmentManager, "settings_dialog")
handler.removeCallbacks(hideHelp)
handler.postDelayed(hideHelp, delayHideHelp)
} else {
handler.removeCallbacks(hideHelp)
dialogFragment.dismiss()
}
}
private val hideHelp = Runnable {
if (dialogFragment.isVisible) {
dialogFragment.dismiss()
}
} }
private fun channelUp() { private fun channelUp() {
@ -244,8 +283,72 @@ class MainActivity : FragmentActivity() {
}, 2000) }, 2000)
} }
private fun showChannel(channel: String) {
if (!mainFragment.isHidden) {
return
}
if (dialogFragment.isVisible) {
return
}
if (channelNum) {
channelFragment.show(channel)
}
}
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
when (keyCode) { when (keyCode) {
KeyEvent.KEYCODE_0 -> {
showChannel("0")
return true
}
KeyEvent.KEYCODE_1 -> {
showChannel("1")
return true
}
KeyEvent.KEYCODE_2 -> {
showChannel("2")
return true
}
KeyEvent.KEYCODE_3 -> {
showChannel("3")
return true
}
KeyEvent.KEYCODE_4 -> {
showChannel("4")
return true
}
KeyEvent.KEYCODE_5 -> {
showChannel("5")
return true
}
KeyEvent.KEYCODE_6 -> {
showChannel("6")
return true
}
KeyEvent.KEYCODE_7 -> {
showChannel("7")
return true
}
KeyEvent.KEYCODE_8 -> {
showChannel("8")
return true
}
KeyEvent.KEYCODE_9 -> {
showChannel("9")
return true
}
KeyEvent.KEYCODE_ESCAPE -> { KeyEvent.KEYCODE_ESCAPE -> {
back() back()
return true return true
@ -388,5 +491,6 @@ class MainActivity : FragmentActivity() {
companion object { companion object {
private const val TAG = "MainActivity" private const val TAG = "MainActivity"
private const val CHANNEL_REVERSAL = "channel_reversal" private const val CHANNEL_REVERSAL = "channel_reversal"
private const val CHANNEL_NUM = "channel_num"
} }
} }

View File

@ -216,7 +216,7 @@ class MainFragment : BrowseSupportFragment() {
fun fragmentReady() { fun fragmentReady() {
ready++ ready++
Log.i(TAG, "ready $ready") Log.i(TAG, "ready $ready")
if (ready == 3) { if (ready == 4) {
// request.fetchPage() // request.fetchPage()
val tvViewModel = tvListViewModel.getTVViewModel(itemPosition) val tvViewModel = tvListViewModel.getTVViewModel(itemPosition)
tvViewModel?.changed() tvViewModel?.changed()
@ -225,6 +225,16 @@ class MainFragment : BrowseSupportFragment() {
} }
} }
fun play(itemPosition: Int) {
view?.post {
if (itemPosition < tvListViewModel.size()) {
this.itemPosition = itemPosition
tvListViewModel.setItemPosition(itemPosition)
tvListViewModel.getTVViewModel(itemPosition)?.changed()
}
}
}
fun prev() { fun prev() {
view?.post { view?.post {
itemPosition-- itemPosition--
@ -232,9 +242,7 @@ class MainFragment : BrowseSupportFragment() {
itemPosition = tvListViewModel.size() - 1 itemPosition = tvListViewModel.size() - 1
} }
tvListViewModel.setItemPosition(itemPosition) tvListViewModel.setItemPosition(itemPosition)
tvListViewModel.getTVViewModel(itemPosition)?.changed()
val tvViewModel = tvListViewModel.getTVViewModel(itemPosition)
tvViewModel?.changed()
} }
} }
@ -245,9 +253,7 @@ class MainFragment : BrowseSupportFragment() {
itemPosition = 0 itemPosition = 0
} }
tvListViewModel.setItemPosition(itemPosition) tvListViewModel.setItemPosition(itemPosition)
tvListViewModel.getTVViewModel(itemPosition)?.changed()
val tvViewModel = tvListViewModel.getTVViewModel(itemPosition)
tvViewModel?.changed()
} }
} }
@ -297,9 +303,7 @@ class MainFragment : BrowseSupportFragment() {
if (itemPosition != item.id.value!!) { if (itemPosition != item.id.value!!) {
itemPosition = item.id.value!! itemPosition = item.id.value!!
tvListViewModel.setItemPosition(itemPosition) tvListViewModel.setItemPosition(itemPosition)
tvListViewModel.getTVViewModel(itemPosition)?.changed()
val tvViewModel = tvListViewModel.getTVViewModel(itemPosition)
tvViewModel?.changed()
} }
(activity as? MainActivity)?.switchMainFragment() (activity as? MainActivity)?.switchMainFragment()
} }

View File

@ -8,12 +8,20 @@ import androidx.fragment.app.DialogFragment
import com.lizongying.mytv.databinding.DialogBinding import com.lizongying.mytv.databinding.DialogBinding
class MyDialogFragment(private val versionName: String, private val channelReversal: Boolean) : class MyDialogFragment(private val versionName: String,
private val channelReversal: Boolean,
private val channelNum: Boolean,
) :
DialogFragment() { DialogFragment() {
private var _binding: DialogBinding? = null private var _binding: DialogBinding? = null
private val binding get() = _binding!! private val binding get() = _binding!!
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setStyle(STYLE_NO_TITLE, 0)
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,
@ -23,12 +31,18 @@ class MyDialogFragment(private val versionName: String, private val channelRever
_binding?.version?.text = _binding?.version?.text =
"当前版本: $versionName\n获取最新: https://github.com/lizongying/my-tv/releases/" "当前版本: $versionName\n获取最新: https://github.com/lizongying/my-tv/releases/"
val switchView = _binding?.switchView val switchChannelReversal = _binding?.switchChannelReversal
switchView?.isChecked = channelReversal switchChannelReversal?.isChecked = channelReversal
switchView?.setOnCheckedChangeListener { _, isChecked -> switchChannelReversal?.setOnCheckedChangeListener { _, isChecked ->
(activity as MainActivity).saveChannelReversal(isChecked) (activity as MainActivity).saveChannelReversal(isChecked)
} }
val switchChannelNum = _binding?.switchChannelNum
switchChannelNum?.isChecked = channelNum
switchChannelNum?.setOnCheckedChangeListener { _, isChecked ->
(activity as MainActivity).saveChannelNum(isChecked)
}
return binding.root return binding.root
} }

View File

@ -103,6 +103,11 @@ class PlayerFragment : Fragment() {
} }
} }
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
companion object { companion object {
private const val TAG = "PlaybackVideoFragment" private const val TAG = "PlaybackVideoFragment"
} }

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/channel_fragment"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_gravity="end|top"
android:layout_marginTop="20dp"
android:layout_marginEnd="50dp">
<TextView
android:id="@+id/channel_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="0dp"
android:text="99"
android:textColor="#FFEEEEEE"
android:textStyle="bold"
android:textSize="50sp" />
</FrameLayout>

View File

@ -26,12 +26,18 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:text="当前版本: $versionName\n获取最新: https://github.com/lizongying/my-tv/releases/" android:text="当前版本: $versionName\n获取最新: https://github.com/lizongying/my-tv/releases/"
></TextView> ></TextView>
<Switch <Switch
android:id="@+id/switch_view" android:id="@+id/switch_channel_reversal"
android:text="@string/title_channel_reversal" android:text="@string/title_channel_reversal"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Switch
android:id="@+id/switch_channel_num"
android:text="@string/title_channel_num"
android:layout_marginTop="10dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
</LinearLayout> </LinearLayout>

View File

@ -1,4 +1,5 @@
<resources> <resources>
<string name="app_name">我的电视</string> <string name="app_name">我的电视</string>
<string name="title_channel_reversal">频道反转</string> <string name="title_channel_reversal">换台反转</string>
<string name="title_channel_num">数字选台</string>
</resources> </resources>