持续更新:详细总结 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中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

MySQL数据库双机热备的配置方法详解

《MySQL数据库双机热备的配置方法详解》在企业级应用中,数据库的高可用性和数据的安全性是至关重要的,MySQL作为最流行的开源关系型数据库管理系统之一,提供了多种方式来实现高可用性,其中双机热备(M... 目录1. 环境准备1.1 安装mysql1.2 配置MySQL1.2.1 主服务器配置1.2.2 从

MyBatis常用XML语法详解

《MyBatis常用XML语法详解》文章介绍了MyBatis常用XML语法,包括结果映射、查询语句、插入语句、更新语句、删除语句、动态SQL标签以及ehcache.xml文件的使用,感兴趣的朋友跟随小... 目录1、定义结果映射2、查询语句3、插入语句4、更新语句5、删除语句6、动态 SQL 标签7、ehc

Python版本信息获取方法详解与实战

《Python版本信息获取方法详解与实战》在Python开发中,获取Python版本号是调试、兼容性检查和版本控制的重要基础操作,本文详细介绍了如何使用sys和platform模块获取Python的主... 目录1. python版本号获取基础2. 使用sys模块获取版本信息2.1 sys模块概述2.1.1

一文详解Python如何开发游戏

《一文详解Python如何开发游戏》Python是一种非常流行的编程语言,也可以用来开发游戏模组,:本文主要介绍Python如何开发游戏的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录一、python简介二、Python 开发 2D 游戏的优劣势优势缺点三、Python 开发 3D

IDEA和GIT关于文件中LF和CRLF问题及解决

《IDEA和GIT关于文件中LF和CRLF问题及解决》文章总结:因IDEA默认使用CRLF换行符导致Shell脚本在Linux运行报错,需在编辑器和Git中统一为LF,通过调整Git的core.aut... 目录问题描述问题思考解决过程总结问题描述项目软件安装shell脚本上git仓库管理,但拉取后,上l

Python实现字典转字符串的五种方法

《Python实现字典转字符串的五种方法》本文介绍了在Python中如何将字典数据结构转换为字符串格式的多种方法,首先可以通过内置的str()函数进行简单转换;其次利用ison.dumps()函数能够... 目录1、使用json模块的dumps方法:2、使用str方法:3、使用循环和字符串拼接:4、使用字符

Python版本与package版本兼容性检查方法总结

《Python版本与package版本兼容性检查方法总结》:本文主要介绍Python版本与package版本兼容性检查方法的相关资料,文中提供四种检查方法,分别是pip查询、conda管理、PyP... 目录引言为什么会出现兼容性问题方法一:用 pip 官方命令查询可用版本方法二:conda 管理包环境方法

Linux云服务器手动配置DNS的方法步骤

《Linux云服务器手动配置DNS的方法步骤》在Linux云服务器上手动配置DNS(域名系统)是确保服务器能够正常解析域名的重要步骤,以下是详细的配置方法,包括系统文件的修改和常见问题的解决方案,需要... 目录1. 为什么需要手动配置 DNS?2. 手动配置 DNS 的方法方法 1:修改 /etc/res

基于Python开发Windows自动更新控制工具

《基于Python开发Windows自动更新控制工具》在当今数字化时代,操作系统更新已成为计算机维护的重要组成部分,本文介绍一款基于Python和PyQt5的Windows自动更新控制工具,有需要的可... 目录设计原理与技术实现系统架构概述数学建模工具界面完整代码实现技术深度分析多层级控制理论服务层控制注