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

相关文章

JAVA中安装多个JDK的方法

《JAVA中安装多个JDK的方法》文章介绍了在Windows系统上安装多个JDK版本的方法,包括下载、安装路径修改、环境变量配置(JAVA_HOME和Path),并说明如何通过调整JAVA_HOME在... 首先去oracle官网下载好两个版本不同的jdk(需要登录Oracle账号,没有可以免费注册)下载完

SpringSecurity整合redission序列化问题小结(最新整理)

《SpringSecurity整合redission序列化问题小结(最新整理)》文章详解SpringSecurity整合Redisson时的序列化问题,指出需排除官方Jackson依赖,通过自定义反序... 目录1. 前言2. Redission配置2.1 RedissonProperties2.2 Red

nginx 负载均衡配置及如何解决重复登录问题

《nginx负载均衡配置及如何解决重复登录问题》文章详解Nginx源码安装与Docker部署,介绍四层/七层代理区别及负载均衡策略,通过ip_hash解决重复登录问题,对nginx负载均衡配置及如何... 目录一:源码安装:1.配置编译参数2.编译3.编译安装 二,四层代理和七层代理区别1.二者混合使用举例

nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析(结合应用场景)

《nginx-t、nginx-sstop和nginx-sreload命令的详细解析(结合应用场景)》本文解析Nginx的-t、-sstop、-sreload命令,分别用于配置语法检... 以下是关于 nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析,结合实际应

Spring boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

Java中读取YAML文件配置信息常见问题及解决方法

《Java中读取YAML文件配置信息常见问题及解决方法》:本文主要介绍Java中读取YAML文件配置信息常见问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录1 使用Spring Boot的@ConfigurationProperties2. 使用@Valu

创建Java keystore文件的完整指南及详细步骤

《创建Javakeystore文件的完整指南及详细步骤》本文详解Java中keystore的创建与配置,涵盖私钥管理、自签名与CA证书生成、SSL/TLS应用,强调安全存储及验证机制,确保通信加密和... 目录1. 秘密键(私钥)的理解与管理私钥的定义与重要性私钥的管理策略私钥的生成与存储2. 证书的创建与

Java 方法重载Overload常见误区及注意事项

《Java方法重载Overload常见误区及注意事项》Java方法重载允许同一类中同名方法通过参数类型、数量、顺序差异实现功能扩展,提升代码灵活性,核心条件为参数列表不同,不涉及返回类型、访问修饰符... 目录Java 方法重载(Overload)详解一、方法重载的核心条件二、构成方法重载的具体情况三、不构

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys