/*
* 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);
}
}
}