Understanding setFactory

An ordinary set or get a View, using more is setContentView or LayoutInflater # inflate, internal setContentView is achieved by calling LayoutInflater # inflate (specifically called AppCompatViewInflater # setContentView (ind resId) in).

Xml layout files can be resolved by LayoutInflater # inflate View as needed, by analyzing LayoutInflate # inflate the source code, you can see the layout .xml file parsing process will call LayoutInflater # rInflate, will then be created by invoking LayoutInflater # createViewFromTag View. It is recommended "to meet LayoutInflater & Factory"
Let's look at the process of creating View of LayoutInflate # createViewFormTag together:

View createViewFromTag(View parent, String name, Context context, AttributeSet attrs,
boolean ignoreThemeAttr) {
if (name.equals("view")) {
name = attrs.getAttributeValue(null, "class");
}

// Apply a theme wrapper, if allowed and one is specified.
if (!ignoreThemeAttr) {
final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME);
final int themeResId = ta.getResourceId(0, 0);
if (themeResId != 0) {
context = new ContextThemeWrapper(context, themeResId);
}
ta.recycle();
}

if (name.equals(TAG_1995)) {
// Let's party like it's 1995!
return new BlinkLayout(context, attrs);
}

{the try
View View;
IF (! mFactory2 = null) {
// The attrs information created by View mFactory2
View = mFactory2.onCreateView (parent, name, context, attrs);
} the else IF (mFactory = null!) {
// The attrs information created by View mFactory
View mFactory.onCreateView = (name, context, attrs);
} the else {
View = null;
}

if (view == null && mPrivateFactory != null) {
view = mPrivateFactory.onCreateView(parent, name, context, attrs);
}

IF (View == null) {
Final Object lastContext mConstructorArgs = [0];
mConstructorArgs [0] = context;
the try {
IF ( '.' name.indexOf -1 == ()) {
// Create View Android native ( android.view packet following View)
View = onCreateView (parent, name, attrs);
} the else {
// create a custom package or rely View View (XML is declared full path)
View the createView = (name, null , attrs);
}
} {the finally
mConstructorArgs [0] = lastContext;
}
}

return view;
} catch (InflateException e) {
throw e;

} catch (ClassNotFoundException e) {
final InflateException ie = new InflateException(attrs.getPositionDescription()
+ ": Error inflating class " + name, e);
ie.setStackTrace(EMPTY_STACK_TRACE);
throw ie;

} catch (Exception e) {
final InflateException ie = new InflateException(attrs.getPositionDescription()
+ ": Error inflating class " + name, e);
ie.setStackTrace(EMPTY_STACK_TRACE);
throw ie;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41 is
42 is
43 is
44 is
45
46 is
47
48
49
50
51 is
52 is
53 is
54 is
55
56 is
57 is
58
59
60
61 is
62 is
63 is
64
65
66
67
68
69
70
As can be seen from the above-described process of creating the source code of View, will first find Factory2 # onCreateView and Factory # onCreateView to create, and then take the default creation process. So, we can create here Factory2 Factory or custom, or add Factory2 Factory objects and custom objects to LayoutInflater them to intervene in the creation View, LayoutInflate also provides related API for us to add your own ViewFactory.

For example: Let LayoutInflater provided by the Factory to the view Button convert TextView

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
LayoutInflater.from(this).setFactory(new LayoutInflater.Factory() {
@Override
public View onCreateView(String name, Context context, AttributeSet attrs) {
for (int i = 0; i < attrs.getAttributeCount(); i ++){
String attrName = attrs.getAttributeName(i);
String attrValue = attrs.getAttributeValue(i);
Log.i(TAG, String.format("name = %s, attrName = %s, attrValue= %s", name, attrName, attrValue));
}
TextView textView = null;
if (name.equals("Button")){
textView = new TextView(context, attrs);
}

the textView return;
}
});
super.onCreate (savedInstanceState);
; the setContentView (R.layout.activity_theme_change)
}
. 1
2
. 3
. 4
. 5
. 6
. 7
. 8
. 9
10
. 11
12 is
13 is
14
15
16
. 17
18 is
. 19
20 is
21 is
the start Activity After allowing , view Button are transformed into TextView, and can see the output:

= the Button name, ID = attrName, attrValue The 2,131,230,758 = @
name = the Button, attrName = background, attrValue The 2,131,034,152 = @
name = the Button, layout_width attrName =, = -2 attrValue The
name = the Button, layout_height attrName =, = -2 attrValue The
name = the Button, attrName ID =, = attrValue The 2,131,230,757 @
name = the Button, attrName = background, attrValue The 2,131,034,150 = @
name = the Button, layout_width attrName =, = -2 attrValue The
name = the Button, attrName = layout_height, attrValue The = -2
. 1
2
. 3
. 4
5
6
7
8
obtain any of the apk file compression resource object of
this process have been provided to change the View type and attributes of the way, let's see how to get a resource res apk compressed file.

We usually get resources under the res directory by Context # getSource (), Context # getAssets () ( want to Context # getSource (). GetAssets ( )) access to resources in the asset catalog. So, to get resources apk file a compressed file, create a Resource instance to be a compressed file, and then get the resource information in the compressed file by this example.
For example, Resource newly created instance is mResource, it can be used mResource.getColor (colorId), to obtain the corresponding color colorID examples.

The question then is divided into two steps:
--------------------- 

Guess you like

Origin www.cnblogs.com/ly570/p/11284690.html