error page

This commit is contained in:
Li ZongYing
2024-04-26 19:57:12 +08:00
parent fe92fa5853
commit 5aa08f51a1
26 changed files with 339 additions and 107 deletions
Binary file not shown.
Binary file not shown.
@@ -1,8 +1,11 @@
package com.lizongying.mytv
import android.util.Log
import android.view.KeyEvent
import android.view.LayoutInflater
import android.view.MotionEvent
import android.view.View
import android.view.ViewConfiguration
import android.view.ViewGroup
import android.view.animation.ScaleAnimation
import androidx.core.view.marginTop
@@ -12,6 +15,7 @@ import com.bumptech.glide.Glide
import com.lizongying.mytv.databinding.CardBinding
import com.lizongying.mytv.models.TVListViewModel
import com.lizongying.mytv.models.TVViewModel
import kotlin.math.abs
class CardAdapter(
@@ -45,6 +49,7 @@ class CardAdapter(
binding.desc.layoutParams = layoutParams
val cardView = binding.root
cardView.isClickable = true
cardView.isFocusable = true
cardView.isFocusableInTouchMode = true
return ViewHolder(cardView, binding)
@@ -55,14 +60,14 @@ class CardAdapter(
recyclerView.invalidate()
}
private fun startScaleAnimation(view: View, fromScale: Float, toScale: Float, duration: Long) {
private fun startScaleAnimation(view: View) {
val scaleAnimation = ScaleAnimation(
fromScale, toScale,
fromScale, toScale,
0.9f, 1.0f,
0.9f, 1.0f,
ScaleAnimation.RELATIVE_TO_SELF, 0.5f,
ScaleAnimation.RELATIVE_TO_SELF, 0.5f
)
scaleAnimation.duration = duration
scaleAnimation.duration = 200
scaleAnimation.fillAfter = false
view.startAnimation(scaleAnimation)
}
@@ -80,7 +85,7 @@ class CardAdapter(
focused = cardView
if (focusable) {
startScaleAnimation(cardView, 0.9f, 1.0f, 200)
startScaleAnimation(cardView)
viewHolder.focus(true)
}
} else {
@@ -94,6 +99,34 @@ class CardAdapter(
listener?.onItemClicked(item)
}
var downX = 0f
var downY = 0f
val touchSlop = ViewConfiguration.get(cardView.context).scaledTouchSlop
cardView.setOnTouchListener { _, event ->
when (event.action) {
MotionEvent.ACTION_DOWN -> {
downX = event.x
downY = event.y
true
}
MotionEvent.ACTION_UP -> {
val upX = event.x
val upY = event.y
val deltaX = abs(upX - downX)
val deltaY = abs(upY - downY)
if (deltaX < touchSlop && deltaY < touchSlop) {
// 如果位移量小于阈值,则执行点击操作
cardView.performClick()
}
true
}
else -> false
}
}
cardView.setOnKeyListener { _, keyCode, event: KeyEvent? ->
if (event?.action == KeyEvent.ACTION_DOWN) {
return@setOnKeyListener listener?.onKey(keyCode) ?: false
@@ -132,6 +165,33 @@ class CardAdapter(
}
}
fun updateEPG() {
for (i in 0 until recyclerView.childCount) {
val childView = recyclerView.getChildAt(i)
val viewHolder = recyclerView.getChildViewHolder(childView) as ViewHolder
if (viewHolder.view.tag != null && viewHolder.view.tag is TVViewModel) {
val tvViewModel = viewHolder.view.tag as TVViewModel
val epg = tvViewModel.epg.value?.filter { it.beginTime < Utils.getDateTimestamp() }
if (!epg.isNullOrEmpty()) {
val title = epg.last().title
if (viewHolder.binding.desc.text != title) {
viewHolder.binding.desc.text = title
Log.i(TAG, "updateEPG $title")
}
} else {
if (viewHolder.binding.desc.text != "") {
viewHolder.binding.desc.text = ""
Log.i(TAG, "updateEPG")
}
}
}
}
}
fun toPosition(position: Int) {
recyclerView.post {
recyclerView.scrollToPosition(position)
@@ -0,0 +1,53 @@
package com.lizongying.mytv
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.view.marginLeft
import androidx.core.view.marginTop
import androidx.fragment.app.Fragment
import com.lizongying.mytv.databinding.ErrorBinding
class ErrorFragment : Fragment() {
private var _binding: ErrorBinding? = null
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = ErrorBinding.inflate(inflater, container, false)
val application = requireActivity().applicationContext as MyTvApplication
binding.logo.layoutParams.width = application.px2Px(binding.logo.layoutParams.width)
binding.logo.layoutParams.height = application.px2Px(binding.logo.layoutParams.height)
val layoutParamsMain = binding.main.layoutParams as ViewGroup.MarginLayoutParams
layoutParamsMain.leftMargin = application.px2Px(binding.main.marginLeft)
binding.main.layoutParams = layoutParamsMain
val layoutParams = binding.msg.layoutParams as ViewGroup.MarginLayoutParams
layoutParams.topMargin = application.px2Px(binding.msg.marginTop)
binding.msg.layoutParams = layoutParams
binding.msg.textSize = application.px2PxFont(binding.msg.textSize)
(activity as MainActivity).fragmentReady(TAG)
return binding.root
}
fun show(msg: String) {
binding.msg.text = msg
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
companion object {
private const val TAG = "ErrorFragment"
}
}
@@ -52,6 +52,7 @@ class InfoFragment : Fragment() {
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
@@ -59,6 +60,7 @@ class InfoFragment : Fragment() {
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)
@@ -17,6 +17,7 @@ import android.widget.Toast
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.lifecycleScope
import com.lizongying.mytv.models.TVViewModel
import com.lizongying.mytv.requests.Request
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
@@ -27,6 +28,7 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
private var ready = 0
private val playerFragment = PlayerFragment()
private val errorFragment = ErrorFragment()
private val mainFragment = MainFragment()
private val infoFragment = InfoFragment()
private val channelFragment = ChannelFragment()
@@ -53,7 +55,6 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
}
override fun onCreate(savedInstanceState: Bundle?) {
Log.i(TAG, "onCreate")
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
@@ -67,11 +68,13 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.add(R.id.main_browse_fragment, playerFragment)
.add(R.id.main_browse_fragment, errorFragment)
.add(R.id.main_browse_fragment, timeFragment)
.add(R.id.main_browse_fragment, infoFragment)
.add(R.id.main_browse_fragment, channelFragment)
.add(R.id.main_browse_fragment, mainFragment)
.hide(mainFragment)
.hide(errorFragment)
.commit()
}
gestureDetector = GestureDetector(this, GestureListener())
@@ -103,6 +106,44 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
}
}
fun showErrorFragment(msg: String) {
errorFragment.show(msg)
if (errorFragment.isVisible) {
return
}
supportFragmentManager.beginTransaction()
.show(errorFragment)
.commit()
}
fun hideErrorFragment() {
errorFragment.show("")
if (!errorFragment.isVisible) {
return
}
supportFragmentManager.beginTransaction()
.hide(errorFragment)
.commit()
}
fun showPlayerFragment() {
if (playerFragment.isVisible) {
return
}
supportFragmentManager.beginTransaction()
.show(playerFragment)
.commit()
}
fun hidePlayerFragment() {
if (!playerFragment.isVisible) {
return
}
supportFragmentManager.beginTransaction()
.hide(playerFragment)
.commit()
}
private fun showChannel(channel: String) {
if (!mainFragment.isHidden) {
return
@@ -183,7 +224,7 @@ class MainActivity : FragmentActivity(), Request.RequestListener {
fun fragmentReady(tag: String) {
ready++
Log.i(TAG, "ready $tag $ready ")
if (ready == 7) {
if (ready == 8) {
mainFragment.fragmentReady()
showTime()
}
@@ -20,8 +20,10 @@ import com.lizongying.mytv.api.YSP
import com.lizongying.mytv.databinding.MenuBinding
import com.lizongying.mytv.databinding.RowBinding
import com.lizongying.mytv.models.ProgramType
import com.lizongying.mytv.models.TVList
import com.lizongying.mytv.models.TVListViewModel
import com.lizongying.mytv.models.TVViewModel
import com.lizongying.mytv.requests.Request
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -183,8 +185,13 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
if (tvViewModel.errInfo.value != null
&& tvViewModel.getTV().id == itemPosition
) {
Toast.makeText(context, tvViewModel.errInfo.value, Toast.LENGTH_SHORT)
.show()
if (tvViewModel.errInfo.value == "") {
(activity as? MainActivity)?.showPlayerFragment()
(activity as? MainActivity)?.hideErrorFragment()
} else {
(activity as? MainActivity)?.hidePlayerFragment()
(activity as? MainActivity)?.showErrorFragment(tvViewModel.errInfo.value.toString())
}
}
}
tvViewModel.ready.observe(viewLifecycleOwner) { _ ->
@@ -266,8 +273,6 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
}
override fun onItemHasFocus(tvViewModel: TVViewModel) {
tvListViewModel.setItemPositionCurrent(tvViewModel.getTV().id)
val row = tvViewModel.getRowPosition()
for (i in rowList) {
@@ -283,7 +288,6 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
}
override fun onItemClicked(tvViewModel: TVViewModel) {
Log.i(TAG, "onItemClicked")
if (this.isHidden) {
(activity as? MainActivity)?.switchMainFragment()
return
@@ -293,6 +297,7 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
itemPosition = tvViewModel.getTV().id
tvListViewModel.setItemPosition(itemPosition)
tvListViewModel.getTVViewModel(itemPosition)?.changed("menu")
Log.i(TAG, "onItemClicked ${tvViewModel.getTV().id}")
}
(activity as? MainActivity)?.switchMainFragment()
}
@@ -410,8 +415,9 @@ class MainFragment : Fragment(), CardAdapter.ItemListener {
Log.i(TAG, "toPosition $rowPosition $itemPosition")
for (i in rowList) {
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).updateEPG()
(i.adapter as CardAdapter).focusable = true
(i.adapter as CardAdapter).toPosition(itemPosition!!)
break
}
}
@@ -78,10 +78,18 @@ class PlayerFragment : Fragment(), SurfaceHolder.Callback {
override fun onPlayerError(error: PlaybackException) {
super.onPlayerError(error)
Log.e(TAG, "PlaybackException $error")
val err = "播放错误"
tvViewModel?.setErrInfo(err)
tvViewModel?.changed("retry")
}
override fun onIsPlayingChanged(isPlaying: Boolean) {
super.onIsPlayingChanged(isPlaying)
if (isPlaying) {
tvViewModel?.setErrInfo("")
}
}
})
}
})
@@ -18,7 +18,7 @@ import androidx.core.app.ActivityCompat
import androidx.core.content.PermissionChecker
import androidx.core.content.PermissionChecker.checkSelfPermission
import com.lizongying.mytv.api.ReleaseV2
import com.lizongying.mytv.requests.MyRequest
import com.lizongying.mytv.requests.ReleaseRequest
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -32,7 +32,7 @@ class UpdateManager(
) :
ConfirmationFragment.ConfirmationListener {
private var myRequest = MyRequest()
private var myRequest = ReleaseRequest()
private var release: ReleaseV2? = null
private var downloadReceiver: DownloadReceiver? = null
@@ -5,6 +5,7 @@ import android.os.Build
import android.util.TypedValue
import com.google.gson.Gson
import com.lizongying.mytv.api.TimeResponse
import com.lizongying.mytv.requests.Request
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.IOException
@@ -1,4 +1,4 @@
package com.lizongying.mytv
package com.lizongying.mytv.api
import android.content.Context
@@ -1,7 +1,6 @@
package com.lizongying.mytv.api
import android.content.Context
import com.lizongying.mytv.Encryptor
import com.lizongying.mytv.SP
import com.lizongying.mytv.Utils.getDateTimestamp
import com.lizongying.mytv.models.TVViewModel
@@ -1,4 +1,4 @@
package com.lizongying.mytv
package com.lizongying.mytv.models
import com.lizongying.mytv.models.ProgramType
import java.io.Serializable
@@ -28,6 +28,8 @@ data class TV(
", pid='" + pid + '\'' +
", sid='" + sid + '\'' +
", programType='" + programType + '\'' +
", needToken='" + needToken + '\'' +
", mustToken='" + mustToken + '\'' +
'}'
}
}
@@ -1,6 +1,6 @@
package com.lizongying.mytv
package com.lizongying.mytv.models
import com.lizongying.mytv.models.ProgramType
import com.lizongying.mytv.R
object TVList {
val list: Map<String, List<TV>> by lazy {
@@ -900,6 +900,7 @@ object TVList {
v.forEach { v1 ->
if (!v1.mustToken) {
v1.id = id
v1.needToken = false
id++
group.add(v1)
}
@@ -16,10 +16,6 @@ class TVListViewModel : ViewModel() {
val itemPosition: LiveData<Int>
get() = _itemPosition
private val _itemPositionCurrent = MutableLiveData<Int>()
val itemPositionCurrent: LiveData<Int>
get() = _itemPositionCurrent
fun addTVViewModel(tvViewModel: TVViewModel) {
if (_tvListViewModel.value == null) {
_tvListViewModel.value = mutableListOf(tvViewModel)
@@ -32,23 +28,15 @@ class TVListViewModel : ViewModel() {
return _tvListViewModel.value?.get(id)
}
fun getTVViewModelCurrent(): TVViewModel? {
return _itemPositionCurrent.value?.let { _tvListViewModel.value?.get(it) }
}
fun setItemPosition(position: Int) {
_itemPosition.value = position
_itemPositionCurrent.value = position
}
fun setItemPositionCurrent(position: Int) {
_itemPositionCurrent.value = position
}
fun size(): Int {
if (_tvListViewModel.value == null) {
return 0
}
return _tvListViewModel.value!!.size
}
}
@@ -1,10 +1,8 @@
package com.lizongying.mytv.models
import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.lizongying.mytv.TV
import com.lizongying.mytv.api.FEPG
import com.lizongying.mytv.proto.Ysp.cn.yangshipin.omstv.common.proto.programModel.Program
import com.tencent.videolite.android.datamodel.cctvjce.TVProgram
@@ -56,24 +54,15 @@ class TVViewModel(private var tv: TV) : ViewModel() {
if (_videoUrl.value!!.last().contains("cctv.cn")) {
tv.videoUrl = tv.videoUrl.subList(0, tv.videoUrl.lastIndex) + listOf(url)
} else {
tv.videoUrl = tv.videoUrl + listOf(url)
tv.videoUrl += listOf(url)
}
} else {
tv.videoUrl = tv.videoUrl + listOf(url)
tv.videoUrl += listOf(url)
}
_videoUrl.value = tv.videoUrl
_videoIndex.value = tv.videoUrl.lastIndex
}
fun firstSource() {
if (_videoUrl.value!!.isNotEmpty()) {
setVideoIndex(0)
allReady()
} else {
Log.e(TAG, "no first")
}
}
fun changed(from: String) {
_change.value = from
}
@@ -82,10 +71,6 @@ class TVViewModel(private var tv: TV) : ViewModel() {
_ready.value = true
}
fun setVideoIndex(videoIndex: Int) {
_videoIndex.value = videoIndex
}
init {
_videoUrl.value = tv.videoUrl
_videoIndex.value = tv.videoUrl.lastIndex
@@ -10,7 +10,7 @@ import retrofit2.Response
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine
class MyRequest {
class ReleaseRequest {
private var releaseService = ApiClient().releaseService
suspend fun getRelease(): ReleaseV2? {
@@ -39,6 +39,6 @@ class MyRequest {
}
companion object {
private const val TAG = "MyRequest"
private const val TAG = "ReleaseRequest"
}
}
@@ -1,11 +1,10 @@
package com.lizongying.mytv
package com.lizongying.mytv.requests
import android.os.Handler
import android.os.Looper
import android.util.Base64
import android.util.Log
import com.google.gson.Gson
import java.net.URLDecoder
import com.lizongying.mytv.Utils
import com.lizongying.mytv.Utils.getDateFormat
import com.lizongying.mytv.api.ApiClient
import com.lizongying.mytv.api.Auth
@@ -25,6 +24,7 @@ import com.lizongying.mytv.api.YSPBtraceService
import com.lizongying.mytv.api.YSPJceService
import com.lizongying.mytv.api.YSPProtoService
import com.lizongying.mytv.api.YSPTokenService
import com.lizongying.mytv.models.TVList
import com.lizongying.mytv.models.TVViewModel
import com.lizongying.mytv.proto.Ysp.cn.yangshipin.oms.common.proto.pageModel
import com.lizongying.mytv.proto.Ysp.cn.yangshipin.omstv.common.proto.epgProgramModel
@@ -118,11 +118,17 @@ object Request {
} else {
if (!tvModel.getTV().mustToken) {
fetchAuth(tvModel, cookie)
} else {
// TODO
}
}
} else {
fetchAuth(tvModel, cookie)
}
} else {
val err = "认证结果错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
} else {
@@ -137,11 +143,17 @@ object Request {
} else {
if (!tvModel.getTV().mustToken) {
fetchAuth(tvModel, cookie)
} else {
// TODO
}
}
} else {
fetchAuth(tvModel, cookie)
}
} else {
val err = "认证状态错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
}
@@ -158,11 +170,17 @@ object Request {
} else {
if (!tvModel.getTV().mustToken) {
fetchAuth(tvModel, cookie)
} else {
// TODO
}
}
} else {
fetchAuth(tvModel, cookie)
}
} else {
val err = "认证请求错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
})
@@ -171,7 +189,7 @@ object Request {
private fun fetchVideo(tvModel: TVViewModel, cookie: String) {
cancelCall()
if (::btraceRunnable.isInitialized) {
if (Request::btraceRunnable.isInitialized) {
handler.removeCallbacks(btraceRunnable)
}
@@ -229,18 +247,25 @@ object Request {
if (!tvModel.getTV().mustToken) {
fetchVideo(tvModel, cookie)
// fetchAuth(tvModel, cookie)
} else {
// TODO
}
}
} else {
fetchVideo(tvModel, cookie)
// fetchAuth(tvModel, cookie)
}
} else {
val err = "结果错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
} else {
if (liveInfo?.data?.errinfo != null && liveInfo.data.errinfo == "应版权方要求,暂停提供直播信号,请点击观看其他精彩节目") {
Log.e(TAG, "$title error ${liveInfo.data.errinfo}")
tvModel.setErrInfo(liveInfo.data.errinfo)
val err = "版权错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
} else {
Log.e(TAG, "$title url error $request $liveInfo")
if (tvModel.retryTimes < tvModel.retryMaxTimes) {
@@ -255,12 +280,18 @@ object Request {
if (!tvModel.getTV().mustToken) {
fetchVideo(tvModel, cookie)
// fetchAuth(tvModel, cookie)
} else {
// TODO
}
}
} else {
fetchVideo(tvModel, cookie)
// fetchAuth(tvModel, cookie)
}
} else {
val err = "其他错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
}
@@ -278,12 +309,18 @@ object Request {
if (!tvModel.getTV().mustToken) {
fetchVideo(tvModel, cookie)
// fetchAuth(tvModel, cookie)
} else {
// TODO
}
}
} else {
fetchVideo(tvModel, cookie)
// fetchAuth(tvModel, cookie)
}
} else {
val err = "状态错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
}
@@ -300,11 +337,17 @@ object Request {
} else {
if (!tvModel.getTV().mustToken) {
fetchVideo(tvModel, cookie)
} else {
// TODO
}
}
} else {
fetchVideo(tvModel, cookie)
}
} else {
val err = "请求错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
})
@@ -340,6 +383,8 @@ object Request {
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109"
fetchAuth(tvModel, cookie)
} else {
// TODO
}
}
}
@@ -355,6 +400,8 @@ object Request {
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109"
fetchAuth(tvModel, cookie)
} else {
// TODO
}
}
}
@@ -397,6 +444,8 @@ object Request {
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109"
fetchVideo(tvModel, cookie)
} else {
// TODO
}
}
}
@@ -412,6 +461,8 @@ object Request {
val cookie =
"versionName=99.99.99; versionCode=999999; vplatform=109; platformVersion=Chrome; deviceModel=120; appid=1400421205; yspappid=519748109"
fetchVideo(tvModel, cookie)
} else {
// TODO
}
}
}
@@ -447,6 +498,10 @@ object Request {
if (tvModel.tokenFHRetryTimes < tvModel.tokenFHRetryMaxTimes) {
tvModel.tokenFHRetryTimes++
fetchFAuth(tvModel)
} else {
val err = "状态错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
}
@@ -456,6 +511,10 @@ object Request {
if (tvModel.tokenFHRetryTimes < tvModel.tokenFHRetryMaxTimes) {
tvModel.tokenFHRetryTimes++
fetchFAuth(tvModel)
} else {
val err = "请求错误"
Log.e(TAG, "$title $err")
tvModel.setErrInfo(err)
}
}
})
@@ -817,6 +876,6 @@ object Request {
}
fun setRequestListener(listener: RequestListener) {
this.listener = listener
Request.listener = listener
}
}
+23
View File
@@ -0,0 +1,23 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"
android:viewportWidth="50"
android:viewportHeight="50"
android:width="62.5dp"
android:height="62.5dp">
<group
android:scaleX="0.1"
android:scaleY="-0.1"
android:translateY="50">
<path
android:pathData="M205 377c-27 -27 -40 -33 -65 -29 -30 4 -70 -19 -70 -40 0 -5 -16 -24 -35 -42 -38 -36 -44 -66 -23 -111 22 -49 51 -55 248 -55l182 0 29 29c46 46 37 106 -20 136 -20 10 -31 25 -35 49 -4 22 -20 46 -42 65 -29 26 -43 31 -85 31 -44 0 -55 -4 -84 -33zm138 2c29 -13 57 -58 57 -93 0 -17 5 -26 15 -26 24 0 65 -46 65 -71 0 -13 -10 -33 -22 -46 -21 -22 -26 -23 -205 -23 -182 0 -184 0 -208 25 -33 32 -32 70 3 105 16 15 36 40 45 54 18 27 54 35 74 15 8 -8 16 -2 29 19 9 17 27 35 38 41 28 13 80 13 109 0z"
android:fillColor="#FFEEEEEE" />
<path
android:pathData="M174 269c-10 -17 13 -36 27 -22 12 12 4 33 -11 33 -5 0 -12 -5 -16 -11z"
android:fillColor="#FFEEEEEE" />
<path
android:pathData="M294 269c-10 -17 13 -36 27 -22 12 12 4 33 -11 33 -5 0 -12 -5 -16 -11z"
android:fillColor="#FFEEEEEE" />
<path
android:pathData="M194 196c-32 -14 -50 -33 -41 -42 3 -3 20 4 38 15 43 26 75 26 118 0 34 -20 49 -20 36 1 -10 16 -69 40 -97 40 -13 -1 -37 -7 -54 -14z"
android:fillColor="#FFEEEEEE" />
</group>
</vector>
+30
View File
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/error"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center_horizontal"
android:gravity="center_vertical|center_horizontal"
android:orientation="vertical" >
<ImageView
android:id="@+id/logo"
android:src="@drawable/sad_cloud"
android:layout_width="50dp"
android:layout_height="50dp" />
<TextView
android:id="@+id/msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:textColor="#FFEEEEEE"
android:text="Message"
android:textSize="20sp" />
</LinearLayout>
</FrameLayout>
+2 -1
View File
@@ -2,5 +2,6 @@
<color name="black">#000</color>
<color name="white">#FFF</color>
<color name="focus">#0096a6</color>
<color name="blur">#FF263238</color>
<color name="blur">#223239</color>
<color name="ic_launcher_background">#223239</color>
</resources>
@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#223239</color>
</resources>
-22
View File
@@ -1,25 +1,3 @@
<resources>
<style name="CustomImageCardViewStyle" parent="Widget.Leanback.ImageCardViewStyle">
<item name="cardType">infoUnder</item>
<item name="infoVisibility">always</item>
<!-- In order to keep backward compatibility we have to create an icon on right. -->
<item name="lbImageCardViewType">Title|Content|IconOnRight</item>
<!-- Deprecated. Use 'Widget.Leanback.ImageCardView.InfoAreaStyle' instead. -->
<item name="infoAreaBackground">@null</item>
</style>
<style name="CustomImageCardViewImageStyle" parent="Widget.Leanback.ImageCardView.ImageStyle">
<item name="android:layout_width">150dp</item>
<item name="android:layout_height">40dp</item>
<item name="android:adjustViewBounds">true</item>
<item name="android:contentDescription">@null</item>
<item name="android:scaleType">centerInside</item>
<item name="layout_viewType">main</item>
</style>
<style name="CustomImageCardTheme" parent="Theme.Leanback">
<item name="imageCardViewStyle">@style/CustomImageCardViewStyle</item>
<item name="imageCardViewImageStyle">@style/CustomImageCardViewImageStyle</item>
</style>
</resources>
-3
View File
@@ -1,8 +1,5 @@
<resources>
<style name="Theme.MyTV" parent="@style/Theme.Leanback">
<item name="browsePaddingStart">11dp</item>
<item name="browsePaddingEnd">11dp</item>
<item name="browseRowsMarginTop">54dp</item>
</style>
</resources>