use of com.android.layoutlib.bridge.android.BridgeContext in project android_frameworks_base by ParanoidAndroid.
the class RenderSessionImpl method inflate.
/**
* Inflates the layout.
* <p>
* {@link #acquire(long)} must have been called before this.
*
* @throws IllegalStateException if the current context is different than the one owned by
* the scene, or if {@link #init(long)} was not called.
*/
public Result inflate() {
checkLock();
try {
SessionParams params = getParams();
HardwareConfig hardwareConfig = params.getHardwareConfig();
BridgeContext context = getContext();
// the view group that receives the window background.
ViewGroup backgroundView = null;
if (mWindowIsFloating || params.isForceNoDecor()) {
backgroundView = mViewRoot = mContentRoot = new FrameLayout(context);
} else {
if (hasSoftwareButtons() && mNavigationBarOrientation == LinearLayout.VERTICAL) {
/*
* This is a special case where the navigation bar is on the right.
+-------------------------------------------------+---+
| Status bar (always) | |
+-------------------------------------------------+ |
| (Layout with background drawable) | |
| +---------------------------------------------+ | |
| | Title/Action bar (optional) | | |
| +---------------------------------------------+ | |
| | Content, vertical extending | | |
| | | | |
| +---------------------------------------------+ | |
+-------------------------------------------------+---+
So we create a horizontal layout, with the nav bar on the right,
and the left part is the normal layout below without the nav bar at
the bottom
*/
LinearLayout topLayout = new LinearLayout(context);
mViewRoot = topLayout;
topLayout.setOrientation(LinearLayout.HORIZONTAL);
try {
NavigationBar navigationBar = new NavigationBar(context, hardwareConfig.getDensity(), LinearLayout.VERTICAL);
navigationBar.setLayoutParams(new LinearLayout.LayoutParams(mNavigationBarSize, LayoutParams.MATCH_PARENT));
topLayout.addView(navigationBar);
} catch (XmlPullParserException e) {
}
}
/*
* we're creating the following layout
*
+-------------------------------------------------+
| Status bar (always) |
+-------------------------------------------------+
| (Layout with background drawable) |
| +---------------------------------------------+ |
| | Title/Action bar (optional) | |
| +---------------------------------------------+ |
| | Content, vertical extending | |
| | | |
| +---------------------------------------------+ |
+-------------------------------------------------+
| Navigation bar for soft buttons, maybe see above|
+-------------------------------------------------+
*/
LinearLayout topLayout = new LinearLayout(context);
topLayout.setOrientation(LinearLayout.VERTICAL);
// if we don't already have a view root this is it
if (mViewRoot == null) {
mViewRoot = topLayout;
} else {
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
layoutParams.weight = 1;
topLayout.setLayoutParams(layoutParams);
// this is the case of soft buttons + vertical bar.
// this top layout is the first layout in the horizontal layout. see above)
mViewRoot.addView(topLayout, 0);
}
if (mStatusBarSize > 0) {
// system bar
try {
StatusBar systemBar = new StatusBar(context, hardwareConfig.getDensity());
systemBar.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, mStatusBarSize));
topLayout.addView(systemBar);
} catch (XmlPullParserException e) {
}
}
LinearLayout backgroundLayout = new LinearLayout(context);
backgroundView = backgroundLayout;
backgroundLayout.setOrientation(LinearLayout.VERTICAL);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
layoutParams.weight = 1;
backgroundLayout.setLayoutParams(layoutParams);
topLayout.addView(backgroundLayout);
// if the theme says no title/action bar, then the size will be 0
if (mActionBarSize > 0) {
try {
FakeActionBar actionBar = new FakeActionBar(context, hardwareConfig.getDensity(), params.getAppLabel(), params.getAppIcon());
actionBar.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, mActionBarSize));
backgroundLayout.addView(actionBar);
} catch (XmlPullParserException e) {
}
} else if (mTitleBarSize > 0) {
try {
TitleBar titleBar = new TitleBar(context, hardwareConfig.getDensity(), params.getAppLabel());
titleBar.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, mTitleBarSize));
backgroundLayout.addView(titleBar);
} catch (XmlPullParserException e) {
}
}
// content frame
mContentRoot = new FrameLayout(context);
layoutParams = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
layoutParams.weight = 1;
mContentRoot.setLayoutParams(layoutParams);
backgroundLayout.addView(mContentRoot);
if (mNavigationBarOrientation == LinearLayout.HORIZONTAL && mNavigationBarSize > 0) {
// system bar
try {
NavigationBar navigationBar = new NavigationBar(context, hardwareConfig.getDensity(), LinearLayout.HORIZONTAL);
navigationBar.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, mNavigationBarSize));
topLayout.addView(navigationBar);
} catch (XmlPullParserException e) {
}
}
}
// Sets the project callback (custom view loader) to the fragment delegate so that
// it can instantiate the custom Fragment.
Fragment_Delegate.setProjectCallback(params.getProjectCallback());
View view = mInflater.inflate(mBlockParser, mContentRoot);
// done with the parser, pop it.
context.popParser();
Fragment_Delegate.setProjectCallback(null);
// set the AttachInfo on the root view.
AttachInfo_Accessor.setAttachInfo(mViewRoot);
// post-inflate process. For now this supports TabHost/TabWidget
postInflateProcess(view, params.getProjectCallback());
// get the background drawable
if (mWindowBackground != null && backgroundView != null) {
Drawable d = ResourceHelper.getDrawable(mWindowBackground, context);
backgroundView.setBackground(d);
}
return SUCCESS.createResult();
} catch (PostInflateException e) {
return ERROR_INFLATION.createResult(e.getMessage(), e);
} catch (Throwable e) {
// get the real cause of the exception.
Throwable t = e;
while (t.getCause() != null) {
t = t.getCause();
}
return ERROR_INFLATION.createResult(t.getMessage(), t);
}
}
use of com.android.layoutlib.bridge.android.BridgeContext in project android_frameworks_base by ParanoidAndroid.
the class RenderSessionImpl method postInflateProcess.
/**
* Post process on a view hierachy that was just inflated.
* <p/>At the moment this only support TabHost: If {@link TabHost} is detected, look for the
* {@link TabWidget}, and the corresponding {@link FrameLayout} and make new tabs automatically
* based on the content of the {@link FrameLayout}.
* @param view the root view to process.
* @param projectCallback callback to the project.
*/
private void postInflateProcess(View view, IProjectCallback projectCallback) throws PostInflateException {
if (view instanceof TabHost) {
setupTabHost((TabHost) view, projectCallback);
} else if (view instanceof QuickContactBadge) {
QuickContactBadge badge = (QuickContactBadge) view;
badge.setImageToDefault();
} else if (view instanceof AdapterView<?>) {
// get the view ID.
int id = view.getId();
BridgeContext context = getContext();
// get a ResourceReference from the integer ID.
ResourceReference listRef = context.resolveId(id);
if (listRef != null) {
SessionParams params = getParams();
AdapterBinding binding = params.getAdapterBindings().get(listRef);
// if there was no adapter binding, trying to get it from the call back.
if (binding == null) {
binding = params.getProjectCallback().getAdapterBinding(listRef, context.getViewKey(view), view);
}
if (binding != null) {
if (view instanceof AbsListView) {
if ((binding.getFooterCount() > 0 || binding.getHeaderCount() > 0) && view instanceof ListView) {
ListView list = (ListView) view;
boolean skipCallbackParser = false;
int count = binding.getHeaderCount();
for (int i = 0; i < count; i++) {
Pair<View, Boolean> pair = context.inflateView(binding.getHeaderAt(i), list, false, /*attachToRoot*/
skipCallbackParser);
if (pair.getFirst() != null) {
list.addHeaderView(pair.getFirst());
}
skipCallbackParser |= pair.getSecond();
}
count = binding.getFooterCount();
for (int i = 0; i < count; i++) {
Pair<View, Boolean> pair = context.inflateView(binding.getFooterAt(i), list, false, /*attachToRoot*/
skipCallbackParser);
if (pair.getFirst() != null) {
list.addFooterView(pair.getFirst());
}
skipCallbackParser |= pair.getSecond();
}
}
if (view instanceof ExpandableListView) {
((ExpandableListView) view).setAdapter(new FakeExpandableAdapter(listRef, binding, params.getProjectCallback()));
} else {
((AbsListView) view).setAdapter(new FakeAdapter(listRef, binding, params.getProjectCallback()));
}
} else if (view instanceof AbsSpinner) {
((AbsSpinner) view).setAdapter(new FakeAdapter(listRef, binding, params.getProjectCallback()));
}
}
}
} else if (view instanceof ViewGroup) {
ViewGroup group = (ViewGroup) view;
final int count = group.getChildCount();
for (int c = 0; c < count; c++) {
View child = group.getChildAt(c);
postInflateProcess(child, projectCallback);
}
}
}
use of com.android.layoutlib.bridge.android.BridgeContext in project android_frameworks_base by ParanoidAndroid.
the class RenderSessionImpl method init.
/**
* Initializes and acquires the scene, creating various Android objects such as context,
* inflater, and parser.
*
* @param timeout the time to wait if another rendering is happening.
*
* @return whether the scene was prepared
*
* @see #acquire(long)
* @see #release()
*/
@Override
public Result init(long timeout) {
Result result = super.init(timeout);
if (result.isSuccess() == false) {
return result;
}
SessionParams params = getParams();
BridgeContext context = getContext();
RenderResources resources = getParams().getResources();
DisplayMetrics metrics = getContext().getMetrics();
// use default of true in case it's not found to use alpha by default
mIsAlphaChannelImage = getBooleanThemeValue(resources, "windowIsFloating", true);
mWindowIsFloating = getBooleanThemeValue(resources, "windowIsFloating", true);
findBackground(resources);
findStatusBar(resources, metrics);
findActionBar(resources, metrics);
findNavigationBar(resources, metrics);
// FIXME: find those out, and possibly add them to the render params
boolean hasSystemNavBar = true;
boolean hasNavigationBar = true;
IWindowManager iwm = new IWindowManagerImpl(getContext().getConfiguration(), metrics, Surface.ROTATION_0, hasSystemNavBar, hasNavigationBar);
WindowManagerGlobal_Delegate.setWindowManagerService(iwm);
// build the inflater and parser.
mInflater = new BridgeInflater(context, params.getProjectCallback());
context.setBridgeInflater(mInflater);
mBlockParser = new BridgeXmlBlockParser(params.getLayoutDescription(), context, false);
return SUCCESS.createResult();
}
use of com.android.layoutlib.bridge.android.BridgeContext in project android_frameworks_base by ParanoidAndroid.
the class RenderSessionImpl method animate.
/**
* Animate an object
* <p>
* {@link #acquire(long)} must have been called before this.
*
* @throws IllegalStateException if the current context is different than the one owned by
* the scene, or if {@link #acquire(long)} was not called.
*
* @see RenderSession#animate(Object, String, boolean, IAnimationListener)
*/
public Result animate(Object targetObject, String animationName, boolean isFrameworkAnimation, IAnimationListener listener) {
checkLock();
BridgeContext context = getContext();
// find the animation file.
ResourceValue animationResource = null;
int animationId = 0;
if (isFrameworkAnimation) {
animationResource = context.getRenderResources().getFrameworkResource(ResourceType.ANIMATOR, animationName);
if (animationResource != null) {
animationId = Bridge.getResourceId(ResourceType.ANIMATOR, animationName);
}
} else {
animationResource = context.getRenderResources().getProjectResource(ResourceType.ANIMATOR, animationName);
if (animationResource != null) {
animationId = context.getProjectCallback().getResourceId(ResourceType.ANIMATOR, animationName);
}
}
if (animationResource != null) {
try {
Animator anim = AnimatorInflater.loadAnimator(context, animationId);
if (anim != null) {
anim.setTarget(targetObject);
new PlayAnimationThread(anim, this, animationName, listener).start();
return SUCCESS.createResult();
}
} catch (Exception e) {
// get the real cause of the exception.
Throwable t = e;
while (t.getCause() != null) {
t = t.getCause();
}
return ERROR_UNKNOWN.createResult(t.getMessage(), t);
}
}
return ERROR_ANIM_NOT_FOUND.createResult();
}
use of com.android.layoutlib.bridge.android.BridgeContext in project android_frameworks_base by ParanoidAndroid.
the class RenderSessionImpl method insertChild.
/**
* Insert a new child into an existing parent.
* <p>
* {@link #acquire(long)} must have been called before this.
*
* @throws IllegalStateException if the current context is different than the one owned by
* the scene, or if {@link #acquire(long)} was not called.
*
* @see RenderSession#insertChild(Object, ILayoutPullParser, int, IAnimationListener)
*/
public Result insertChild(final ViewGroup parentView, ILayoutPullParser childXml, final int index, IAnimationListener listener) {
checkLock();
BridgeContext context = getContext();
// create a block parser for the XML
BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(childXml, context, false);
// inflate the child without adding it to the root since we want to control where it'll
// get added. We do pass the parentView however to ensure that the layoutParams will
// be created correctly.
final View child = mInflater.inflate(blockParser, parentView, false);
blockParser.ensurePopped();
invalidateRenderingSize();
if (listener != null) {
new AnimationThread(this, "insertChild", listener) {
@Override
public Result preAnimation() {
parentView.setLayoutTransition(new LayoutTransition());
return addView(parentView, child, index);
}
@Override
public void postAnimation() {
parentView.setLayoutTransition(null);
}
}.start();
// always return success since the real status will come through the listener.
return SUCCESS.createResult(child);
}
// add it to the parentView in the correct location
Result result = addView(parentView, child, index);
if (result.isSuccess() == false) {
return result;
}
result = render(false);
if (result.isSuccess()) {
result = result.getCopyWithData(child);
}
return result;
}
Aggregations