技术标签: android ui 进阶
1、概述
在Android 事件传递与焦点处理(tv) 这篇中有描述android 的事件传递与拦截分发的流程
这篇描述一下具体的一些焦点处理
先再提一下最常见的ViewGroup中的三种焦点处理方式,后续详细描述
FOCUS_BEFORE_DESCENDANTS 0x20000 默认
ViewGroup本身先对焦点进行处理,如果没有处理则分发给child View进行处理
FOCUS_AFTER_DESCENDANTS 0x40000
先分发给Child View进行处理,如果所有的Child View都没有处理,则自己再处理
FOCUS_BLOCK_DESCENDANTS 0x60000
ViewGroup本身进行处理,不管是否处理成功,都不会分发给ChildView进行处理
2、listView gridView 抢焦点 问题
(1)、 最常见的 item抢焦点
当item有焦点时,item上的button等子控件获取不到焦点;
当子控件有焦点时,item无焦点无法响应onItemClick事件
解决:(原因后面分析)
把焦点处理方式设成 FOCUS_BLOCK_DESCENDANTS
可以在xml中设置 也可以在代码里设置
(2)、listView GridView 在界面中抢了焦点
比如一个界面中有button gridView 还有其他的一些界面元素,一打开第一个焦点就落在gridView的item0 上
之所以用gridView说事,是实际中自己在写tv 界面时他老抢,listView与gridView类比
后面是用listView 或者 gridView 描述以实际使用中为准
解决:界面一启动的时候先把gridView 的gridView.setFocusable(false); 然后要使用的时候再使能回来
ps:在使用gridView 和listView 的技巧
a) onItemSelected 不会重复调用
如果监听了 setOnItemSelectedListener 使用setSelection(int position) 如果gridViewsetFocusable 没有使能, item是不会有focus的效果的,而且两次先后两次setSelection 同一个postition onItemSelected监听在第二次重复的时候是不会调用的。声明下这里的先后两次包括:第一次selection 然后离开到其他元素比如其他的listView 然后再select回来也算是先后两次调用只要中间不是调用自己的其他item。
b) item 的focus技巧
另外 一个listView在某个item focus了之后。下一步焦点转移到其他元素控件。想再回到该item 比较简单的方式是让该listView.requestFocus() 该item自然就又focus出来了。
比较简单,这也充分的说明了一个问题单焦点离开listview的时候select的状态还是在的只是没有focus的效果显示出来这个可以通过读取 listView.getSelectedItemPosition() 看到。
c)所以在使用listView gridView 需要item高亮的时候 尽量使用item来高亮不要用内部元素高亮
3、ListView GridView ViewGroup 的焦点分析
简单的描述下为什么FOCUS_BEFORE_DESCENDANTS FOCUS_AFTER_DESCENDANTS FOCUS_BLOCK_DESCENDANTS 三种的处理方式是怎么来的,为什么会被抢焦点
3.1 ViewGroup 分析 三种焦点拦截方式与 onRequestFocusInDescendants 函数(子view处理函数)
ViewGroup 中:
看源码 requestFocus() 函数 可以看出FOCUS_BLOCK_DESCENDANTS FOCUS_BEFORE_DESCENDANTS FOCUS_AFTER_DESCENDANTS 这三个标签的区别 和对onRequestFocusInDescendants() 的调用顺序
@Override public boolean requestFocus(int direction, Rect previouslyFocusedRect) { if (DBG) { System.out.println(this + " ViewGroup.requestFocus direction=" + direction); } int descendantFocusability = getDescendantFocusability(); switch (descendantFocusability) { case FOCUS_BLOCK_DESCENDANTS://ViewGroup本身进行处理,不管是否处理成功,都不会分发给ChildView进行处理
return super.requestFocus(direction, previouslyFocusedRect); case FOCUS_BEFORE_DESCENDANTS: {//ViewGroup本身先对焦点进行处理,如果没有处理(返回false)则分发给child View进行处理 final boolean took = super.requestFocus(direction, previouslyFocusedRect); return took ? took : onRequestFocusInDescendants(direction, previouslyFocusedRect); } case FOCUS_AFTER_DESCENDANTS: {//先分发给Child View进行处理,如果所有的Child View都没有处理(false),则自己再处理 //final boolean took = onRequestFocusInDescendants(direction, previouslyFocusedRect); return took ? took : super.requestFocus(direction, previouslyFocusedRect); } default: throw new IllegalStateException("descendant focusability must be " + "one of FOCUS_BEFORE_DESCENDANTS, FOCUS_AFTER_DESCENDANTS, FOCUS_BLOCK_DESCENDANTS " + "but is " + descendantFocusability); } }然后 就是子类可以重写的 onRequestFocusInDescendants 默认的函数如下可以看出,是按顺序的 逐个看看能不能获取焦点protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) { int index; int increment; int end; int count = mChildrenCount; if ((direction & FOCUS_FORWARD) != 0) { index = 0; increment = 1; end = count; } else { index = count - 1; increment = -1; end = -1; } final View[] children = mChildren; for (int i = index; i != end; i += increment) { View child = children[i]; if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE) { if (child.requestFocus(direction, previouslyFocusedRect)) { return true; } } } return false; }viewGroup的默认配置
initViewGroup() -> setDescendantFocusability(FOCUS_BEFORE_DESCENDANTS);//ViewGroup本身先对焦点进行处理,如果没有处理则分发给child View进行处理。
注:这里的
ViewGroup 本身先对焦点进行处理指的就是:super.requestFocus(direction, previouslyFocusedRect);
分发给child view 处理指的就是:onRequestFocusInDescendants() 函数里的处理过程,是这个函数决定具体分发给哪个childView处理,或者直接拦截不处理。
3.2 listView 的分析listView 的表现在这个blog 里描述的 挺详细:http://www.it165.net/pro/html/201406/15086.htmlListView 的源码中没有看到对viewGroup 设置 setDescendantFocusability 采用默认的值 则自己没有处理 逐个分发给子view处理,那么
/** * Indicates that the views created by the ListAdapter can contain focusable * items. * * @param itemsCanFocus true if items can get focus, false otherwise */ public void setItemsCanFocus(boolean itemsCanFocus) { mItemsCanFocus = itemsCanFocus; if (!itemsCanFocus) { setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); } }
文章浏览阅读2.1k次。原文链接先说说编解码问题编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码。 Eg:str1.decode('gb2312') #将gb2312编码的字符串转换成unicode编码str2.encode('gb2312') #将unicode编码..._python中encode在什么模块
文章浏览阅读949次,点赞21次,收藏15次。本文介绍了Java中的数据输入流(DataInputStream)和数据输出流(DataOutputStream)的使用方法。
文章浏览阅读111次。ie无法兼容_ie 浏览器 newdate
文章浏览阅读239次。这篇文章把 Docker 和 K8s 的关系给大家做了一个解答,希望还在迟疑自己现有的知识储备能不能直接学 K8s 的,赶紧行动起来,K8s 是典型的入门有点难,后面越用越香。
文章浏览阅读561次。ADI中文手册获取方法_adi 如何查看数据手册
文章浏览阅读1k次,点赞4次,收藏3次。React 获取接口数据实现分页效果以拼多多接口为例实现思路加载前 加载动画加载后 判断有内容的时候 无内容的时候用到的知识点1、动画效果(用在加载前,加载之后就隐藏或关闭,用开关效果即可)2、axios请求3、map渲染页面4、分页插件(antd)代码实现import React, { Component } from 'react';//引入axiosimport axios from 'axios';//引入antd插件import { Pagination }_react 分页
文章浏览阅读449次,点赞9次,收藏7次。这个变量与验签过程中的SignatureVerificationFilter::PUT_MESSAGE这个宏是对应的,SignatureVerificationFilter::PUT_MESSAGE,如果在签名过程中putMessage设置为true,则在验签过程中需要添加SignatureVerificationFilter::PUT_MESSAGE。项目中使用到了CryPtopp库进行RSA签名与验签,但是在使用过程中反复提示无效的数字签名。否则就会出现文章开头出现的数字签名无效。_cryptopp 签名
文章浏览阅读848次。新闻稿是新闻从业者经常使用的一种文体,它的格式与内容都有着一定的规范。本文将从新闻稿的格式和范文两个方面进行介绍,以帮助读者更好地了解新闻稿的写作_新闻稿时间应该放在什么位置
文章浏览阅读1.7k次。Java中的转换器设计模式 在这篇文章中,我们将讨论 Java / J2EE项目中最常用的 Converter Design Pattern。由于Java8 功能不仅提供了相应类型之间的通用双向转换方式,而且还提供了转换相同类型对象集合的常用方法,从而将样板代码减少到绝对最小值。我们使用Java8 功能编写了..._java转换器模式
文章浏览阅读150次。1,kubectl run创建pods[root@master ~]# kubectl run nginx-deploy --image=nginx:1.14-alpine --port=80 --replicas=1[root@master ~]# kubectl get podsNAME READY STATUS REST...
文章浏览阅读128次。PAT菜鸡进化史_乙级_1003“答案正确”是自动判题系统给出的最令人欢喜的回复。本题属于 PAT 的“答案正确”大派送 —— 只要读入的字符串满足下列条件,系统就输出“答案正确”,否则输出“答案错误”。得到“答案正确”的条件是: 1. 字符串中必须仅有 P、 A、 T这三种字符,不可以包含其它字符; 2. 任意形如 xPATx 的字符串都可以获得“答案正确”,其中 x 或者是空字符串,或..._1003 pat乙级 最优
文章浏览阅读5.6k次。CH340与Android串口通信为何要将CH340的ATD+Eclipse上的安卓工程移植到AndroidStudio移植的具体步骤CH340串口通信驱动函数通信过程中重难点还存在的问题为何要将CH340的ATD+Eclipse上的安卓工程移植到AndroidStudio为了在这个工程基础上进行改动,验证串口的数据和配置串口的参数,我首先在Eclipse上配置了安卓开发环境,注意在配置环境是..._340串口小板 安卓给安卓发指令