持续更新:详细总结 TV开发常用的方法和遇到的问题解决方法

2024-04-29 17:32

本文主要是介绍持续更新:详细总结 TV开发常用的方法和遇到的问题解决方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

开发

基本方法

  • View# setFocusable()/android:focusable
    设置View是否可以聚焦(注意:设置了View不一定可以拿到焦点 具体看这篇深入理解:View和ViewGroup如何才能获取焦点)

  • View# boolean hasFocus()
    View是否有焦点。如果是ViewGroup:自身有焦点或者其子View有焦点返回true,其他返回false

  • View# boolean hasFocusable()
    view是否可以聚焦。如果是ViewGroup:自身可以聚焦或者其子View有可以聚焦的返回true,其他返回false

  • ViewGroup# View getFocusedChild()
    ViewGroup方法。获取当前有焦点或者包含焦点的子View。获取到的View不一定是当前获取焦点的View,无法准确获取真正有焦点的View
    比如:以下xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/fl_container"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".activity.tv.FocusTestActivity"><FrameLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"><Buttonandroid:id="@+id/test_btn"android:focusable="true"android:layout_width="wrap_content"android:layout_height="wrap_content"/></FrameLayout></FrameLayout>

焦点实际上在Button上,如果我们调用跟布局的FrameLayout的getFocusedChild方法获取到的是第二层的FrameLayout。

  • View# View findFocus() 寻找实际获取焦点的View
    View方法,查找当前View和其子View中实际获取焦点的View。如果我们要查找当前页面获取焦点的View,我们最好使用DecorView的findFocus方法

  • Window# View getCurrentFocus()
    Window方法获取当前Window聚焦的方法。内部实际上就是调用DecorView的findCocus方法在视图层级去查找。

监听

  • View# void setOnFocusChangeListener(OnFocusChangeListener listener)
    设置View聚焦监听。

  • View# protected void onFocusChanged(boolean gainFocus, @FocusDirection int direction,
    @Nullable Rect previouslyFocusedRect)
    View可以重写监听焦点变化的方法。
    第一个参数:是否获取焦点了(只有真正获取焦点了会回调,viewGroup的子View获取焦点ViewGroup此方法不回调)
    第二个参数:焦点聚焦的方向 上、下、左、右用于监控焦点来源方向。一般是系统自动找焦点的时候可以看一下这个值,这个值不一定是真实的,因为方向值我可以乱传
    第三个参数:上一个焦点的位置信息,不一定有。

  • ViewTreeObserver# void addOnGlobalFocusChangeListener(OnGlobalFocusChangeListener listener)
    监听当前页面View树焦点的变化。如果你找不到焦点的变化情况可以通过这个方法很好用。回调结果:上一个聚焦的View和当前聚焦的View

使用:

view.getViewTreeObserver().addOnGlobalFocusChangeListener(new ViewTreeObserver.OnGlobalFocusChangeListener() {@Overridepublic void onGlobalFocusChanged(View oldFocus, View newFocus) {}});

请求焦点

  • boolean requestFocus()
    请求焦点,方向默认往下
  • boolean requestFocus(int direction)
    指定请求方法,请求焦点。取值View.FOCUS_UP、View.FOCUS_DOWN、View.FOCUS_LEFT、View.FOCUS_RIGHT、View.FOCUS_BACKWARD、VIew.FOCUS_FORWARD
  • boolean requestFocus(int direction, Rect previouslyFocusedRect)
    指定请求方法,并指定上一个焦点所在的View的区域信息(是一个标记功能,可以不用填),请求焦点

通常情况下我们调用第一个就可以了,如果明确指定请求焦点的方向后面有处理使用第二个方法。

焦点查找

  • View# View focusSearch(@FocusRealDirection int direction)
    在指定方向去查找下一个最近的可以聚焦的View。找不到就返回null。通过这个方法我们可以知道一个View的指定方向上是否还有可聚焦的View。用于监听是否到了页面边缘。

  • FocusFinder类
    Android系统提供的查找可聚焦View的方法,系统自动查找焦点也是通过这个类来实现的。开放的方法不多,我们主要用这个方法:
    View findNextFocus(ViewGroup root, View focused, int direction)
    第一个参数:指定焦点查找范围,比如我们如果传递DecorView,就是在整个View树中去查找。如果我们传递一个指定的ViewGroup,就在这个ViewGroup内去查找。通过这个方法我们可以监听一个View或者ViewGroup的是否到达可聚焦的边缘,做一些边缘抖动的动画等等
    第二个参数:当前聚焦的View
    第三个参数:查找方向上、下、左、下、前一个、后一个
    基本使用:

		View nextFocus = FocusFinder.getInstance().findNextFocus((ViewGroup) getWindow().getDecorView(), getWindow().getCurrentFocus(), View.FOCUS_DOWN);
  • View# 指定下一个可聚焦View的id,对应xml属性就是foucsxxxId
    • void setNextFocusDownId(int nextFocusDownId)
    • void setNextFocusForwardId(int nextFocusForwardId)
    • void setNextFocusUpId(int nextFocusUpId)
    • void setNextFocusLeftId(int nextFocusLeftId)
    • void setNextFocusRightId(int nextFocusRightId)
      当这个View聚焦之后,如果这个View指定了这些id,那么按上、下、左、右按键的时候,就会用你指定的可聚焦的View来聚焦。如果指定的不可聚焦,系统就会自动就近去找。

调试

adb

  • 按键模拟

    • adb shell input keyevent xxxkeyCode
      模拟发送指定的keyCode对应的按键。具体的KeyCode在KeyEvent这个类可以看到
    • adb shell input text a
      模拟输入字符a
  • 查看盒子分辨率和dpi信息
    adb shell dumpsys window displays
    在这里插入图片描述
    第一个是盒子初始分辨率
    第二个是盒子dpi
    第三个是盒子当前分辨率

  • 修改盒子分辨率
    adb shell wm size 1920x1080

  • 修改盒子dpi
    adb shell wm density 320

  • adb 连接
    adb connect ip:port

  • 查看所有已安装应用包名
    adb shell pm list packages

  • 查看所有已安装应用包名和对应Apk文件的路径
    adb shell pm list packages -f

  • 查看指定apk设备安装路径
    adb shell pm path 应用包名

  • adb启动开发者选项Activity
    adb shell am start com.android.settings/.DevelopmentSettings

  • 布局边界(重启生效)
    启动布局边界:adb shell setprop debug.layout true
    关闭布局边界:adb shell setprop debug.layout false

  • 过度绘制检查(重启生效)
    启动:adb shell setprop debug.hwui.overdraw show
    关闭:adb shell setprop debug.hwui.overdraw false

  • 查看当前栈顶的Activity
    adb shell dumpsys activity | grep “mFocus”

apk安装常见错误

  • Failure [INSTALL_FAILED_TEST_ONLY]

解决方法:
adb install -t xxxxx.apk
Android Stuido3.0版本打release包在某些设备上可能导致无法安装

gradle.properties中添加以下属性可杜绝release包无法升级的问题
android.injected.testOnly=false

  • Failure [INSTALL_FAILED_ALREADY_EXISTS]

apk包存在导致的问题
解决方法:
adb install -r apk包名
或者
adb uninstall 包名
adb install apk

  • Failure [INSTALL_FAILED_UPDATE_INCOMPATIBLE]

安装包版本兼容问题
解决办法:
adb uninstall 包名
adb install apk

  • [INSTALL_FAILED_CONFLICTING_PROVIDER]

手机上存在provider的authorities 相同

在这里插入图片描述

应用内换authorities的值,和其他应用冲突只能换authorities值了

其他问题

  • 如何替换系统应用
1、使系统可以挂载
adb root
adb remount //使系统可挂载2、查找系统引用
adb shell
cd system/app 或者 system/priv-app下查找apk3、删除系统应用和应用数据
rm -rf xxxx
rm -rf data/data/应用包名4、推入我们新的应用
adb push xxxx.apk  /system/app 或者 system/priv-app5、重启设备生效
adb reboot
不重启直接安装会报 Failure [INSTALL_FAILED_ALREADY_EXISTS] 错误
  • 如何测试APK是否设置android:debuggable="false"
    • aapt list -v -a apk文件名 | grep debuggable

      得到如下输出:
      A: android:debuggable(0x0101000f)=(type 0x12)0x0
      这表示 android:debuggable=”false”

      aapt命令在sdk/build-tools/版本/xxx

    • Android Studio反编译打好的apk直接看manifest文件
      在这里插入图片描述

开发中遇到的坑

  • VideoView播放的时候会抢焦点

默认不调用requestFocus方法的时候,如果有VideoView,系统会给VideoView焦点,VideoView设置setFocusable(false)是没有的。解决方法就是给页面其他可聚焦元素主动调用requestFocus方法就可以了。

  • 对ViewGroup手动调用dispatchKeyEvent方法其中的子View的dispatchKeyEvent方法不触发

如果ViewGroup不包含焦点,调用dispatchKeyEvent不会往子View分发的,解决办法就是调用ViewGroup的requestFocus方法或者调用某个子View的requestFocus方法,让ViewGroup获得或者包含焦点

这篇关于持续更新:详细总结 TV开发常用的方法和遇到的问题解决方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/946709

相关文章

解决RocketMQ的幂等性问题

《解决RocketMQ的幂等性问题》重复消费因调用链路长、消息发送超时或消费者故障导致,通过生产者消息查询、Redis缓存及消费者唯一主键可以确保幂等性,避免重复处理,本文主要介绍了解决RocketM... 目录造成重复消费的原因解决方法生产者端消费者端代码实现造成重复消费的原因当系统的调用链路比较长的时

深度解析Nginx日志分析与499状态码问题解决

《深度解析Nginx日志分析与499状态码问题解决》在Web服务器运维和性能优化过程中,Nginx日志是排查问题的重要依据,本文将围绕Nginx日志分析、499状态码的成因、排查方法及解决方案展开讨论... 目录前言1. Nginx日志基础1.1 Nginx日志存放位置1.2 Nginx日志格式2. 499

SpringBoot监控API请求耗时的6中解决解决方案

《SpringBoot监控API请求耗时的6中解决解决方案》本文介绍SpringBoot中记录API请求耗时的6种方案,包括手动埋点、AOP切面、拦截器、Filter、事件监听、Micrometer+... 目录1. 简介2.实战案例2.1 手动记录2.2 自定义AOP记录2.3 拦截器技术2.4 使用Fi

kkFileView启动报错:报错2003端口占用的问题及解决

《kkFileView启动报错:报错2003端口占用的问题及解决》kkFileView启动报错因office组件2003端口未关闭,解决:查杀占用端口的进程,终止Java进程,使用shutdown.s... 目录原因解决总结kkFileViewjavascript启动报错启动office组件失败,请检查of

Python对接支付宝支付之使用AliPay实现的详细操作指南

《Python对接支付宝支付之使用AliPay实现的详细操作指南》支付宝没有提供PythonSDK,但是强大的github就有提供python-alipay-sdk,封装里很多复杂操作,使用这个我们就... 目录一、引言二、准备工作2.1 支付宝开放平台入驻与应用创建2.2 密钥生成与配置2.3 安装ali

PyQt5 GUI 开发的基础知识

《PyQt5GUI开发的基础知识》Qt是一个跨平台的C++图形用户界面开发框架,支持GUI和非GUI程序开发,本文介绍了使用PyQt5进行界面开发的基础知识,包括创建简单窗口、常用控件、窗口属性设... 目录简介第一个PyQt程序最常用的三个功能模块控件QPushButton(按钮)控件QLable(纯文本

Linux系统中查询JDK安装目录的几种常用方法

《Linux系统中查询JDK安装目录的几种常用方法》:本文主要介绍Linux系统中查询JDK安装目录的几种常用方法,方法分别是通过update-alternatives、Java命令、环境变量及目... 目录方法 1:通过update-alternatives查询(推荐)方法 2:检查所有已安装的 JDK方

SQL Server安装时候没有中文选项的解决方法

《SQLServer安装时候没有中文选项的解决方法》用户安装SQLServer时界面全英文,无中文选项,通过修改安装设置中的国家或地区为中文中国,重启安装程序后界面恢复中文,解决了问题,对SQLSe... 你是不是在安装SQL Server时候发现安装界面和别人不同,并且无论如何都没有中文选项?这个问题也

Java Thread中join方法使用举例详解

《JavaThread中join方法使用举例详解》JavaThread中join()方法主要是让调用改方法的thread完成run方法里面的东西后,在执行join()方法后面的代码,这篇文章主要介绍... 目录前言1.join()方法的定义和作用2.join()方法的三个重载版本3.join()方法的工作原

2025版mysql8.0.41 winx64 手动安装详细教程

《2025版mysql8.0.41winx64手动安装详细教程》本文指导Windows系统下MySQL安装配置,包含解压、设置环境变量、my.ini配置、初始化密码获取、服务安装与手动启动等步骤,... 目录一、下载安装包二、配置环境变量三、安装配置四、启动 mysql 服务,修改密码一、下载安装包安装地