Compare commits

..
4 Commits
Author SHA1 Message Date
Li ZongYing fe92fa5853 optimize style 2024-04-25 22:36:37 +08:00
Li ZongYing 3d8ab65955 fix ysp 2024-04-23 19:41:30 +08:00
Li ZongYing 5485a686bc fix crash on 4.2 2024-04-19 20:13:43 +08:00
Li ZongYing 716efb5a83 change style 2024-04-19 19:26:06 +08:00
41 changed files with 720 additions and 239 deletions
+36
View File
@@ -1,5 +1,23 @@
## 更新日志 ## 更新日志
### v1.8.4(通用)
* 解決部分情況下打開後黑屏问题
* 延长频道信息显示时间,增加信息显示长度
* 调整频道列表间距
* 其他样式优化
### v1.8.2(通用)
* 修复无法播放问题
### v1.8.0(通用)
* 修复返回键无法退出问题
* 设置中增加退出按钮
* 修改非电视上的样式
* 修复低版本闪退问题
### v1.7.8(通用) ### v1.7.8(通用)
* 修复播放过程中的卡顿问题 * 修复播放过程中的卡顿问题
@@ -14,6 +32,24 @@
* 临时去掉部分频道,提高频道的可用性 * 临时去掉部分频道,提高频道的可用性
* 部分频道增加节目单 * 部分频道增加节目单
### v1.7.5(安卓5及以上专用)
* 修复播放过程中的卡顿问题
* 增加时间显示
* 频道号优化
* 设置中增加退出按钮
### v1.7.4(通用)
* 修复368
### v1.7.3(安卓5及以上专用)
* 临时去掉部分频道,提高频道的可用性
* 部分频道增加节目单
* 遥控器左键进入节目列表
* 遥控器右键进入菜单
### v1.7.2(通用) ### v1.7.2(通用)
* 支持节目列表网格样式和行样式切换,软件重启后生效 * 支持节目列表网格样式和行样式切换,软件重启后生效
+11 -4
View File
@@ -31,16 +31,23 @@ adb install my-tv.apk
* CHC高清三个电影频道 * CHC高清三个电影频道
* 地方频道 * 地方频道
* 收藏夹 * 收藏夹
* 自定义源
* 海外 * 海外
* 1.5.0 无法安装,1.5.1 可以安装 * 1.5.0 无法安装,1.5.1 可以安装
* 节目增加预告 * 节目增加预告
* 频道列表优化
* epg更新后菜单更新 * epg更新后菜单更新
* 防止菜单第一个获取焦点 * 隐藏频道
* 隐藏
* 亮度调节 * 亮度调节
* 音量调节 * 音量调节
* 错误页
* 频道列表页只点击一次即可
## 版权说明
本项目仅供学习研究,禁止用于商业用途,请于下载二十四小时内删除。
本项目可能随时终止,请大家谨慎使用,建议使用官方渠道进行观看。
本项目使用的部分代码、图片、文字等资源来源于网络,如有侵权,请联系删除。
## 赞赏 ## 赞赏
+8 -3
View File
@@ -112,11 +112,16 @@ dependencies {
implementation "com.squareup.retrofit2:converter-gson:$retrofit2_version" implementation "com.squareup.retrofit2:converter-gson:$retrofit2_version"
implementation "com.squareup.retrofit2:converter-protobuf:$retrofit2_version" implementation "com.squareup.retrofit2:converter-protobuf:$retrofit2_version"
implementation "com.squareup.retrofit2:retrofit:$retrofit2_version" implementation "com.squareup.retrofit2:retrofit:$retrofit2_version"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2"
implementation 'androidx.core:core-ktx:1.11.0-beta02'
implementation 'androidx.leanback:leanback:1.2.0-alpha02'
implementation 'com.github.bumptech.glide:glide:4.11.0' implementation 'com.github.bumptech.glide:glide:4.11.0'
implementation 'androidx.core:core-ktx:1.11.0-beta02'
implementation 'androidx.multidex:multidex:2.0.1'
implementation 'androidx.leanback:leanback:1.2.0-alpha02'
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.2" implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.6.2"
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2"
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0-RC") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0-RC")
implementation 'com.google.android.exoplayer:exoplayer-ui:2.13.3' implementation 'com.google.android.exoplayer:exoplayer-ui:2.13.3'
+1 -1
View File
@@ -14,7 +14,7 @@
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application <application
android:name=".MyApplication" android:name=".MyTvApplication"
android:allowBackup="true" android:allowBackup="true"
android:banner="@drawable/banner" android:banner="@drawable/banner"
android:icon="@drawable/logo" android:icon="@drawable/logo"
@@ -1,16 +1,15 @@
package com.lizongying.mytv package com.lizongying.mytv
import android.graphics.Color
import android.view.ContextThemeWrapper
import android.view.KeyEvent import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.animation.ScaleAnimation import android.view.animation.ScaleAnimation
import android.widget.ImageView import androidx.core.view.marginTop
import androidx.core.view.updatePadding import androidx.core.view.setPadding
import androidx.leanback.widget.ImageCardView
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.lizongying.mytv.databinding.CardBinding
import com.lizongying.mytv.models.TVListViewModel import com.lizongying.mytv.models.TVListViewModel
import com.lizongying.mytv.models.TVViewModel import com.lizongying.mytv.models.TVViewModel
@@ -25,15 +24,30 @@ class CardAdapter(
private var listener: ItemListener? = null private var listener: ItemListener? = null
private var focused: View? = null private var focused: View? = null
var visiable = false var focusable = false
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val cardView = object : val inflater = LayoutInflater.from(parent.context)
ImageCardView(ContextThemeWrapper(parent.context, R.style.CustomImageCardTheme)) {} val binding = CardBinding.inflate(inflater, parent, false)
val application = mainFragment.requireActivity().applicationContext as MyTvApplication
binding.card.layoutParams.width = application.px2Px(binding.card.layoutParams.width)
binding.card.layoutParams.height = application.px2Px(binding.card.layoutParams.height)
binding.icon.layoutParams.height = application.px2Px(binding.icon.layoutParams.height)
binding.icon.setPadding(application.px2Px(binding.icon.paddingTop))
binding.main.layoutParams.height = application.px2Px(binding.main.layoutParams.height)
binding.main.setPadding(application.px2Px(binding.main.paddingTop))
binding.title.textSize = application.px2PxFont(binding.title.textSize)
binding.desc.textSize = application.px2PxFont(binding.desc.textSize)
val layoutParams = binding.desc.layoutParams as ViewGroup.MarginLayoutParams
layoutParams.topMargin = application.px2Px(binding.desc.marginTop)
binding.desc.layoutParams = layoutParams
val cardView = binding.root
cardView.isFocusable = true cardView.isFocusable = true
cardView.isFocusableInTouchMode = true cardView.isFocusableInTouchMode = true
cardView.updatePadding(1, 0, 1, 0) return ViewHolder(cardView, binding)
return ViewHolder(cardView)
} }
fun clear() { fun clear() {
@@ -57,7 +71,7 @@ class CardAdapter(
val item = tvListViewModel.getTVViewModel(position) val item = tvListViewModel.getTVViewModel(position)
val tvViewModel = item as TVViewModel val tvViewModel = item as TVViewModel
val cardView = viewHolder.view as ImageCardView val cardView = viewHolder.view
cardView.tag = tvViewModel cardView.tag = tvViewModel
val onFocusChangeListener = View.OnFocusChangeListener { view, hasFocus -> val onFocusChangeListener = View.OnFocusChangeListener { view, hasFocus ->
@@ -65,16 +79,12 @@ class CardAdapter(
listener?.onItemHasFocus(item) listener?.onItemHasFocus(item)
focused = cardView focused = cardView
if (focusable) {
startScaleAnimation(cardView, 0.9f, 1.0f, 200) startScaleAnimation(cardView, 0.9f, 1.0f, 200)
// viewHolder.focus(true)
// if (mainFragment.shouldHasFocus(view.tag as TVViewModel)) { }
// } } else {
viewHolder.focus(false)
// if (visiable) {
// startScaleAnimation(cardView, 0.9f, 1.0f, 200)
// } else {
// visiable = true
// }
} }
} }
@@ -91,28 +101,35 @@ class CardAdapter(
false false
} }
cardView.titleText = tvViewModel.getTV().title viewHolder.binding.title.text = tvViewModel.getTV().title
viewHolder.binding.icon.let {
Glide.with(viewHolder.view.context) Glide.with(viewHolder.view.context)
.load(tvViewModel.getTV().logo) .load(tvViewModel.getTV().logo)
.centerInside() .centerInside()
.into(cardView.mainImageView) .into(it)
}
cardView.mainImageView.setBackgroundColor(Color.WHITE)
cardView.setMainImageScaleType(ImageView.ScaleType.CENTER_INSIDE)
val epg = tvViewModel.epg.value?.filter { it.beginTime < Utils.getDateTimestamp() } val epg = tvViewModel.epg.value?.filter { it.beginTime < Utils.getDateTimestamp() }
if (!epg.isNullOrEmpty()) { if (!epg.isNullOrEmpty()) {
cardView.contentText = epg.last().title viewHolder.binding.desc.text = epg.last().title
} else { } else {
cardView.contentText = "" viewHolder.binding.desc.text = ""
} }
} }
override fun getItemCount() = tvListViewModel.size() override fun getItemCount() = tvListViewModel.size()
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { class ViewHolder(itemView: View, var binding: CardBinding) : RecyclerView.ViewHolder(itemView) {
val view = itemView val view = itemView
fun focus(hasFocus: Boolean) {
if (hasFocus) {
binding.main.setBackgroundResource(R.drawable.rounded_light_bottom)
} else {
binding.main.setBackgroundResource(R.drawable.rounded_dark_bottom)
}
}
} }
fun toPosition(position: Int) { fun toPosition(position: Int) {
@@ -1,10 +1,13 @@
package com.lizongying.mytv package com.lizongying.mytv
import android.content.res.Resources
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.view.marginRight
import androidx.core.view.marginTop
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.lizongying.mytv.databinding.ChannelBinding import com.lizongying.mytv.databinding.ChannelBinding
import com.lizongying.mytv.models.TVViewModel import com.lizongying.mytv.models.TVViewModel
@@ -14,8 +17,9 @@ class ChannelFragment : Fragment() {
private val binding get() = _binding!! private val binding get() = _binding!!
private val handler = Handler() private val handler = Handler()
private val delay: Long = 3000 private val delay: Long = 5000
private var channel = 0 private var channel = 0
private var channelCount = 0
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
@@ -23,6 +27,40 @@ class ChannelFragment : Fragment() {
): View { ): View {
_binding = ChannelBinding.inflate(inflater, container, false) _binding = ChannelBinding.inflate(inflater, container, false)
_binding!!.root.visibility = View.GONE _binding!!.root.visibility = View.GONE
val application = requireActivity().applicationContext as MyTvApplication
val width = application.getWidth()
val height = application.getHeight()
val ratio = 16f / 9f
if (width.toFloat() / height > ratio) {
val x =
((Resources.getSystem().displayMetrics.widthPixels - height * ratio) / 2).toInt()
val originalLayoutParams =
binding.channel.layoutParams as ViewGroup.MarginLayoutParams
originalLayoutParams.rightMargin += x
binding.channel.layoutParams = originalLayoutParams
}
if (width.toFloat() / height < ratio) {
val y =
((height - Resources.getSystem().displayMetrics.widthPixels / ratio) / 2).toInt()
val originalLayoutParams =
binding.channel.layoutParams as ViewGroup.MarginLayoutParams
originalLayoutParams.topMargin += y
binding.channel.layoutParams = originalLayoutParams
}
binding.channel.layoutParams.width = application.px2Px(binding.channel.layoutParams.width)
binding.channel.layoutParams.height = application.px2Px(binding.channel.layoutParams.height)
val layoutParams = binding.channel.layoutParams as ViewGroup.MarginLayoutParams
layoutParams.topMargin = application.px2Px(binding.channel.marginTop)
layoutParams.rightMargin = application.px2Px(binding.channel.marginRight)
binding.channel.layoutParams = layoutParams
binding.content.textSize = application.px2PxFont(binding.content.textSize)
(activity as MainActivity).fragmentReady("ChannelFragment") (activity as MainActivity).fragmentReady("ChannelFragment")
return binding.root return binding.root
} }
@@ -30,20 +68,21 @@ class ChannelFragment : Fragment() {
fun show(tvViewModel: TVViewModel) { fun show(tvViewModel: TVViewModel) {
handler.removeCallbacks(hideRunnable) handler.removeCallbacks(hideRunnable)
handler.removeCallbacks(playRunnable) handler.removeCallbacks(playRunnable)
binding.channelContent.text = (tvViewModel.getTV().id.plus(1)).toString() binding.content.text = (tvViewModel.getTV().id.plus(1)).toString()
view?.visibility = View.VISIBLE view?.visibility = View.VISIBLE
handler.postDelayed(hideRunnable, delay) handler.postDelayed(hideRunnable, delay)
} }
fun show(channel: String) { fun show(channel: String) {
if (binding.channelContent.text.length > 1) { if (channelCount > 1) {
return return
} }
this.channel = "${binding.channelContent.text}$channel".toInt() channelCount++
this.channel = "${this.channel}$channel".toInt()
handler.removeCallbacks(hideRunnable) handler.removeCallbacks(hideRunnable)
handler.removeCallbacks(playRunnable) handler.removeCallbacks(playRunnable)
if (binding.channelContent.text == "") { if (channelCount < 2) {
binding.channelContent.text = channel binding.content.text = "${this.channel}"
view?.visibility = View.VISIBLE view?.visibility = View.VISIBLE
handler.postDelayed(playRunnable, delay) handler.postDelayed(playRunnable, delay)
} else { } else {
@@ -65,14 +104,18 @@ class ChannelFragment : Fragment() {
} }
private val hideRunnable = Runnable { private val hideRunnable = Runnable {
binding.channelContent.text = "" binding.content.text = ""
view?.visibility = View.GONE view?.visibility = View.GONE
channel = 0
channelCount = 0
} }
private val playRunnable = Runnable { private val playRunnable = Runnable {
(activity as MainActivity).play(channel - 1) (activity as MainActivity).play(channel - 1)
binding.channelContent.text = "" binding.content.text = ""
view?.visibility = View.GONE view?.visibility = View.GONE
channel = 0
channelCount = 0
} }
override fun onDestroyView() { override fun onDestroyView() {
+1 -1
View File
@@ -50,7 +50,7 @@ val Context.appVersionCode: Long
* Return the version name of the app which is defined in build.gradle. * Return the version name of the app which is defined in build.gradle.
* eg:1.0.0 * eg:1.0.0
*/ */
val Context.appVersionName: String get() = packageInfo.versionName ?: "" val Context.appVersionName: String get() = packageInfo.versionName
val Context.appSignature: String val Context.appSignature: String
get() { get() {
@@ -1,54 +0,0 @@
package com.lizongying.mytv
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Rect
import android.view.View
import androidx.core.content.ContextCompat
import androidx.leanback.widget.ImageCardView
import androidx.recyclerview.widget.RecyclerView
class GrayOverlayItemDecoration(private val context: Context) : RecyclerView.ItemDecoration() {
private val grayOverlayPaint = Paint().apply {
color = ContextCompat.getColor(context, R.color.gray_overlay)
style = Paint.Style.FILL
}
override fun onDrawOver(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
super.onDrawOver(c, parent, state)
val childCount = parent.childCount
for (i in 0 until childCount) {
val child = parent.getChildAt(i)
if (!child.hasFocus()) {
(child as ImageCardView).setInfoAreaBackgroundColor(ContextCompat.getColor(context, R.color.blur))
// child.alpha = 0.5f
// 计算遮罩层的大小
// val overlayRect = Rect(
// child.left,
// child.top,
// child.right,
// child.bottom
// )
// // 绘制灰色遮罩层
// c.drawRect(overlayRect, grayOverlayPaint)
} else {
(child as ImageCardView).setInfoAreaBackgroundColor(ContextCompat.getColor(context, R.color.focus))
// child.alpha = 1f
}
}
}
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
// 在此处设置偏移量为0,以防止遮罩层影响项的布局
outRect.setEmpty()
}
}
@@ -1,11 +1,16 @@
package com.lizongying.mytv package com.lizongying.mytv
import android.content.res.Resources
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.util.Log import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.view.marginBottom
import androidx.core.view.marginLeft
import androidx.core.view.marginTop
import androidx.core.view.setPadding
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.lizongying.mytv.databinding.InfoBinding import com.lizongying.mytv.databinding.InfoBinding
@@ -16,31 +21,66 @@ class InfoFragment : Fragment() {
private val binding get() = _binding!! private val binding get() = _binding!!
private val handler = Handler() private val handler = Handler()
private val delay: Long = 3000 private val delay: Long = 5000
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
_binding = InfoBinding.inflate(inflater, container, false) _binding = InfoBinding.inflate(inflater, container, false)
val application = requireActivity().applicationContext as MyTvApplication
val width = application.getWidth()
val height = application.getHeight()
val ratio = 16f / 9f
if (width.toFloat() / height < ratio) {
val y =
((height - Resources.getSystem().displayMetrics.widthPixels / ratio) / 2).toInt()
val originalLayoutParams = binding.info.layoutParams as ViewGroup.MarginLayoutParams
originalLayoutParams.bottomMargin += y
binding.info.layoutParams = originalLayoutParams
}
binding.info.layoutParams.width = application.px2Px(binding.info.layoutParams.width)
binding.info.layoutParams.height = application.px2Px(binding.info.layoutParams.height)
val layoutParams = binding.info.layoutParams as ViewGroup.MarginLayoutParams
layoutParams.bottomMargin = application.px2Px(binding.info.marginBottom)
binding.info.layoutParams = layoutParams
binding.logo.layoutParams.width = application.px2Px(binding.logo.layoutParams.width)
binding.logo.setPadding(application.px2Px(binding.logo.paddingTop))
binding.main.layoutParams.width = application.px2Px(binding.main.layoutParams.width)
binding.main.setPadding(application.px2Px(binding.main.paddingTop))
val layoutParamsMain = binding.main.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsMain.leftMargin = application.px2Px(binding.main.marginLeft)
binding.main.layoutParams = layoutParamsMain
val layoutParamsDesc = binding.desc.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsDesc.topMargin = application.px2Px(binding.desc.marginTop)
binding.desc.layoutParams = layoutParamsDesc
binding.title.textSize = application.px2PxFont(binding.title.textSize)
binding.desc.textSize = application.px2PxFont(binding.desc.textSize)
_binding!!.root.visibility = View.GONE _binding!!.root.visibility = View.GONE
(activity as MainActivity).fragmentReady("InfoFragment") (activity as MainActivity).fragmentReady("InfoFragment")
return binding.root return binding.root
} }
fun show(tvViewModel: TVViewModel) { fun show(tvViewModel: TVViewModel) {
binding.textView.text = tvViewModel.getTV().title binding.title.text = tvViewModel.getTV().title
Glide.with(this) Glide.with(this)
.load(tvViewModel.getTV().logo) .load(tvViewModel.getTV().logo)
.into(binding.infoLogo) .into(binding.logo)
Log.i(TAG, "${tvViewModel.getTV().title} ${tvViewModel.epg.value}") Log.i(TAG, "${tvViewModel.getTV().title} ${tvViewModel.epg.value}")
val epg = tvViewModel.epg.value?.filter { it.beginTime < Utils.getDateTimestamp() } val epg = tvViewModel.epg.value?.filter { it.beginTime < Utils.getDateTimestamp() }
if (!epg.isNullOrEmpty()) { if (!epg.isNullOrEmpty()) {
binding.infoDesc.text = epg.last().title binding.desc.text = epg.last().title
} else { } else {
binding.infoDesc.text = "" binding.desc.text = ""
} }
handler.removeCallbacks(removeRunnable) handler.removeCallbacks(removeRunnable)
@@ -0,0 +1,29 @@
package com.lizongying.mytv
import android.content.Context
import android.graphics.Rect
import android.view.View
import androidx.recyclerview.widget.RecyclerView
class ItemDecoration(context: Context) : RecyclerView.ItemDecoration() {
private var application: MyTvApplication
init {
application = context.applicationContext as MyTvApplication
}
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
super.getItemOffsets(outRect, view, parent, state)
val space = application.dp2Px(5)
outRect.top = space
outRect.bottom = space
outRect.left = space
outRect.right = space
}
}
@@ -42,12 +42,13 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
private val delayHideSetting: Long = 10000 private val delayHideSetting: Long = 10000
init { init {
Utils.setRequestListener(this)
}
private fun syncTime() {
lifecycleScope.launch(Dispatchers.IO) { lifecycleScope.launch(Dispatchers.IO) {
val utilsJob = async(start = CoroutineStart.LAZY) { Utils.init() } val utilsJob = async(start = CoroutineStart.LAZY) { Utils.init() }
utilsJob.start() utilsJob.start()
// utilsJob.await()
} }
} }
@@ -93,7 +94,6 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
Log.i(TAG, "net ${Build.VERSION.SDK_INT}") Log.i(TAG, "net ${Build.VERSION.SDK_INT}")
ready++ ready++
} }
} }
fun showInfoFragment(tvViewModel: TVViewModel) { fun showInfoFragment(tvViewModel: TVViewModel) {
@@ -119,7 +119,6 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
fun play(tvViewModel: TVViewModel) { fun play(tvViewModel: TVViewModel) {
playerFragment.play(tvViewModel) playerFragment.play(tvViewModel)
mainFragment.view?.requestFocus()
} }
fun play(itemPosition: Int) { fun play(itemPosition: Int) {
@@ -134,14 +133,6 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
mainFragment.next() mainFragment.next()
} }
private fun prevSource() {
// mainFragment.prevSource()
}
private fun nextSource() {
// mainFragment.nextSource()
}
fun switchMainFragment() { fun switchMainFragment() {
val transaction = supportFragmentManager.beginTransaction() val transaction = supportFragmentManager.beginTransaction()
@@ -192,7 +183,7 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
fun fragmentReady(tag: String) { fun fragmentReady(tag: String) {
ready++ ready++
Log.i(TAG, "ready $tag $ready ") Log.i(TAG, "ready $tag $ready ")
if (ready == 6) { if (ready == 7) {
mainFragment.fragmentReady() mainFragment.fragmentReady()
showTime() showTime()
} }
@@ -205,6 +196,7 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
} else { } else {
timeFragment.hide() timeFragment.hide()
} }
mainFragment.changeStyle()
} }
override fun onTouchEvent(event: MotionEvent?): Boolean { override fun onTouchEvent(event: MotionEvent?): Boolean {
@@ -325,7 +317,7 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
return return
} }
if (!settingFragment.isHidden) { if (settingFragment.isVisible) {
hideSettingFragment() hideSettingFragment()
return return
} }
@@ -484,7 +476,8 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
private fun getAppSignature() = this.appSignature private fun getAppSignature() = this.appSignature
override fun onStart() { override fun onStart() {
Log.i(TAG, "onStart") Log.i(TAG, "onStart MainActivity")
syncTime()
super.onStart() super.onStart()
} }
@@ -1,5 +1,6 @@
package com.lizongying.mytv package com.lizongying.mytv
import android.content.res.Resources
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import android.view.KeyEvent import android.view.KeyEvent
@@ -7,12 +8,14 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast import android.widget.Toast
import androidx.core.view.marginBottom
import androidx.core.view.marginLeft
import androidx.core.view.marginTop
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import com.lizongying.mytv.Utils.dpToPx
import com.lizongying.mytv.api.YSP import com.lizongying.mytv.api.YSP
import com.lizongying.mytv.databinding.MenuBinding import com.lizongying.mytv.databinding.MenuBinding
import com.lizongying.mytv.databinding.RowBinding import com.lizongying.mytv.databinding.RowBinding
@@ -36,12 +39,46 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
private var lastVideoUrl = "" private var lastVideoUrl = ""
private lateinit var application: MyTvApplication
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
_binding = MenuBinding.inflate(inflater, container, false) _binding = MenuBinding.inflate(inflater, container, false)
application = requireActivity().applicationContext as MyTvApplication
val width = application.getWidth()
val height = application.getHeight()
val ratio = 16f / 9f
if (width.toFloat() / height > ratio) {
val x =
((Resources.getSystem().displayMetrics.widthPixels - height * ratio) / 2).toInt()
val originalLayoutParams =
binding.scroll.layoutParams as ViewGroup.MarginLayoutParams
originalLayoutParams.leftMargin += x
originalLayoutParams.rightMargin += x
binding.scroll.layoutParams = originalLayoutParams
Log.i(
TAG,
"binding.scroll ${Resources.getSystem().displayMetrics.widthPixels} ${height * ratio}"
)
}
if (width.toFloat() / height < ratio) {
val y =
((height - Resources.getSystem().displayMetrics.widthPixels / ratio) / 2).toInt()
val originalLayoutParams =
binding.scroll.layoutParams as ViewGroup.MarginLayoutParams
originalLayoutParams.topMargin += y
originalLayoutParams.bottomMargin += y
binding.scroll.layoutParams = originalLayoutParams
}
binding.menu.setOnClickListener { binding.menu.setOnClickListener {
hideSelf() hideSelf()
} }
@@ -82,46 +119,55 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
val adapter = val adapter =
CardAdapter( CardAdapter(
itemBinding.rowItems, itemBinding.items,
this, this,
tvListViewModelCurrent, tvListViewModelCurrent,
) )
rowList.add(itemBinding.rowItems) rowList.add(itemBinding.items)
adapter.setItemListener(this) adapter.setItemListener(this)
itemBinding.rowHeader.text = k itemBinding.header.text = k
itemBinding.rowItems.tag = idx.toInt() itemBinding.items.tag = idx.toInt()
itemBinding.rowItems.adapter = adapter itemBinding.items.adapter = adapter
itemBinding.rowItems.addOnScrollListener(object : RecyclerView.OnScrollListener() { itemBinding.items.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) { override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy) super.onScrolled(recyclerView, dx, dy)
(activity as MainActivity).mainActive() (activity as MainActivity).mainActive()
} }
}) })
val itemDecoration = context?.let { GrayOverlayItemDecoration(it) } val itemDecoration = context?.let { ItemDecoration(it) }
if (itemDecoration != null) { if (itemDecoration != null) {
itemBinding.rowItems.addItemDecoration(itemDecoration) itemBinding.items.addItemDecoration(itemDecoration)
} }
if (SP.grid) { if (SP.grid) {
itemBinding.rowItems.layoutManager = itemBinding.items.layoutManager =
GridLayoutManager(context, 6) GridLayoutManager(context, 6)
itemBinding.rowItems.layoutParams.height = itemBinding.items.layoutParams.height =
dpToPx(92 * ((tvListViewModelCurrent.size() + 6 - 1) / 6)) application.dp2Px(110 * ((tvListViewModelCurrent.size() + 6 - 1) / 6) + 5)
} else { } else {
itemBinding.rowItems.layoutManager = itemBinding.items.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
} }
val layoutParams = itemBinding.row.layoutParams as ViewGroup.MarginLayoutParams val layoutParams = itemBinding.row.layoutParams as ViewGroup.MarginLayoutParams
layoutParams.topMargin = dpToPx(11F) layoutParams.topMargin = application.dp2Px(11)
itemBinding.row.layoutParams = layoutParams itemBinding.row.layoutParams = layoutParams
itemBinding.row.setOnClickListener{ itemBinding.row.setOnClickListener {
hideSelf() hideSelf()
} }
val layoutParamsHeader =
itemBinding.header.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsHeader.topMargin = application.px2Px(itemBinding.header.marginTop)
layoutParamsHeader.bottomMargin = application.px2Px(itemBinding.header.marginBottom)
layoutParamsHeader.leftMargin = application.px2Px(itemBinding.header.marginLeft)
itemBinding.header.layoutParams = layoutParamsHeader
itemBinding.header.textSize = application.px2PxFont(itemBinding.header.textSize)
content.addView(itemBinding.row) content.addView(itemBinding.row)
idx++ idx++
@@ -182,8 +228,24 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
} }
} }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { fun changeStyle() {
super.onViewCreated(view, savedInstanceState) if (SP.grid) {
for (i in rowList) {
if (i is RecyclerView) {
i.layoutManager = GridLayoutManager(context, 6)
i.layoutParams.height =
application.dp2Px(110 * (((i.adapter as CardAdapter).getItemCount() + 6 - 1) / 6) + 5)
}
}
} else {
for (i in rowList) {
if (i is RecyclerView) {
i.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
i.layoutParams.height = application.dp2Px(110 + 5)
}
}
}
} }
override fun onKey(keyCode: Int): Boolean { override fun onKey(keyCode: Int): Boolean {
@@ -210,7 +272,10 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
for (i in rowList) { for (i in rowList) {
if (i.tag as Int != row) { if (i.tag as Int != row) {
((i as RecyclerView).adapter as CardAdapter).focusable = false
((i as RecyclerView).adapter as CardAdapter).clear() ((i as RecyclerView).adapter as CardAdapter).clear()
} else {
((i as RecyclerView).adapter as CardAdapter).focusable = true
} }
} }
@@ -227,7 +292,7 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
if (itemPosition != tvViewModel.getTV().id) { if (itemPosition != tvViewModel.getTV().id) {
itemPosition = tvViewModel.getTV().id itemPosition = tvViewModel.getTV().id
tvListViewModel.setItemPosition(itemPosition) tvListViewModel.setItemPosition(itemPosition)
tvListViewModel.getTVViewModel(itemPosition)?.changed() tvListViewModel.getTVViewModel(itemPosition)?.changed("menu")
} }
(activity as? MainActivity)?.switchMainFragment() (activity as? MainActivity)?.switchMainFragment()
} }
@@ -274,8 +339,7 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
} }
fun fragmentReady() { fun fragmentReady() {
// request.fetchPage() tvListViewModel.getTVViewModel(itemPosition)?.changed("init")
tvListViewModel.getTVViewModel(itemPosition)?.changed()
tvListViewModel.tvListViewModel.value?.forEach { tvViewModel -> tvListViewModel.tvListViewModel.value?.forEach { tvViewModel ->
updateEPG(tvViewModel) updateEPG(tvViewModel)
@@ -287,7 +351,7 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
if (itemPosition > -1 && itemPosition < tvListViewModel.size()) { if (itemPosition > -1 && itemPosition < tvListViewModel.size()) {
this.itemPosition = itemPosition this.itemPosition = itemPosition
tvListViewModel.setItemPosition(itemPosition) tvListViewModel.setItemPosition(itemPosition)
tvListViewModel.getTVViewModel(itemPosition)?.changed() tvListViewModel.getTVViewModel(itemPosition)?.changed("num")
} else { } else {
Toast.makeText(context, "频道不存在", Toast.LENGTH_SHORT).show() Toast.makeText(context, "频道不存在", Toast.LENGTH_SHORT).show()
} }
@@ -301,7 +365,7 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
itemPosition = tvListViewModel.size() - 1 itemPosition = tvListViewModel.size() - 1
} }
tvListViewModel.setItemPosition(itemPosition) tvListViewModel.setItemPosition(itemPosition)
tvListViewModel.getTVViewModel(itemPosition)?.changed() tvListViewModel.getTVViewModel(itemPosition)?.changed("prev")
} }
} }
@@ -312,7 +376,7 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
itemPosition = 0 itemPosition = 0
} }
tvListViewModel.setItemPosition(itemPosition) tvListViewModel.setItemPosition(itemPosition)
tvListViewModel.getTVViewModel(itemPosition)?.changed() tvListViewModel.getTVViewModel(itemPosition)?.changed("next")
} }
} }
@@ -337,6 +401,7 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
} }
override fun onHiddenChanged(hidden: Boolean) { override fun onHiddenChanged(hidden: Boolean) {
Log.i(TAG, "onHiddenChanged $hidden")
super.onHiddenChanged(hidden) super.onHiddenChanged(hidden)
if (!hidden) { if (!hidden) {
val tvModel = tvListViewModel.getTVViewModel(itemPosition) val tvModel = tvListViewModel.getTVViewModel(itemPosition)
@@ -345,15 +410,16 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
Log.i(TAG, "toPosition $rowPosition $itemPosition") Log.i(TAG, "toPosition $rowPosition $itemPosition")
for (i in rowList) { for (i in rowList) {
if (i.tag as Int == rowPosition) { if (i.tag as Int == rowPosition) {
((i as RecyclerView).adapter as CardAdapter).focusable = true
((i as RecyclerView).adapter as CardAdapter).toPosition(itemPosition!!) ((i as RecyclerView).adapter as CardAdapter).toPosition(itemPosition!!)
break break
} }
} }
} else { } else {
view?.post { view?.post {
// for (i in rowList) { for (i in rowList) {
// ((i as RecyclerView).adapter as CardAdapter).visiable = false ((i as RecyclerView).adapter as CardAdapter).focusable = false
// } }
} }
} }
} }
@@ -1,6 +0,0 @@
package com.lizongying.mytv
import android.app.Application
class MyApplication : Application() {
}
@@ -0,0 +1,95 @@
package com.lizongying.mytv
import android.app.Application
import android.content.Context
import android.content.res.Resources
import android.util.DisplayMetrics
import android.view.WindowManager
import androidx.multidex.MultiDex
class MyTvApplication : Application() {
private lateinit var displayMetrics: DisplayMetrics
private lateinit var realDisplayMetrics: DisplayMetrics
private var width = 0
private var height = 0
private var deviation = 0
private var ratio = 1.0
private var density = 2.0f
private var scale = 1.0f
override fun onCreate() {
super.onCreate()
displayMetrics = DisplayMetrics()
realDisplayMetrics = DisplayMetrics()
val windowManager = getSystemService(Context.WINDOW_SERVICE) as WindowManager
windowManager.defaultDisplay.getMetrics(displayMetrics)
windowManager.defaultDisplay.getRealMetrics(realDisplayMetrics)
if (realDisplayMetrics.heightPixels > realDisplayMetrics.widthPixels) {
width = realDisplayMetrics.heightPixels
height = realDisplayMetrics.widthPixels
} else {
width = realDisplayMetrics.widthPixels
height = realDisplayMetrics.heightPixels
}
density = displayMetrics.density
ratio = if ((width.toDouble() / height) < (16.0 / 9)) {
width * 2 / 1920.0 / density
} else {
height * 2 / 1080.0 / density
}
deviation = width - Resources.getSystem().displayMetrics.widthPixels
scale = Resources.getSystem().displayMetrics.scaledDensity
}
fun getDisplayMetrics(): DisplayMetrics {
return displayMetrics
}
fun getRealDisplayMetrics(): DisplayMetrics {
return realDisplayMetrics
}
fun getWidth(): Int {
return width
}
fun getDeviation(): Int {
return deviation
}
fun getHeight(): Int {
return height
}
fun getRatio(): Double {
return ratio
}
fun dp2Px(dp: Int): Int {
return (dp * ratio * density + 0.5f).toInt()
}
fun px2Px(px: Int): Int {
return (px * ratio + 0.5f).toInt()
}
fun px2PxFont(px: Float): Float {
return (px * ratio / scale).toFloat()
}
fun sp2Px(sp: Float): Float {
return (sp * ratio * scale).toFloat()
}
override fun attachBaseContext(base: Context?) {
super.attachBaseContext(base)
MultiDex.install(base)
}
}
@@ -80,7 +80,7 @@ class PlayerFragment : Fragment(), SurfaceHolder.Callback {
super.onPlayerError(error) super.onPlayerError(error)
Log.e(TAG, "PlaybackException $error") Log.e(TAG, "PlaybackException $error")
tvViewModel?.changed() tvViewModel?.changed("retry")
} }
}) })
} }
@@ -54,7 +54,7 @@ object Request {
private var token = "" private var token = ""
private var tokenFH = "" private var tokenFH = ""
private var needAuth = false private var needAuth = true
private var needToken = false private var needToken = false
private val handler = Handler(Looper.getMainLooper()) private val handler = Handler(Looper.getMainLooper())
@@ -590,7 +590,7 @@ object Request {
val randomNumber = Random.nextDouble() val randomNumber = Random.nextDouble()
val url = tvModel.getTV().videoUrl.first() val url = tvModel.getTV().videoUrl.first()
var r = KvcollectRequest( val r = KvcollectRequest(
guid = guid, guid = guid,
prog = sid, prog = sid,
viewid = sid, viewid = sid,
@@ -605,27 +605,10 @@ object Request {
_dc = randomNumber, _dc = randomNumber,
) )
var e = val e =
"BossId=${r.BossId}&Pwd=${r.Pwd}&_dc=${r._dc}&cdn=${r.cdn}&cmd=${r.cmd}&defn=${r.defn}&downspeed=${r.downspeed}&durl=${r.durl}&errcode=${r.errcode}&fact1=${r.fact1}&firstreport=${r.firstreport}&fplayerver=${r.fplayerver}&ftime=${r.ftime}&geturltime=6&guid=${r.guid}&hc_openid=${r.hc_openid}&hh_ua=${r.hh_ua}&live_type=${r.live_type}&livepid=${r.livepid}&login_type=${r.login_type}&open_id=&openid=${r.openid}&platform=${r.platform}&playno=${r.playno}&prd=${r.prd}&prog=${r.prog}&rand_str=${r.rand_str}&sRef=${r.sRef}&sUrl=${r.sUrl}&sdtfrom=${r.sdtfrom}&seq=${r.seq}&url=${r.url}&viewid=${r.viewid}" "BossId=${r.BossId}&Pwd=${r.Pwd}&_dc=${r._dc}&cdn=${r.cdn}&cmd=${r.cmd}&defn=${r.defn}&downspeed=${r.downspeed}&durl=${r.durl}&errcode=${r.errcode}&fact1=${r.fact1}&firstreport=${r.firstreport}&fplayerver=${r.fplayerver}&ftime=${r.ftime}&geturltime=6&guid=${r.guid}&hc_openid=${r.hc_openid}&hh_ua=${r.hh_ua}&live_type=${r.live_type}&livepid=${r.livepid}&login_type=${r.login_type}&open_id=&openid=${r.openid}&platform=${r.platform}&playno=${r.playno}&prd=${r.prd}&prog=${r.prog}&rand_str=${r.rand_str}&sRef=${r.sRef}&sUrl=${r.sUrl}&sdtfrom=${r.sdtfrom}&seq=${r.seq}&url=${r.url}&viewid=${r.viewid}"
println(e)
r.signature = YSP.getAuthSignature(e) r.signature = YSP.getAuthSignature(e)
println(r.signature) callBtracePage = yspBtraceService2.kvcollect2(r)
// val ttt = """{"BossId":2727,"Pwd":1424084450,"prog":"2022576801","playno":"BEoZw3cpZh","guid":"luccvoyr_58va8i3cqw6","hh_ua":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36","cdn":"waibao","sdtfrom":"ysp_pc_01","prd":60000,"platform":"5910204","errcode":"","durl":"https://outlivecloud-cdn.ysp.cctv.cn/906028A94D533483FE8BAC5CF4DB6CC70753E25A93EF3EC50988538DEDBF10161D1EA8F67C916EE41BA9D891D7893C69500B3F1A37CA814D2EE19341197360196CD9CCF327949104097C904643D493EB5A9B588EC28A2FAC1C8E30F8EE330DB2364B0DEC0124F6990A83773FF283489A/2022576803.m3u8?from=player&svrtime=1713365896&pid=600001859&cdn=5401&revoi=6E400EC7436C79D49BA06E61333D31FB8915F3484D9426FE4CCC4DE01CB8FD1DF473A8F416EF1107B669B0A9447F913272789A827EDD3DC0FE88534D9B59A35669678946589AA4D246F8F248F7C33AB08CE72FA0A73FE7F1F9FD2091D30176895CB8BD44A5B85FAD9579C700CB2AFD8D0939574B2A3EFF4C1B237DFF3E0CD3E194662F9FDEE48D1ACD7BDFAB01868B220743021C40E0EA5514ECCF396B509DA1&app_id=519748109&guid=luccvoyr_58va8i3cqw6&ysign=bb79232986c5429600d76cfedb1d5978&ytime=1713365896&ytype=1","firstreport":1,"sUrl":"https://www.yangshipin.cn/#/tv/home?pid=600001859","sRef":"","fplayerver":"100","livepid":"600001859","viewid":"2022576801","seq":0,"cmd":263,"login_type":"","geturltime":6,"downspeed":1.75,"hc_openid":"","open_id":"","defn":"fhd","fact1":"ysp_pc_live_b","openid":"","_dc":0.7140416315131102,"live_type":"","ftime":"2024-04-17 22:58:31","url":"https://outlivecloud-cdn.ysp.cctv.cn/906028A94D533483FE8BAC5CF4DB6CC70753E25A93EF3EC50988538DEDBF10161D1EA8F67C916EE41BA9D891D7893C69500B3F1A37CA814D2EE19341197360196CD9CCF327949104097C904643D493EB5A9B588EC28A2FAC1C8E30F8EE330DB2364B0DEC0124F6990A83773FF283489A/2022576803.m3u8?from=player&svrtime=1713365896&pid=600001859&cdn=5401&revoi=6E400EC7436C79D49BA06E61333D31FB8915F3484D9426FE4CCC4DE01CB8FD1DF473A8F416EF1107B669B0A9447F913272789A827EDD3DC0FE88534D9B59A35669678946589AA4D246F8F248F7C33AB08CE72FA0A73FE7F1F9FD2091D30176895CB8BD44A5B85FAD9579C700CB2AFD8D0939574B2A3EFF4C1B237DFF3E0CD3E194662F9FDEE48D1ACD7BDFAB01868B220743021C40E0EA5514ECCF396B509DA1&app_id=519748109&guid=luccvoyr_58va8i3cqw6&ysign=bb79232986c5429600d76cfedb1d5978&ytime=1713365896&ytype=1","rand_str":"oKkkZs8lON"}"""
// val gson = Gson()
// r = gson.fromJson(ttt, KvcollectRequest::class.java)
//
// e =
// "BossId=${r.BossId}&Pwd=${r.Pwd}&_dc=${r._dc}&cdn=${r.cdn}&cmd=${r.cmd}&defn=${r.defn}&downspeed=${r.downspeed}&durl=${r.durl}&errcode=${r.errcode}&fact1=${r.fact1}&firstreport=${r.firstreport}&fplayerver=${r.fplayerver}&ftime=${r.ftime}&geturltime=6&guid=${r.guid}&hc_openid=${r.hc_openid}&hh_ua=${r.hh_ua}&live_type=${r.live_type}&livepid=${r.livepid}&login_type=${r.login_type}&open_id=&openid=${r.openid}&platform=${r.platform}&playno=${r.playno}&prd=${r.prd}&prog=${r.prog}&rand_str=${r.rand_str}&sRef=${r.sRef}&sUrl=${r.sUrl}&sdtfrom=${r.sdtfrom}&seq=${r.seq}&url=${r.url}&viewid=${r.viewid}"
// println(e)
// e = "BossId=2727&Pwd=1424084450&_dc=0.7140416315131102&cdn=waibao&cmd=263&defn=fhd&downspeed=1.75&durl=https://outlivecloud-cdn.ysp.cctv.cn/906028A94D533483FE8BAC5CF4DB6CC70753E25A93EF3EC50988538DEDBF10161D1EA8F67C916EE41BA9D891D7893C69500B3F1A37CA814D2EE19341197360196CD9CCF327949104097C904643D493EB5A9B588EC28A2FAC1C8E30F8EE330DB2364B0DEC0124F6990A83773FF283489A/2022576803.m3u8?from=player&svrtime=1713365896&pid=600001859&cdn=5401&revoi=6E400EC7436C79D49BA06E61333D31FB8915F3484D9426FE4CCC4DE01CB8FD1DF473A8F416EF1107B669B0A9447F913272789A827EDD3DC0FE88534D9B59A35669678946589AA4D246F8F248F7C33AB08CE72FA0A73FE7F1F9FD2091D30176895CB8BD44A5B85FAD9579C700CB2AFD8D0939574B2A3EFF4C1B237DFF3E0CD3E194662F9FDEE48D1ACD7BDFAB01868B220743021C40E0EA5514ECCF396B509DA1&app_id=519748109&guid=luccvoyr_58va8i3cqw6&ysign=bb79232986c5429600d76cfedb1d5978&ytime=1713365896&ytype=1&errcode=&fact1=ysp_pc_live_b&firstreport=1&fplayerver=100&ftime=2024-04-17 22:58:31&geturltime=6&guid=luccvoyr_58va8i3cqw6&hc_openid=&hh_ua=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36&live_type=&livepid=600001859&login_type=&open_id=&openid=&platform=5910204&playno=BEoZw3cpZh&prd=60000&prog=2022576801&rand_str=oKkkZs8lON&sRef=&sUrl=https://www.yangshipin.cn/#/tv/home?pid=600001859&sdtfrom=ysp_pc_01&seq=0&url=https://outlivecloud-cdn.ysp.cctv.cn/906028A94D533483FE8BAC5CF4DB6CC70753E25A93EF3EC50988538DEDBF10161D1EA8F67C916EE41BA9D891D7893C69500B3F1A37CA814D2EE19341197360196CD9CCF327949104097C904643D493EB5A9B588EC28A2FAC1C8E30F8EE330DB2364B0DEC0124F6990A83773FF283489A/2022576803.m3u8?from=player&svrtime=1713365896&pid=600001859&cdn=5401&revoi=6E400EC7436C79D49BA06E61333D31FB8915F3484D9426FE4CCC4DE01CB8FD1DF473A8F416EF1107B669B0A9447F913272789A827EDD3DC0FE88534D9B59A35669678946589AA4D246F8F248F7C33AB08CE72FA0A73FE7F1F9FD2091D30176895CB8BD44A5B85FAD9579C700CB2AFD8D0939574B2A3EFF4C1B237DFF3E0CD3E194662F9FDEE48D1ACD7BDFAB01868B220743021C40E0EA5514ECCF396B509DA1&app_id=519748109&guid=luccvoyr_58va8i3cqw6&ysign=bb79232986c5429600d76cfedb1d5978&ytime=1713365896&ytype=1&viewid=2022576801"
// println(e)
// r.signature = YSP.getAuthSignature(e)
// println(r.signature)
callBtracePage = yspBtraceService2.kvcollect2(
r
)
callBtracePage?.enqueue(object : Callback<Void> { callBtracePage?.enqueue(object : Callback<Void> {
override fun onResponse(call: Call<Void>, response: Response<Void>) { override fun onResponse(call: Call<Void>, response: Response<Void>) {
if (response.isSuccessful) { if (response.isSuccessful) {
@@ -5,6 +5,8 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.view.WindowManager import android.view.WindowManager
import androidx.core.view.marginEnd
import androidx.core.view.marginTop
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import com.lizongying.mytv.databinding.SettingBinding import com.lizongying.mytv.databinding.SettingBinding
@@ -87,6 +89,70 @@ class SettingFragment : DialogFragment() {
) )
) )
val application = requireActivity().applicationContext as MyTvApplication
binding.content.layoutParams.width =
application.px2Px(binding.content.layoutParams.width)
binding.content.setPadding(
application.px2Px(binding.content.paddingLeft),
application.px2Px(binding.content.paddingTop),
application.px2Px(binding.content.paddingRight),
application.px2Px(binding.content.paddingBottom)
)
binding.name.textSize = application.px2PxFont(binding.name.textSize)
binding.version.textSize = application.px2PxFont(binding.version.textSize)
val layoutParamsDesc = binding.version.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsDesc.topMargin = application.px2Px(binding.version.marginTop)
binding.version.layoutParams = layoutParamsDesc
binding.checkVersion.textSize = application.px2PxFont(binding.checkVersion.textSize)
val layoutParamsCheckVersion =
binding.checkVersion.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsCheckVersion.marginEnd = application.px2Px(binding.checkVersion.marginEnd)
binding.checkVersion.layoutParams = layoutParamsCheckVersion
binding.versionName.textSize = application.px2PxFont(binding.versionName.textSize)
binding.exit.textSize = application.px2PxFont(binding.exit.textSize)
binding.switchChannelReversal.textSize =
application.px2PxFont(binding.switchChannelReversal.textSize)
val layoutParamsChannelReversal =
binding.switchChannelReversal.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsChannelReversal.topMargin =
application.px2Px(binding.switchChannelReversal.marginTop)
binding.switchChannelReversal.layoutParams = layoutParamsChannelReversal
binding.switchChannelNum.textSize = application.px2PxFont(binding.switchChannelNum.textSize)
val layoutParamsChannelNum =
binding.switchChannelNum.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsChannelNum.topMargin = application.px2Px(binding.switchChannelNum.marginTop)
binding.switchChannelNum.layoutParams = layoutParamsChannelNum
binding.switchTime.textSize = application.px2PxFont(binding.switchTime.textSize)
val layoutParamsTime = binding.switchTime.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsTime.topMargin = application.px2Px(binding.switchTime.marginTop)
binding.switchTime.layoutParams = layoutParamsTime
binding.switchBootStartup.textSize =
application.px2PxFont(binding.switchBootStartup.textSize)
val layoutParamsBootStartup =
binding.switchBootStartup.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsBootStartup.topMargin = application.px2Px(binding.switchBootStartup.marginTop)
binding.switchBootStartup.layoutParams = layoutParamsBootStartup
binding.switchGrid.textSize = application.px2PxFont(binding.switchGrid.textSize)
val layoutParamsGrid = binding.switchGrid.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsGrid.topMargin = application.px2Px(binding.switchGrid.marginTop)
binding.switchGrid.layoutParams = layoutParamsGrid
binding.appreciate.layoutParams.width =
application.px2Px(binding.appreciate.layoutParams.width)
binding.exit.setOnClickListener {
requireActivity().finishAffinity()
}
return binding.root return binding.root
} }
+3 -2
View File
@@ -15,14 +15,15 @@ data class TV(
var programType: ProgramType, var programType: ProgramType,
var needToken: Boolean = false, var needToken: Boolean = false,
var mustToken: Boolean = false, var mustToken: Boolean = false,
) : Serializable {
) : Serializable {
override fun toString(): String { override fun toString(): String {
return "TV{" + return "TV{" +
"id=" + id + "id=" + id +
", title='" + title + '\'' + ", title='" + title + '\'' +
", alias='" + alias + '\'' +
", videoUrl='" + videoUrl + '\'' + ", videoUrl='" + videoUrl + '\'' +
", channel='" + channel + '\'' +
", logo='" + logo + '\'' + ", logo='" + logo + '\'' +
", pid='" + pid + '\'' + ", pid='" + pid + '\'' +
", sid='" + sid + '\'' + ", sid='" + sid + '\'' +
@@ -1,11 +1,13 @@
package com.lizongying.mytv package com.lizongying.mytv
import android.content.res.Resources
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.util.Log
import android.view.LayoutInflater import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.core.view.marginRight
import androidx.core.view.marginTop
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import com.lizongying.mytv.Utils.getDateFormat import com.lizongying.mytv.Utils.getDateFormat
import com.lizongying.mytv.databinding.TimeBinding import com.lizongying.mytv.databinding.TimeBinding
@@ -21,8 +23,39 @@ class TimeFragment : Fragment() {
inflater: LayoutInflater, container: ViewGroup?, inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle? savedInstanceState: Bundle?
): View { ): View {
Log.i(TAG, "onCreateView")
_binding = TimeBinding.inflate(inflater, container, false) _binding = TimeBinding.inflate(inflater, container, false)
val application = requireActivity().applicationContext as MyTvApplication
val width = application.getWidth()
val height = application.getHeight()
val ratio = 16f / 9f
if (width.toFloat() / height > ratio) {
val x =
((Resources.getSystem().displayMetrics.widthPixels - height * ratio) / 2).toInt()
val originalLayoutParams = binding.time.layoutParams as ViewGroup.MarginLayoutParams
originalLayoutParams.rightMargin += x
binding.time.layoutParams = originalLayoutParams
}
if (width.toFloat() / height < ratio) {
val y =
((height - Resources.getSystem().displayMetrics.widthPixels / ratio) / 2).toInt()
val originalLayoutParams = binding.time.layoutParams as ViewGroup.MarginLayoutParams
originalLayoutParams.topMargin += y
binding.time.layoutParams = originalLayoutParams
}
binding.time.layoutParams.width = application.px2Px(binding.time.layoutParams.width)
binding.time.layoutParams.height = application.px2Px(binding.time.layoutParams.height)
val layoutParams = binding.time.layoutParams as ViewGroup.MarginLayoutParams
layoutParams.topMargin = application.px2Px(binding.time.marginTop)
layoutParams.rightMargin = application.px2Px(binding.time.marginRight)
binding.time.layoutParams = layoutParams
binding.content.textSize = application.px2PxFont(binding.content.textSize)
(activity as MainActivity).fragmentReady("TimeFragment") (activity as MainActivity).fragmentReady("TimeFragment")
return binding.root return binding.root
} }
@@ -42,7 +75,10 @@ class TimeFragment : Fragment() {
private val showRunnable: Runnable = Runnable { private val showRunnable: Runnable = Runnable {
run { run {
binding.channelContent.text = getDateFormat("HH:mm") if (_binding == null) {
return@Runnable
}
binding.content.text = getDateFormat("HH:mm")
handler.postDelayed(showRunnable, delay) handler.postDelayed(showRunnable, delay)
} }
} }
@@ -59,6 +95,7 @@ class TimeFragment : Fragment() {
} }
override fun onDestroyView() { override fun onDestroyView() {
handler.removeCallbacks(showRunnable)
super.onDestroyView() super.onDestroyView()
_binding = null _binding = null
} }
@@ -62,7 +62,7 @@ class UpdateManager(
private fun updateUI(text: String) { private fun updateUI(text: String) {
val dialog = ConfirmationFragment(this@UpdateManager, text) val dialog = ConfirmationFragment(this@UpdateManager, text)
dialog.show(settingFragment.fragmentManager, TAG) settingFragment.fragmentManager?.let { dialog.show(it, TAG) }
} }
private fun haveStoragePermission(): Boolean { private fun haveStoragePermission(): Boolean {
@@ -15,6 +15,8 @@ import java.util.Locale
object Utils { object Utils {
private var between: Long = 0 private var between: Long = 0
private var listener: Request.RequestListener? = null
fun getDateFormat(format: String): String { fun getDateFormat(format: String): String {
return SimpleDateFormat( return SimpleDateFormat(
format, format,
@@ -38,6 +40,10 @@ object Utils {
println("Failed to retrieve timestamp from server: ${e.message}") println("Failed to retrieve timestamp from server: ${e.message}")
} }
between = System.currentTimeMillis() - currentTimeMillis between = System.currentTimeMillis() - currentTimeMillis
withContext(Dispatchers.Main) {
listener?.onRequestFinished(null)
}
} }
/** /**
@@ -72,10 +78,26 @@ object Utils {
} }
fun dpToPx(dp: Int): Int { fun dpToPx(dp: Int): Int {
// val density = Resources.getSystem().displayMetrics.density
// return (dp * density + 0.5f).toInt()
return TypedValue.applyDimension( return TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP, dp.toFloat(), Resources.getSystem().displayMetrics TypedValue.COMPLEX_UNIT_DIP, dp.toFloat(), Resources.getSystem().displayMetrics
).toInt() ).toInt()
} }
fun pxToDp(px: Float): Int {
val scale = Resources.getSystem().displayMetrics.density
return (px / scale).toInt()
}
fun pxToDp(px: Int): Int {
val scale = Resources.getSystem().displayMetrics.density
return (px / scale).toInt()
}
fun isTmallDevice() = Build.MANUFACTURER.equals("Tmall", ignoreCase = true) fun isTmallDevice() = Build.MANUFACTURER.equals("Tmall", ignoreCase = true)
fun setRequestListener(listener: Request.RequestListener) {
this.listener = listener
}
} }
@@ -41,8 +41,8 @@ class TVViewModel(private var tv: TV) : ViewModel() {
val videoIndex: LiveData<Int> val videoIndex: LiveData<Int>
get() = _videoIndex get() = _videoIndex
private val _change = MutableLiveData<Boolean>() private val _change = MutableLiveData<String>()
val change: LiveData<Boolean> val change: LiveData<String>
get() = _change get() = _change
private val _ready = MutableLiveData<Boolean>() private val _ready = MutableLiveData<Boolean>()
@@ -74,8 +74,8 @@ class TVViewModel(private var tv: TV) : ViewModel() {
} }
} }
fun changed() { fun changed(from: String) {
_change.value = true _change.value = from
} }
fun allReady() { fun allReady() {
@@ -1,4 +0,0 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#FF263238" />
<corners android:radius="4dp" /> <!-- Adjust the radius as needed -->
</shape>
@@ -0,0 +1,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/blur" />
<corners
android:bottomLeftRadius="4dp"
android:bottomRightRadius="4dp" />
</shape>
@@ -0,0 +1,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/blur" />
<corners
android:topLeftRadius="4dp"
android:bottomLeftRadius="4dp" />
</shape>
@@ -0,0 +1,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/blur" />
<corners
android:topRightRadius="4dp"
android:bottomRightRadius="4dp" />
</shape>
@@ -0,0 +1,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/focus" />
<corners
android:bottomLeftRadius="4dp"
android:bottomRightRadius="4dp" />
</shape>
@@ -0,0 +1,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners
android:topLeftRadius="4dp"
android:bottomLeftRadius="4dp" />
</shape>
@@ -0,0 +1,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" />
<corners
android:topRightRadius="4dp"
android:bottomRightRadius="4dp" />
</shape>
@@ -1,4 +1,6 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"> <shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/white" /> <solid android:color="@color/white" />
<corners android:radius="4dp" /> <!-- Adjust the radius as needed --> <corners
android:topLeftRadius="4dp"
android:topRightRadius="4dp" />
</shape> </shape>
+60
View File
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/card"
android:layout_width="150dp"
android:layout_height="100dp"
android:orientation="vertical"
android:layout_gravity="center_vertical"
>
<ImageView
android:id="@+id/icon"
android:layout_width="match_parent"
android:layout_height="40dp"
android:background="@drawable/rounded_white_top"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:padding="5dp" />
<LinearLayout
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="60dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/icon"
android:background="@drawable/rounded_dark_bottom"
android:orientation="vertical"
android:padding="7dp">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:gravity="start"
android:text="Title"
android:maxLines="1"
android:ellipsize="end"
android:textColor="#FFEEEEEE"
android:textSize="14sp" />
<TextView
android:id="@+id/desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/title"
android:layout_marginTop="8dp"
android:gravity="start"
android:maxLines="1"
android:ellipsize="end"
android:text="Description"
android:textColor="#B3EEEEEE"
android:textSize="12sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
+2 -3
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/channel_fragment" android:id="@+id/channel"
android:layout_width="90dp" android:layout_width="90dp"
android:layout_height="60dp" android:layout_height="60dp"
android:layout_gravity="end|top" android:layout_gravity="end|top"
@@ -8,11 +8,10 @@
android:layout_marginEnd="170dp"> android:layout_marginEnd="170dp">
<TextView <TextView
android:id="@+id/channel_content" android:id="@+id/content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="end" android:layout_gravity="end"
android:layout_marginTop="0dp"
android:textColor="#FFEEEEEE" android:textColor="#FFEEEEEE"
android:textStyle="bold" android:textStyle="bold"
android:textSize="40sp" /> android:textSize="40sp" />
+13 -20
View File
@@ -1,40 +1,39 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/info_fragment" android:id="@+id/info"
android:layout_width="320dp" android:layout_width="400dp"
android:layout_height="80dp" android:layout_height="80dp"
android:layout_gravity="center_horizontal|bottom" android:layout_gravity="center_horizontal|bottom"
android:layout_marginBottom="20dp" android:layout_marginBottom="20dp">
android:background="@drawable/rounded_background">
<ImageView <ImageView
android:id="@+id/info_logo" android:id="@+id/logo"
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_marginTop="8dp" android:background="@drawable/rounded_white_left"
android:padding="10dp" /> android:padding="10dp" />
<LinearLayout <LinearLayout
android:layout_width="216dp" android:id="@+id/main"
android:layout_width="300dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_marginStart="100dp" android:layout_marginStart="100dp"
android:background="#FF263238" android:background="@drawable/rounded_dark_right"
android:gravity="start|center_vertical" android:gravity="start|center_vertical"
android:orientation="vertical" android:orientation="vertical"
android:padding="7dp"> android:padding="7dp">
<TextView <TextView
android:id="@+id/textView" android:id="@+id/title"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="start" android:layout_gravity="start"
android:layout_marginTop="0dp"
android:gravity="start" android:gravity="start"
android:textColor="#FFEEEEEE" android:textColor="#FFEEEEEE"
android:textSize="22sp" /> android:textSize="20sp" />
<TextView <TextView
android:id="@+id/info_desc" android:id="@+id/desc"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="start" android:layout_gravity="start"
@@ -42,12 +41,6 @@
android:gravity="start" android:gravity="start"
android:singleLine="true" android:singleLine="true"
android:textColor="#B3EEEEEE" android:textColor="#B3EEEEEE"
android:textSize="16sp" /> android:textSize="14sp" />
</LinearLayout> </LinearLayout>
<View
android:layout_width="8dp"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:background="@drawable/rounded_background2" />
</FrameLayout> </FrameLayout>
+1 -1
View File
@@ -8,7 +8,7 @@
android:focusable="false" android:focusable="false"
> >
<ScrollView <ScrollView
android:id="@+id/scroll_view" android:id="@+id/scroll"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<LinearLayout <LinearLayout
+1 -1
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/player_fragment" android:id="@+id/player"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:background="@color/black" android:background="@color/black"
+3 -3
View File
@@ -10,19 +10,19 @@
> >
<TextView <TextView
android:id="@+id/row_header" android:id="@+id/header"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="start" android:layout_gravity="start"
android:layout_marginTop="0dp" android:layout_marginTop="0dp"
android:layout_marginStart="10dp" android:layout_marginStart="20dp"
android:layout_marginBottom="5dp" android:layout_marginBottom="5dp"
android:gravity="start" android:gravity="start"
android:textColor="#FFEEEEEE" android:textColor="#FFEEEEEE"
android:textSize="22sp" /> android:textSize="22sp" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/row_items" android:id="@+id/items"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
</androidx.recyclerview.widget.RecyclerView> </androidx.recyclerview.widget.RecyclerView>
+27 -10
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dialog" android:id="@+id/setting"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
> >
@@ -8,15 +8,17 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content"> android:layout_height="wrap_content">
<LinearLayout <LinearLayout
android:id="@+id/content"
android:layout_width="300dp" android:layout_width="300dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
android:paddingTop="20dp" android:paddingTop="20dp"
android:paddingLeft="7dp" android:paddingLeft="7dp"
android:paddingRight="7dp" android:paddingRight="7dp"
android:background="#FF263238" android:background="@drawable/rounded_dark_left"
> >
<TextView <TextView
android:id="@+id/name"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="@string/app_name" android:text="@string/app_name"
@@ -27,9 +29,10 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:text="当前版本: $versionName\n获取最新: https://github.com/lizongying/my-tv/releases/" android:text="当前版本: $versionName\n获取最新: https://github.com/lizongying/my-tv/releases/"
android:textSize="14sp"
/> />
<LinearLayout <LinearLayout
android:layout_width="300dp" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="horizontal"
> >
@@ -38,6 +41,7 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginEnd="10dp" android:layout_marginEnd="10dp"
android:textSize="14sp"
android:text="@string/check_version" android:text="@string/check_version"
/> />
<ProgressBar <ProgressBar
@@ -48,45 +52,58 @@
<TextView <TextView
android:id="@+id/version_name" android:id="@+id/version_name"
android:text="" android:text=""
android:textSize="14sp"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
</LinearLayout> </LinearLayout>
<Button
android:id="@+id/exit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:text="@string/exit"
/>
<Switch <Switch
android:id="@+id/switch_channel_reversal" android:id="@+id/switch_channel_reversal"
android:text="@string/title_channel_reversal" android:text="@string/title_channel_reversal"
android:layout_marginTop="10dp" android:textSize="14sp"
android:layout_marginTop="5dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<Switch <Switch
android:id="@+id/switch_channel_num" android:id="@+id/switch_channel_num"
android:text="@string/title_channel_num" android:text="@string/title_channel_num"
android:layout_marginTop="10dp" android:textSize="14sp"
android:layout_marginTop="5dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<Switch <Switch
android:id="@+id/switch_time" android:id="@+id/switch_time"
android:text="@string/title_time" android:text="@string/title_time"
android:layout_marginTop="10dp" android:textSize="14sp"
android:layout_marginTop="5dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<Switch <Switch
android:id="@+id/switch_boot_startup" android:id="@+id/switch_boot_startup"
android:text="@string/title_boot_startup" android:text="@string/title_boot_startup"
android:layout_marginTop="10dp" android:textSize="14sp"
android:layout_marginTop="5dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
<Switch <Switch
android:id="@+id/switch_grid" android:id="@+id/switch_grid"
android:text="@string/title_grid" android:text="@string/title_grid"
android:layout_marginTop="10dp" android:textSize="14sp"
android:layout_marginTop="5dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" /> android:layout_height="wrap_content" />
</LinearLayout> </LinearLayout>
<ImageView <ImageView
android:id="@+id/appreciate"
android:layout_width="300dp" android:layout_width="300dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:src="@drawable/appreciate" android:src="@drawable/appreciate"
android:background="@color/white" /> android:background="@drawable/rounded_white_right" />
</LinearLayout> </LinearLayout>
</FrameLayout> </FrameLayout>
+3 -4
View File
@@ -2,18 +2,17 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/time" android:id="@+id/time"
android:layout_width="100dp" android:layout_width="100dp"
android:layout_height="50dp" android:layout_height="40dp"
android:layout_gravity="end|top" android:layout_gravity="end|top"
android:layout_marginTop="25dp" android:layout_marginTop="25dp"
android:layout_marginEnd="50dp"> android:layout_marginEnd="50dp">
<TextView <TextView
android:id="@+id/channel_content" android:id="@+id/content"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="end" android:layout_gravity="end"
android:layout_marginTop="0dp"
android:textColor="#FFEEEEEE" android:textColor="#FFEEEEEE"
android:textStyle="bold" android:textStyle="bold"
android:textSize="34sp" /> android:textSize="32sp" />
</FrameLayout> </FrameLayout>
-2
View File
@@ -1,8 +1,6 @@
<resources> <resources>
<color name="fastlane_background">#30000000</color>
<color name="black">#000</color> <color name="black">#000</color>
<color name="white">#FFF</color> <color name="white">#FFF</color>
<color name="gray_overlay">#7F000000</color>
<color name="focus">#0096a6</color> <color name="focus">#0096a6</color>
<color name="blur">#FF263238</color> <color name="blur">#FF263238</color>
</resources> </resources>
+1
View File
@@ -6,4 +6,5 @@
<string name="title_boot_startup">开机自启</string> <string name="title_boot_startup">开机自启</string>
<string name="title_grid">频道列表采用网格样式</string> <string name="title_grid">频道列表采用网格样式</string>
<string name="title_time">显示时间</string> <string name="title_time">显示时间</string>
<string name="exit">退出</string>
</resources> </resources>
+2 -2
View File
@@ -10,11 +10,11 @@
</style> </style>
<style name="CustomImageCardViewImageStyle" parent="Widget.Leanback.ImageCardView.ImageStyle"> <style name="CustomImageCardViewImageStyle" parent="Widget.Leanback.ImageCardView.ImageStyle">
<item name="android:layout_width">160dp</item> <item name="android:layout_width">150dp</item>
<item name="android:layout_height">40dp</item> <item name="android:layout_height">40dp</item>
<item name="android:adjustViewBounds">true</item> <item name="android:adjustViewBounds">true</item>
<item name="android:contentDescription">@null</item> <item name="android:contentDescription">@null</item>
<item name="android:scaleType">centerCrop</item> <item name="android:scaleType">centerInside</item>
<item name="layout_viewType">main</item> <item name="layout_viewType">main</item>
</style> </style>