主要内容
图一 总览对Android Studio支持的六类Android Lint规则, 本文主要对Accessibility 和 Internationalization 两中类型所包含的14个项的说明,主要内容都是文档翻译,适当加一些自己的感想。
Accessibility
可访问性的检查,除了第一项之外,其他项更像是为某些自动化的工具做的准备工作,不影响APP的运行。
ClickableViewAccessibility
ClickableViewAccessibility可点击View的可访问性:如果重写onTouchEvent或使用OnTouchListener的View在检测到单击时没有实现performClick并调用它,则视图可能无法正确处理可访问性操作。理想情况下,处理单击操作的逻辑应该放在View#performClick中,因为当单击操作发生时,一些可访问性服务会调用performClick。
ContentDescription
ContentDescription - 1非文本Widget描述:
- 首先,像ImageViews和ImageButtons这样的非文本Widget应该使用contentDescription属性指定文本对Widget进行说明,以便屏幕阅读器和其他可访问性工具能够充分描述和理解用户界面。
- 其次,如果一个非文本Widget在用户界面上只是一个装饰,不展示任何内容也不接受任何用户操作,就不需要给它提供描述性的contentDescription属性文本,而是使用tool属性tools:ignore="ContentDescription"抑制lint提醒。
- 第三,对于文本型Widget不能同时设置hint和contentDescription,否则hint将不会展示在界面上,只设置hint就可以。
参考:Make apps more accessible
ContentDescription - 2GetContentDescriptionOverride
重写非文本Widget描述方法getContentDescription:重写View的getContentDescription方法,可能会阻止某些可访问性服务正确导航视图公开的内容。相反,当内容描述需要更改时,调用setContentDescription。
KeyboardInaccessibleWidget
KeyboardInaccessibleWidget - 1KeyboardInaccessibleWidget - 2键盘无法访问Widget:如果一个Widget声明了可以点击,但是没有声明可以获得焦点,这个Widget是无法通过键盘访问的,需要设置focusable=true。
LabelFor
LabelFor - 1LabelFor - 2缺少可访问标签:可编辑的控件例如EditText应该为hint属性赋值,或者在minSDKVersion大于等于17时,使用labelFor属性为EditText指定一个标签控件。标签控件可以是指定了text属性的文字控件如TextView,也可以是指定了contentDescription的非文字控件如ImageView。
LabelFor - 3如果被指定的标签控件如TextView在另外一个layout文件中,且使用layout属性引用了EditText所在的layout文件,可以ignore这个lint检查。
Internationalization
ByteOrderMark
查了一下这个ByteOrderMark,简称BOM,指的是一些标记字符。这种问题一般是“在不同编码格式的文件之间拷贝字符或者在某些文件系统上编辑了文件”导致的。
文件内BOM提醒:Lint会把文件中包含的BOM字符标记出来。因为Android工程中我们期望使用utf-8对文件和字符进行编码。BOM字符对utf-8来说不是必需的,而且有一些工具是不能正确处理带BOM字符的文本的。
参考:Android提示BOM错误排查、UTF8最好不要带BOM
EnforceUTF8
EnforceUTF8资源文件编码格式非utf-8:XML文件对编码类型的支持比较广泛。然而有些工具不能正确某些类型编码的文件,而utf-8在Android应用中是一种被广泛支持的编码类型。使用utf-8对文件进行编码,可以防止在处理non-ASCII类型的字符时出现奇怪的问题。尤其是Gradle在合并XML类型的资源文件时,预先假定文件是使用utf-8进行编码的。
HardcodedText
HardcodedText硬编码文本属性:不要在layout文件或者代码中直接为文本控件设置text属性值。
- 在不同的位置多次使用相同的文本,如果需要修改文本则会引起多处修改。
- APP不能通过为文本提供一份翻译列表就可以适用新的语言的用户,而有很多工具可以快速的完成提供翻译列表的操作。
- 好的做法是,把text属性的文本值定义在string.xml文件中,方便国际化拓展。
SetTextI18n
SetTextI18nTextView国际化:在调用TextView.setText()给TextView赋值时,不能使用Number.toString()例如图中的Integer.toString(mProfile.getLeftStarCount())把数字转为字符串赋值,因为Number.toString()不能正确处理分隔符和特定语言环境中的数字。
建议使用 String.format() 指定合适的占位符进行赋值。
不能直接使用文本给TextView.setText(),具体参照HardcodedText的说明。代码中可以使用@SuppressLint("SetTextI18n") 禁用lint的这项检查。
RelativeOverlap
RelativeOverlapRelativeOverlap是指RelativeLayout位于同一水平方向的两个Widget分别位于layout的左右两边,又都没有限制控件的长度,随着内容的增长,两个控件中间的距离不断缩小,最后会有部分重叠。所以,要控制一下边界。
Bidrrectional Text 双向文本
RtlEnabled
在API 17或更高版本上使用RTL属性需要在manifest文件的application标签中设置android:supportsRtl="true"。如果已经开始在layout文件中加入RTL属性,但是没有完全使用RTL替代旧版的属性设置,可以设置android:supportsRtl="false"规避lint的检查。
RtlCompat
RtlCompatAPI 17以后给文本控件提供了一个textAlignment属性来控制水平方向文字的对齐方式。但是,如果APP支持的版本包含小于 API 17 的版本,那么必须要设置gravity或者layout_gravity属性,因为老版本的系统会忽略textAlignment属性值。
RtlHardcoded
强制方向设置:在文本对齐和控件对齐中使用Gravity.LEFT/Gravity.RIGHT的方式指定在左侧或者右侧对齐的情形,或在文字从右往左书写的国家或者地区造成困扰。使用Gravity.START/Gravity.END就可以解决这个问题。同理,在layout文件中设置gravity/layout_gravity属性时使用start/end替代left/right。
属性paddingLeft/paddingRight和属性layout_marginLeft/layout_marginRight也需要替换为paddingStart/paddingEnd和layout_marginStart/layout_marginEnd。
如果APP支持的最小API版本小于 API 17,那么需要同时提供left/right属性和start/end属性,因为低版本的系统会忽略start/end属性。
RtlSymmetry
margin|padding左右对称:如果对一个layout对象指定一边的内边距或外边距,那么应该对另一边指定同样大小的内边距或外边距。
参考文献
- android tools属性引用