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

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

好题——hdu2522(小数问题:求1/n的第一个循环节)

好喜欢这题,第一次做小数问题,一开始真心没思路,然后参考了网上的一些资料。 知识点***********************************无限不循环小数即无理数,不能写作两整数之比*****************************(一开始没想到,小学没学好) 此题1/n肯定是一个有限循环小数,了解这些后就能做此题了。 按照除法的机制,用一个函数表示出来就可以了,代码如下

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

poj3468(线段树成段更新模板题)

题意:包括两个操作:1、将[a.b]上的数字加上v;2、查询区间[a,b]上的和 下面的介绍是下解题思路: 首先介绍  lazy-tag思想:用一个变量记录每一个线段树节点的变化值,当这部分线段的一致性被破坏我们就将这个变化值传递给子区间,大大增加了线段树的效率。 比如现在需要对[a,b]区间值进行加c操作,那么就从根节点[1,n]开始调用update函数进行操作,如果刚好执行到一个子节点,

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

hdu1689(线段树成段更新)

两种操作:1、set区间[a,b]上数字为v;2、查询[ 1 , n ]上的sum 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>#include<map>#include<stdio.h>#include<stdl