-
Notifications
You must be signed in to change notification settings - Fork 537
Expand file tree
/
Copy pathLayoutInflaterWrapper.java
More file actions
266 lines (247 loc) · 9.75 KB
/
LayoutInflaterWrapper.java
File metadata and controls
266 lines (247 loc) · 9.75 KB
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/*
* Copyright (C) 2015 HouKx <hkx.aidream@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.pluginmgr;
import org.xmlpull.v1.XmlPullParser;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
/**
* LayoutInflater 包装器,用来替换某些系统布局
* <p>
*
* @author HouKangxi
*
*/
class LayoutInflaterWrapper extends LayoutInflater {
private static final String tag = "LayoutInflaterWrapper";
private LayoutInflater target;
private final Class<?> layoutClass;
private final Class<?> idClass;
@SuppressWarnings("unused")
private final Class<?> attrClass;
private final int screen_title;
public LayoutInflaterWrapper(LayoutInflater target) {
super(target.getContext());
this.target = target;
Class<?> layoutClass = null;
Class<?> idClass = null;
Class<?> attrClass = null;
int screen_title = 0;
try {
layoutClass = Class.forName("com.android.internal.R$layout");
idClass = Class.forName("com.android.internal.R$id");
attrClass = Class.forName("com.android.internal.R$attr");
screen_title = layoutClass.getField("screen_title").getInt(null);
} catch (Exception e) {
e.printStackTrace();
}
this.layoutClass = layoutClass;
this.idClass = idClass;
this.attrClass = attrClass;
this.screen_title = screen_title;
}
@Override
public LayoutInflater cloneInContext(Context newContext) {
return target.cloneInContext(newContext);
}
@Override
public Context getContext() {
return target.getContext();
}
@Override
public void setFactory(Factory factory) {
target.setFactory(factory);
}
// public void setFactory2(Factory2 factory) {
// target.setFactory2(factory);
// }
@Override
public Filter getFilter() {
return target.getFilter();
}
@Override
public void setFilter(Filter filter) {
target.setFilter(filter);
}
@Override
public View inflate(int resource, ViewGroup root) {
Log.i(tag, "inflate布局( resource=" + resource + ", root=" + root + " )");
if (resource == screen_title) {
Log.i(tag, "使用自定义布局");
return createLayout_screen_simple(resource, root);
}
return target.inflate(resource, root);
}
/*
* private View createLayout_screen_title(int resource, ViewGroup root) {
* try { int layoutId = Class .forName(getContext().getPackageName() +
* ".R$layout") .getField("screen_title").getInt(null); Context
* frameworkContext = PluginContainer.getInstance() .getContext();
* XmlResourceParser parser = frameworkContext.getResources()
* .getLayout(layoutId); ViewGroup view = (ViewGroup) target.inflate(parser,
* root); showViews(view, 0, "根结点视图"); android.widget.ViewStub stub =
* (android.widget.ViewStub) view .getChildAt(0); Field field =
* idClass.getField("action_mode_bar_stub"); int viewStubId =
* field.getInt(null); stub.setId(viewStubId); return view; } catch
* (Exception e) { e.printStackTrace(); } return target.inflate(resource,
* root); }
*
* private void showViews(View view, int n, String r) { StringBuilder sb =
* new StringBuilder(r); while (n-- > 0) { sb.append('='); } sb.append(' ');
* String msg = sb.toString() + view; Log.i(tag, msg); if (view instanceof
* ViewGroup) { ViewGroup g = (ViewGroup) view; for (int i = 0, len =
* g.getChildCount(); i < len; i++) { View c = g.getChildAt(i); showViews(c,
* n + 1, view.toString()); } } }
*/
private View createLayout_screen_simple(int resource, ViewGroup root) {
LinearLayout lyt = new LinearLayout(getContext());
lyt.setOrientation(LinearLayout.VERTICAL);
if (android.os.Build.VERSION.SDK_INT >= 14) {
try {
LinearLayout.class.getMethod("setFitsSystemWindows",
boolean.class).invoke(lyt, true);
} catch (Throwable e) {
}
}
int viewStubId = 0;
int frameLytId = 0;
int layoutResource = 0;
int inflatedId = 0;
try {
frameLytId = idClass.getField("content").getInt(null);
viewStubId = idClass.getField("action_mode_bar_stub").getInt(null);
inflatedId = idClass.getField("action_mode_bar").getInt(null);
layoutResource = layoutClass.getField("action_mode_bar").getInt(
null);
} catch (Throwable e) {
e.printStackTrace();
}
{
android.widget.ViewStub viewStub = new android.widget.ViewStub(
getContext());
viewStub.setId(viewStubId);
if (inflatedId != 0)
viewStub.setInflatedId(inflatedId);
if (layoutResource != 0)
viewStub.setLayoutResource(layoutResource);
lyt.addView(viewStub, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT));
}
FrameLayout flyt_content = new FrameLayout(getContext());
flyt_content.setId(frameLytId);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT);
// layoutParams.weight = 1;
flyt_content
.setForegroundGravity(Gravity.FILL_HORIZONTAL | Gravity.TOP);
// try {
// int foreground = attrClass.getField("windowContentOverlay").getInt(
// null);
// flyt_content.setForeground(getContext().getResources().getDrawable(
// foreground));
// } catch (Throwable e) {
// e.printStackTrace();
// }
lyt.addView(flyt_content, layoutParams);
return lyt;
}
/*
* private View createLayout_screen_title(int resource, ViewGroup root) {
* LinearLayout lyt = new LinearLayout(getContext());
* lyt.setOrientation(LinearLayout.VERTICAL); if
* (android.os.Build.VERSION.SDK_INT >= 14) { try {
* LinearLayout.class.getMethod("setFitsSystemWindows",
* boolean.class).invoke(lyt, true); } catch (Throwable e) { } } int
* viewStubId = 0; int textViewId = 0; int frameLytId = 0; int
* layoutResource = 0; int inflatedId = 0; try { textViewId =
* idClass.getField("title").getInt(null); frameLytId =
* idClass.getField("content").getInt(null); viewStubId =
* idClass.getField("action_mode_bar_stub").getInt(null); inflatedId =
* idClass.getField("action_mode_bar").getInt(null); // layoutResource =
* layoutClass.getField("action_mode_bar").getInt( // null); } catch
* (Throwable e) { e.printStackTrace(); } { android.widget.ViewStub viewStub
* = new android.widget.ViewStub( getContext()); viewStub.setId(viewStubId);
* viewStub.setInflatedId(inflatedId); if (layoutResource != 0) {
* viewStub.setLayoutResource(layoutResource); } lyt.addView(viewStub, new
* LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT,
* LinearLayout.LayoutParams.WRAP_CONTENT)); } { FrameLayout flyt_top = new
* FrameLayout(getContext()); int windowTitleSize =
* LinearLayout.LayoutParams.WRAP_CONTENT; // try { // windowTitleSize =
* attrClass.getField("windowTitleSize").getInt( // null); // } catch
* (Throwable e) { // e.printStackTrace(); // } TextView textView = new
* TextView(getContext()); textView.setId(textViewId);
* textView.setGravity(Gravity.CENTER_VERTICAL); flyt_top.addView(textView,
* new FrameLayout.LayoutParams( FrameLayout.LayoutParams.MATCH_PARENT,
* FrameLayout.LayoutParams.MATCH_PARENT)); lyt.addView(flyt_top, new
* LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT,
* windowTitleSize)); }
*
* FrameLayout flyt_content = new FrameLayout(getContext());
* flyt_content.setId(frameLytId); LinearLayout.LayoutParams layoutParams =
* new LinearLayout.LayoutParams( LinearLayout.LayoutParams.MATCH_PARENT,
* 0); layoutParams.weight = 1; flyt_content
* .setForegroundGravity(Gravity.FILL_HORIZONTAL | Gravity.TOP); // try { //
* int foreground = attrClass.getField("windowContentOverlay").getInt( //
* null); //
* flyt_content.setForeground(getContext().getResources().getDrawable( //
* foreground)); // } catch (Throwable e) { // e.printStackTrace(); // }
* lyt.addView(flyt_content, layoutParams); return lyt; }
*/
@Override
public View inflate(XmlPullParser parser, ViewGroup root) {
return target.inflate(parser, root);
}
@Override
public View inflate(int resource, ViewGroup root, boolean attachToRoot) {
return target.inflate(resource, root, attachToRoot);
}
@Override
public View inflate(XmlPullParser parser, ViewGroup root,
boolean attachToRoot) {
return target.inflate(parser, root, attachToRoot);
}
@Override
protected View onCreateView(String name, AttributeSet attrs)
throws ClassNotFoundException {
try {
return (View) LayoutInflater.class.getDeclaredMethod(
"onCreateView", String.class, AttributeSet.class).invoke(
target, name, attrs);
} catch (Exception e) {
e.printStackTrace();
return super.onCreateView(name, attrs);
}
}
protected View onCreateView(View parent, String name, AttributeSet attrs)
throws ClassNotFoundException {
try {
return (View) LayoutInflater.class.getDeclaredMethod(
"onCreateView", View.class, String.class,
AttributeSet.class).invoke(target, parent, name, attrs);
} catch (Exception e) {
e.printStackTrace();
return super.onCreateView(name, attrs);
}
}
}