Sheffield
Sheffield

Reputation: 413

How to get the full class name of a widget in the Android layout xml file?

For some reason, I want to get the full class name of a widget used in the layout file. Some are displayed by full class name like android.support.constraint.ConstraintLayout while some default widgets are not.

For example, in the code below, TextView actually corresponds to android.widget.TextView.

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

All these widget type tags with abbreviated form in XML files come from android.widget package? Or in which files these dependencies determined?

Upvotes: 3

Views: 2017

Answers (2)

Mike M.
Mike M.

Reputation: 39191

Let me begin by saying that you can't really be certain of the exact runtime type that a tag will result in merely by inspecting the layout. LayoutInflater is the (base) class that handles translating layouts to runtime View hierarchies, and its Factory interface "plugin" setup, along with Android's open inheritance component design, present several points where default layout inflation can be modified, or completely overridden. Furthermore, there is no technical requirement that any particular name produce any specific subtype of View.

However, you're probably safe to make some basic assumptions, in general – e.g., a <Button> tag will likely result in an instance of android.widget.Button, or a subclass thereof – because otherwise things could get nonsensical and broken pretty quick. Most often, these inflation modifications are made in order to enhance or extend the base UI types, rather than to wildly alter the standard procedures.

That said, on its own the platform inflater will look in the following four packages, in order, for any View name that does not contain a period (.), which is the sole criterion used to distinguish abbreviated class names from fully qualified ones:

  • android.widget, where most of the available platform View classes are to be found.
  • android.webkit, for <WebView>.
  • android.app, for <ActivityView>, used only by the system and hidden from the SDK.
  • android.view, for <View>, <SurfaceView>, <TextureView>, and a few more hidden ones.

Before that, though, it will have given first chance to create a View to (potentially) multiple Factory implementations, and it will not bother to look if any of those return one. If they don't, then the inflater will check the aforementioned packages, successively prepending each one to the abbreviated name, and attempting to load the result as a View subclass using the Context's ClassLoader.

If the abbreviated name doesn't exist in any of those packages, you will eventually get a rethrown ClassNotFoundException (wrapped in an InflateException) with a message saying Didn't find class "android.view.BadLayoutTagName", showing that android.view is indeed the last package checked.


Possibly the most common external Factory implementation these days comes from the AndroidX and Material Components libraries, and those both will substitute their own extended classes for a number of the platform Views, so you should at least be aware of this.

AndroidX's Factory delegates View creation to a helper class, AppCompatViewInflater, which makes the following substitutions:

Tag name: In package 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

The Material Components library is built on AndroidX, and it further customizes AppCompatViewInflater with its own subclass, MaterialComponentsViewInflater, overriding a few of the above substitutions thusly:

Tag name: In package com.google.android.material:
AutoCompleteTextView textfield.MaterialAutoCompleteTextView
Button button.MaterialButton
CheckBox checkbox.MaterialCheckBox
RadioButton radiobutton.MaterialRadioButton
TextView textview.MaterialTextView

Lastly, I would mention that there are various other tags that are not for Views, and that would normally be consumed by LayoutInflater or a Factory. Since you're processing these layouts yourself, you may need to decide what these mean for your specific aims.

Finally, there is the <view> tag – with a lowercase v – which must have a class attribute (no prefix) with a value specifying the desired View class, abbreviated or full. This alternate format exists to allow for nested classes, as their names will contain the $ character, which is not allowed in an XML tag name.

Upvotes: 3

Abdul Waheed
Abdul Waheed

Reputation: 4678

TextView, Buttons etc are all these bundled by default but other widgets like Constraint Layout and etc they are not bundled by default they are part of support library. That's why you need give full package name. On the other hand, you can do the Same thing with widgets those are bundled by default as well(you can give complete package name for text view as well in XML). But there is no need to do so.

Upvotes: 1

Related Questions