diff --git a/README.md b/README.md
index 3f5a6e01..0295f82c 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,11 @@
## 更新日志
+### v1.4.4(安卓4专用)
+
+* 优化图标显示
+* 增加换台反转
+
### v1.3.3
* 部分错误会提示用户
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f76b90f5..b38f4862 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -9,7 +9,7 @@
diff --git a/app/src/main/java/com/lizongying/mytv/ChannelFragment.kt b/app/src/main/java/com/lizongying/mytv/ChannelFragment.kt
new file mode 100644
index 00000000..4e51b57d
--- /dev/null
+++ b/app/src/main/java/com/lizongying/mytv/ChannelFragment.kt
@@ -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"
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/lizongying/mytv/MainActivity.kt b/app/src/main/java/com/lizongying/mytv/MainActivity.kt
index 88e5887b..563c2356 100644
--- a/app/src/main/java/com/lizongying/mytv/MainActivity.kt
+++ b/app/src/main/java/com/lizongying/mytv/MainActivity.kt
@@ -1,11 +1,11 @@
package com.lizongying.mytv
-import android.app.AlertDialog
+import android.content.Context
+import android.content.SharedPreferences
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.content.pm.Signature
import android.content.pm.SigningInfo
-import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.os.Handler
@@ -16,11 +16,7 @@ import android.view.KeyEvent
import android.view.MotionEvent
import android.view.View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
import android.view.WindowManager
-import android.widget.ImageView
-import android.widget.LinearLayout
-import android.widget.TextView
import android.widget.Toast
-import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
import com.lizongying.mytv.models.TVViewModel
import java.security.MessageDigest
@@ -31,6 +27,7 @@ class MainActivity : FragmentActivity() {
var playerFragment = PlayerFragment()
private val mainFragment = MainFragment2()
private val infoFragment = InfoFragment()
+ private val channelFragment = ChannelFragment()
private var doubleBackToExitPressedOnce = false
@@ -38,6 +35,13 @@ class MainActivity : FragmentActivity() {
private val handler = Handler()
private val delay: Long = 4000
+ private val delayHideHelp: Long = 10000
+
+ private lateinit var sharedPref: SharedPreferences
+ private var channelReversal = false
+
+ private var versionName = ""
+ private lateinit var dialogFragment: MyDialogFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -51,17 +55,26 @@ class MainActivity : FragmentActivity() {
supportFragmentManager.beginTransaction()
.add(R.id.main_browse_fragment, playerFragment)
.add(R.id.main_browse_fragment, infoFragment)
+ .add(R.id.main_browse_fragment, channelFragment)
.add(R.id.main_browse_fragment, mainFragment)
.hide(infoFragment)
+ .hide(channelFragment)
.hide(mainFragment)
.commit()
mainFragment.view?.requestFocus()
}
gestureDetector = GestureDetector(this, GestureListener())
+
+ sharedPref = getPreferences(Context.MODE_PRIVATE)
+ channelReversal = sharedPref.getBoolean(CHANNEL_REVERSAL, false)
+
+ versionName = getPackageInfo().versionName
+ dialogFragment = MyDialogFragment(versionName, channelReversal)
}
fun showInfoFragment(tvViewModel: TVViewModel) {
infoFragment.show(tvViewModel)
+ channelFragment.show(tvViewModel)
}
fun play(tvViewModel: TVViewModel) {
@@ -69,6 +82,10 @@ class MainActivity : FragmentActivity() {
mainFragment.view?.requestFocus()
}
+ fun play(itemPosition: Int) {
+ mainFragment.play(itemPosition)
+ }
+
fun prev() {
mainFragment.prev()
}
@@ -105,7 +122,9 @@ class MainActivity : FragmentActivity() {
}
private val hideRunnable = Runnable {
- supportFragmentManager.beginTransaction().hide(mainFragment).commit()
+ if (!mainFragment.isHidden) {
+ supportFragmentManager.beginTransaction().hide(mainFragment).commit()
+ }
}
private fun mainFragmentIsHidden(): Boolean {
@@ -172,42 +191,42 @@ class MainActivity : FragmentActivity() {
}
}
+ fun saveChannelReversal(channelReversal: Boolean) {
+ with(sharedPref.edit()) {
+ putBoolean(CHANNEL_REVERSAL, channelReversal)
+ apply()
+ }
+ this.channelReversal = channelReversal
+ }
+
private fun showHelp() {
- val versionName = getPackageInfo().versionName
-
- val textView = TextView(this)
- textView.text =
- "当前版本: $versionName\n获取最新: https://github.com/lizongying/my-tv/releases/"
- textView.setBackgroundColor(0xFF263238.toInt())
- textView.setPadding(20, 50, 20, 20)
-
- val imageView = ImageView(this)
- val drawable = ContextCompat.getDrawable(this, R.drawable.appreciate)
- imageView.setImageDrawable(drawable)
- imageView.setBackgroundColor(Color.WHITE)
-
- val linearLayout = LinearLayout(this)
- linearLayout.orientation = LinearLayout.VERTICAL
- linearLayout.addView(textView)
- linearLayout.addView(imageView)
-
- val layoutParams = LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.MATCH_PARENT,
- LinearLayout.LayoutParams.WRAP_CONTENT
- )
- imageView.layoutParams = layoutParams
- textView.layoutParams = layoutParams
-
- val builder: AlertDialog.Builder = AlertDialog.Builder(this)
- builder
- .setView(linearLayout)
-
- val dialog: AlertDialog = builder.create()
- dialog.show()
+ if (!mainFragment.isHidden) {
+ return
+ }
+
+ Log.i(TAG, "dialogFragment ${dialogFragment.isVisible}")
+ if (!dialogFragment.isVisible) {
+ 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() {
if (mainFragment.isHidden) {
+ if (channelReversal) {
+ next()
+ return
+ }
prev()
} else {
// if (mainFragment.selectedPosition == 0) {
@@ -221,6 +240,10 @@ class MainActivity : FragmentActivity() {
private fun channelDown() {
if (mainFragment.isHidden) {
+ if (channelReversal) {
+ prev()
+ return
+ }
next()
} else {
// if (mainFragment.selectedPosition == mainFragment.tvListViewModel.maxNum.size - 1) {
@@ -250,30 +273,100 @@ class MainActivity : FragmentActivity() {
}, 2000)
}
+ private fun showChannel(channel: String) {
+ if (!mainFragment.isHidden) {
+ return
+ }
+
+ if (dialogFragment.isVisible) {
+ return
+ }
+
+ channelFragment.show(channel)
+ }
+
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
-// Toast.makeText(this, "keyCode ${keyCodeToString(keyCode)}", Toast.LENGTH_SHORT).show()
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 -> {
back()
return true
}
+
KeyEvent.KEYCODE_BACK -> {
back()
return true
}
+ KeyEvent.KEYCODE_BOOKMARK -> {
+ showHelp()
+ return true
+ }
+
KeyEvent.KEYCODE_UNKNOWN -> {
showHelp()
return true
}
+
KeyEvent.KEYCODE_HELP -> {
showHelp()
return true
}
+
KeyEvent.KEYCODE_SETTINGS -> {
showHelp()
return true
}
+
KeyEvent.KEYCODE_MENU -> {
showHelp()
return true
@@ -282,6 +375,7 @@ class MainActivity : FragmentActivity() {
KeyEvent.KEYCODE_ENTER -> {
switchMainFragment()
}
+
KeyEvent.KEYCODE_DPAD_CENTER -> {
switchMainFragment()
}
@@ -289,6 +383,7 @@ class MainActivity : FragmentActivity() {
KeyEvent.KEYCODE_DPAD_UP -> {
channelUp()
}
+
KeyEvent.KEYCODE_CHANNEL_UP -> {
channelUp()
}
@@ -296,6 +391,7 @@ class MainActivity : FragmentActivity() {
KeyEvent.KEYCODE_DPAD_DOWN -> {
channelDown()
}
+
KeyEvent.KEYCODE_CHANNEL_DOWN -> {
channelDown()
}
@@ -382,5 +478,6 @@ class MainActivity : FragmentActivity() {
companion object {
private const val TAG = "MainActivity"
+ private const val CHANNEL_REVERSAL = "channel_reversal"
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lizongying/mytv/MainFragment2.kt b/app/src/main/java/com/lizongying/mytv/MainFragment2.kt
index 2f7c372f..42896d19 100644
--- a/app/src/main/java/com/lizongying/mytv/MainFragment2.kt
+++ b/app/src/main/java/com/lizongying/mytv/MainFragment2.kt
@@ -97,7 +97,7 @@ class MainFragment2 : Fragment(), CardAdapter.ItemListener {
mUpdateProgramRunnable = UpdateProgramRunnable()
handler.post(mUpdateProgramRunnable)
- itemPosition = sharedPref?.getInt("position", 0)!!
+ itemPosition = sharedPref?.getInt(POSITION, 0)!!
if (itemPosition >= tvListViewModel.size()) {
itemPosition = 0
}
@@ -108,7 +108,8 @@ class MainFragment2 : Fragment(), CardAdapter.ItemListener {
if (tvViewModel.errInfo.value != null
&& tvViewModel.id.value == itemPosition
) {
- Toast.makeText(context, tvViewModel.errInfo.value, Toast.LENGTH_SHORT).show()
+ Toast.makeText(context, tvViewModel.errInfo.value, Toast.LENGTH_SHORT)
+ .show()
}
}
tvViewModel.ready.observe(viewLifecycleOwner) { _ ->
@@ -213,12 +214,22 @@ class MainFragment2 : Fragment(), CardAdapter.ItemListener {
fun fragmentReady() {
ready++
Log.i(TAG, "ready $ready")
- if (ready == 3) {
+ if (ready == 4) {
// request.fetchPage()
tvListViewModel.getTVViewModel(itemPosition)?.changed()
}
}
+ fun play(itemPosition: Int) {
+ view?.post {
+ if (itemPosition < tvListViewModel.size()) {
+ this.itemPosition = itemPosition
+ tvListViewModel.setItemPosition(itemPosition)
+ tvListViewModel.getTVViewModel(itemPosition)?.changed()
+ }
+ }
+ }
+
fun prev() {
view?.post {
itemPosition--
@@ -268,13 +279,26 @@ class MainFragment2 : Fragment(), CardAdapter.ItemListener {
}
}
- override fun onDestroy() {
- super.onDestroy()
- handler.removeCallbacks(mUpdateProgramRunnable)
+ override fun onStop() {
+ Log.i(TAG, "onStop")
+ super.onStop()
with(sharedPref!!.edit()) {
- putInt("position", itemPosition)
+ putInt(POSITION, itemPosition)
apply()
}
+ Log.i(TAG, "POSITION saved")
+ }
+
+ override fun onDestroy() {
+ Log.i(TAG, "onDestroy")
+ super.onDestroy()
+ handler.removeCallbacks(mUpdateProgramRunnable)
+ }
+
+ override fun onDestroyView() {
+ Log.i(TAG, "onDestroyView")
+ super.onDestroyView()
+ _binding = null
}
override fun onResume() {
@@ -284,5 +308,6 @@ class MainFragment2 : Fragment(), CardAdapter.ItemListener {
companion object {
private const val TAG = "MainFragment"
+ private const val POSITION = "position"
}
}
\ No newline at end of file
diff --git a/app/src/main/java/com/lizongying/mytv/MyDialogFragment.kt b/app/src/main/java/com/lizongying/mytv/MyDialogFragment.kt
new file mode 100644
index 00000000..24a9cb5d
--- /dev/null
+++ b/app/src/main/java/com/lizongying/mytv/MyDialogFragment.kt
@@ -0,0 +1,49 @@
+package com.lizongying.mytv
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.DialogFragment
+import com.lizongying.mytv.databinding.DialogBinding
+
+
+class MyDialogFragment(private val versionName: String, private val channelReversal: Boolean) :
+ DialogFragment() {
+
+ private var _binding: DialogBinding? = null
+ private val binding get() = _binding!!
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ setStyle(STYLE_NO_TITLE, 0)
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ _binding = DialogBinding.inflate(inflater, container, false)
+ _binding?.version?.text =
+ "当前版本: $versionName\n获取最新: https://github.com/lizongying/my-tv/releases/"
+
+ val switchView = _binding?.switchView
+ switchView?.isChecked = channelReversal
+ switchView?.setOnCheckedChangeListener { _, isChecked ->
+ (activity as MainActivity).saveChannelReversal(isChecked)
+ }
+
+ return binding.root
+ }
+
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+
+ companion object {
+ const val TAG = "MyDialogFragment"
+ }
+}
+
diff --git a/app/src/main/java/com/lizongying/mytv/PlayerFragment.kt b/app/src/main/java/com/lizongying/mytv/PlayerFragment.kt
index 77b5557c..b3218455 100644
--- a/app/src/main/java/com/lizongying/mytv/PlayerFragment.kt
+++ b/app/src/main/java/com/lizongying/mytv/PlayerFragment.kt
@@ -103,6 +103,11 @@ class PlayerFragment : Fragment() {
}
}
+ override fun onDestroyView() {
+ super.onDestroyView()
+ _binding = null
+ }
+
companion object {
private const val TAG = "PlaybackVideoFragment"
}
diff --git a/app/src/main/res/layout/channel.xml b/app/src/main/res/layout/channel.xml
new file mode 100644
index 00000000..47c664a8
--- /dev/null
+++ b/app/src/main/res/layout/channel.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog.xml b/app/src/main/res/layout/dialog.xml
new file mode 100644
index 00000000..45bf1fc1
--- /dev/null
+++ b/app/src/main/res/layout/dialog.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/info.xml b/app/src/main/res/layout/info.xml
index b3e3e69e..1678e33a 100644
--- a/app/src/main/res/layout/info.xml
+++ b/app/src/main/res/layout/info.xml
@@ -12,7 +12,6 @@
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
- android:contentDescription="@string/logo"
android:padding="10dp" />
我的电视
- logo
+ 频道反转
\ No newline at end of file