持续更新:详细总结 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

相关文章

Python实现图片分割的多种方法总结

《Python实现图片分割的多种方法总结》图片分割是图像处理中的一个重要任务,它的目标是将图像划分为多个区域或者对象,本文为大家整理了一些常用的分割方法,大家可以根据需求自行选择... 目录1. 基于传统图像处理的分割方法(1) 使用固定阈值分割图片(2) 自适应阈值分割(3) 使用图像边缘检测分割(4)

Java中Switch Case多个条件处理方法举例

《Java中SwitchCase多个条件处理方法举例》Java中switch语句用于根据变量值执行不同代码块,适用于多个条件的处理,:本文主要介绍Java中SwitchCase多个条件处理的相... 目录前言基本语法处理多个条件示例1:合并相同代码的多个case示例2:通过字符串合并多个case进阶用法使用

Mysql如何解决死锁问题

《Mysql如何解决死锁问题》:本文主要介绍Mysql如何解决死锁问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录【一】mysql中锁分类和加锁情况【1】按锁的粒度分类全局锁表级锁行级锁【2】按锁的模式分类【二】加锁方式的影响因素【三】Mysql的死锁情况【1

Python中__init__方法使用的深度解析

《Python中__init__方法使用的深度解析》在Python的面向对象编程(OOP)体系中,__init__方法如同建造房屋时的奠基仪式——它定义了对象诞生时的初始状态,下面我们就来深入了解下_... 目录一、__init__的基因图谱二、初始化过程的魔法时刻继承链中的初始化顺序self参数的奥秘默认

SpringBoot内嵌Tomcat临时目录问题及解决

《SpringBoot内嵌Tomcat临时目录问题及解决》:本文主要介绍SpringBoot内嵌Tomcat临时目录问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录SprinjavascriptgBoot内嵌Tomcat临时目录问题1.背景2.方案3.代码中配置t

SpringBoot使用GZIP压缩反回数据问题

《SpringBoot使用GZIP压缩反回数据问题》:本文主要介绍SpringBoot使用GZIP压缩反回数据问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot使用GZIP压缩反回数据1、初识gzip2、gzip是什么,可以干什么?3、Spr

html5的响应式布局的方法示例详解

《html5的响应式布局的方法示例详解》:本文主要介绍了HTML5中使用媒体查询和Flexbox进行响应式布局的方法,简要介绍了CSSGrid布局的基础知识和如何实现自动换行的网格布局,详细内容请阅读本文,希望能对你有所帮助... 一 使用媒体查询响应式布局        使用的参数@media这是常用的

Windows Docker端口占用错误及解决方案总结

《WindowsDocker端口占用错误及解决方案总结》在Windows环境下使用Docker容器时,端口占用错误是开发和运维中常见且棘手的问题,本文将深入剖析该问题的成因,介绍如何通过查看端口分配... 目录引言Windows docker 端口占用错误及解决方案汇总端口冲突形成原因解析诊断当前端口情况解

Spring 基于XML配置 bean管理 Bean-IOC的方法

《Spring基于XML配置bean管理Bean-IOC的方法》:本文主要介绍Spring基于XML配置bean管理Bean-IOC的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录一. spring学习的核心内容二. 基于 XML 配置 bean1. 通过类型来获取 bean2. 通过

MySql match against工具详细用法

《MySqlmatchagainst工具详细用法》在MySQL中,MATCH……AGAINST是全文索引(Full-Textindex)的查询语法,它允许你对文本进行高效的全文搜素,支持自然语言搜... 目录一、全文索引的基本概念二、创建全文索引三、自然语言搜索四、布尔搜索五、相关性排序六、全文索引的限制七