Search in sources :

Example 1 with BridgeContext

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);
    }
}
Also used : SessionParams(com.android.ide.common.rendering.api.SessionParams) HardwareConfig(com.android.ide.common.rendering.api.HardwareConfig) MarginLayoutParams(android.view.ViewGroup.MarginLayoutParams) LayoutParams(android.view.ViewGroup.LayoutParams) ViewGroup(android.view.ViewGroup) Drawable(android.graphics.drawable.Drawable) BridgeContext(com.android.layoutlib.bridge.android.BridgeContext) StatusBar(com.android.layoutlib.bridge.bars.StatusBar) View(android.view.View) AdapterView(android.widget.AdapterView) ListView(android.widget.ListView) AbsListView(android.widget.AbsListView) ExpandableListView(android.widget.ExpandableListView) NavigationBar(com.android.layoutlib.bridge.bars.NavigationBar) FrameLayout(android.widget.FrameLayout) XmlPullParserException(org.xmlpull.v1.XmlPullParserException) LinearLayout(android.widget.LinearLayout) FakeActionBar(com.android.layoutlib.bridge.bars.FakeActionBar) TitleBar(com.android.layoutlib.bridge.bars.TitleBar)

Example 2 with BridgeContext

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);
        }
    }
}
Also used : SessionParams(com.android.ide.common.rendering.api.SessionParams) TabHost(android.widget.TabHost) ViewGroup(android.view.ViewGroup) BridgeContext(com.android.layoutlib.bridge.android.BridgeContext) AbsListView(android.widget.AbsListView) FakeAdapter(com.android.layoutlib.bridge.impl.binding.FakeAdapter) FakeExpandableAdapter(com.android.layoutlib.bridge.impl.binding.FakeExpandableAdapter) View(android.view.View) AdapterView(android.widget.AdapterView) ListView(android.widget.ListView) AbsListView(android.widget.AbsListView) ExpandableListView(android.widget.ExpandableListView) ListView(android.widget.ListView) AbsListView(android.widget.AbsListView) ExpandableListView(android.widget.ExpandableListView) QuickContactBadge(android.widget.QuickContactBadge) AdapterBinding(com.android.ide.common.rendering.api.AdapterBinding) AbsSpinner(android.widget.AbsSpinner) AdapterView(android.widget.AdapterView) ResourceReference(com.android.ide.common.rendering.api.ResourceReference) ExpandableListView(android.widget.ExpandableListView)

Example 3 with BridgeContext

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();
}
Also used : SessionParams(com.android.ide.common.rendering.api.SessionParams) BridgeInflater(android.view.BridgeInflater) IWindowManager(android.view.IWindowManager) IWindowManagerImpl(android.view.IWindowManagerImpl) RenderResources(com.android.ide.common.rendering.api.RenderResources) BridgeContext(com.android.layoutlib.bridge.android.BridgeContext) DisplayMetrics(android.util.DisplayMetrics) BridgeXmlBlockParser(com.android.layoutlib.bridge.android.BridgeXmlBlockParser) Result(com.android.ide.common.rendering.api.Result)

Example 4 with BridgeContext

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();
}
Also used : Animator(android.animation.Animator) ResourceValue(com.android.ide.common.rendering.api.ResourceValue) BridgeContext(com.android.layoutlib.bridge.android.BridgeContext) XmlPullParserException(org.xmlpull.v1.XmlPullParserException)

Example 5 with BridgeContext

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;
}
Also used : AnimationThread(android.animation.AnimationThread) BridgeContext(com.android.layoutlib.bridge.android.BridgeContext) LayoutTransition(android.animation.LayoutTransition) View(android.view.View) AdapterView(android.widget.AdapterView) ListView(android.widget.ListView) AbsListView(android.widget.AbsListView) ExpandableListView(android.widget.ExpandableListView) BridgeXmlBlockParser(com.android.layoutlib.bridge.android.BridgeXmlBlockParser) Result(com.android.ide.common.rendering.api.Result)

Aggregations

BridgeContext (com.android.layoutlib.bridge.android.BridgeContext)112 ResourceValue (com.android.ide.common.rendering.api.ResourceValue)40 Context (android.content.Context)31 View (android.view.View)24 AdapterView (android.widget.AdapterView)24 RenderResources (com.android.ide.common.rendering.api.RenderResources)24 BridgeXmlBlockParser (com.android.layoutlib.bridge.android.BridgeXmlBlockParser)24 SessionParams (com.android.ide.common.rendering.api.SessionParams)23 ActionMenuItemView (com.android.internal.view.menu.ActionMenuItemView)20 IconMenuItemView (com.android.internal.view.menu.IconMenuItemView)20 ListMenuItemView (com.android.internal.view.menu.ListMenuItemView)20 AbsListView (android.widget.AbsListView)18 ExpandableListView (android.widget.ExpandableListView)18 ListView (android.widget.ListView)18 Result (com.android.ide.common.rendering.api.Result)18 StyleResourceValue (com.android.ide.common.rendering.api.StyleResourceValue)17 LayoutlibDelegate (com.android.tools.layoutlib.annotations.LayoutlibDelegate)16 ActionMenuView (android.widget.ActionMenuView)15 MenuView (com.android.internal.view.menu.MenuView)15 Drawable (android.graphics.drawable.Drawable)13