怎么在Android布局XML文件中获取Widget的全类名称?

本教程将介绍如何在Android布局XML文件中获取Widget的全类名称?的处理方法,这篇教程是从别的地方看到的,然后加了一些国外程序员的疑问与解答,希望能对你有所帮助,好了,下面开始学习吧。

问题描述

出于某种原因,我想获取布局文件中使用的小部件的完整类名。有些小部件按类全名显示,如android.support.constraint.ConstraintLayout,而有些默认小部件则不是。

例如,在下面的代码中,TextView实际上对应于android.widget.TextView

<TextView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="Hello World!" />

所有这些在XML文件中具有缩写形式的小部件类型标记都来自android.widget包?或者这些依赖项确定在哪些文件中?

推荐答案

首先我要说的是,仅仅通过检查布局并不能真正确定标记将导致的确切运行时类型。LayoutInflater是处理将布局转换为运行时View层次结构的(基类)类,它的Factory接口&插件和设置,以及Android的开放继承组件设计,提供了几个可以修改或完全覆盖默认布局膨胀的点。此外,没有技术要求任何特定名称产生View的任何特定子类型。

但是,通常您可以安全地进行一些基本假设–例如,<Button>标记可能会导致android.widget.Button的实例或其子类–否则事情可能很快就会变得毫无意义和崩溃。大多数情况下,进行这些膨胀修改是为了增强或扩展基本UI类型,而不是大幅更改标准过程。

也就是说,平台充气程序将按顺序在以下四个包中查找任何不包含句点(.)的View名称,这是用于区分缩写类名和完全限定类名的唯一标准:

    android.widget,其中可以找到大多数可用平台View类。

    android.webkit,用于<WebView>

    android.app,对于<ActivityView>,仅供系统使用,对SDK隐藏。

    android.view<View><SurfaceView><TextureView>以及更多隐藏项。

在此之前,它将首先有机会创建一个View到(可能)多个Factory实现,并且它不会费心查看其中是否有任何一个返回一个。如果没有,则充气器将检查上述包,将每个包连续添加到缩写名称的前面,并尝试使用ContextClassLoader将结果加载为View子类。

如果缩写名称在这些包中都不存在,您最终将得到一个重新抛出的ClassNotFoundException(包装在InflateException中),并显示一条消息Didn't find class "android.view.BadLayoutTagName",表明android.view确实是最后检查的包。


目前最常见的外部Factory实现可能来自androidX和Material组件库,这两个库都将用它们自己的扩展类替换许多平台View,因此您至少应该意识到这一点。

androidX的FactoryView创建委托给一个helper类AppCompatViewInflater,该类进行以下替换:

标记名: 在包androidx.appcompat.widget中:
AutoCompleteTextView AppCompatAutoCompleteTextView
Button AppCompatButton
CheckBox AppCompatCheckBox
CheckedTextView AppCompatCheckedTextView
EditText AppCompatEditText
ImageButton AppCompatImageButton
ImageView AppCompatImageView
MultiAutoCompleteTextView AppCompatMultiAutoCompleteTextView
RadioButton AppCompatRadioButton
RatingBar AppCompatRatingBar
SeekBar AppCompatSeekBar
Spinner AppCompatSpinner
TextView AppCompatTextView
ToggleButton AppCompatToggleButton

材料组件库构建在androidX上,它使用自己的子类MaterialComponentsViewInflater进一步定制了AppCompatViewInflater,从而覆盖了上面的几个替换:

标记名: 包中com.google.android.material
AutoCompleteTextView textfield.MaterialAutoCompleteTextView
Button button.MaterialButton
CheckBox checkbox.MaterialCheckBox
RadioButton radiobutton.MaterialRadioButton
TextView textview.MaterialTextView

最后,我想提一下,还有各种不是用于View的其他标记,这些标记通常由LayoutInflaterFactory使用。由于您自己处理这些布局,因此您可能需要确定这些布局对您的特定目标意味着什么。

    <include>,用于reusing complete layouts。

    <merge>,用于reusing layout "inners", without an enclosing parent。

    <requestFocus>,布局后尝试设置焦点。

    <tag>,用于向Layout XML中的View添加键控标签(仅适用于棒棒糖及更高版本)。

    <blink>,您可能永远看不到的Easter egg。

    <fragment>,实际由Activity作为其LayoutInflater的私有Factory2处理。

最后是<view>标记–小写的v–它必须有一个class属性(无前缀),该属性的值指定所需的View类(缩写或完整)。此替代格式的存在是为了允许嵌套类,因为它们的名称将包含$字符,这在XML标记名称中是不允许的。

好了关于怎么在Android布局XML文件中获取Widget的全类名称?的教程就到这里就结束了,希望趣模板源码网找到的这篇技术文章能帮助到大家,更多技术教程可以在站内搜索。

0
没有账号?注册  忘记密码?