通过编辑AOSP来支持Android导航栏 [英] Android Navigation Bar on side by editing AOSP

查看:72
本文介绍了通过编辑AOSP来支持Android导航栏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想通过编辑AOSP将导航栏(具有系统软键,如后退,主菜单和菜单,而不是导航抽屉!)放在(右)侧,如下所示.

I want to put the Navigation Bar (has system soft keys like back, home and menu. not Navigation Drawer!) on the (right) side, like below, by editing AOSP.

+-------------------------------------------------+---+
| Status bar (always)                             |   |
+-------------------------------------------------+ N |
| (Layout with background drawable)               | a |
| +---------------------------------------------+ | v |
| | Title/Action bar (optional)                 | |   |
| +---------------------------------------------+ | B |
| | Content, vertical extending                 | | a |
| |                                             | | r |
| +---------------------------------------------+ |   |
+-------------------------------------------------+---+

到目前为止,我假设

So far I assume RenderSessionImpl.java is the file to edit to accomplish this since it renders the screen layout depends on the given screen orientation value.

我找到了下一个代码片段,并编辑了方向参数(HORIZONTAL-> VERTICAL),这样就可以创建水平布局,并且导航栏位于右侧.

I found the next snippet and edited the orientation parameter(HORIZONTAL -> VERTICAL) so it would creates a horizontal layout, with the nav bar on the right.

if (mNavigationBarOrientation == LinearLayout.HORIZONTAL &&
        mNavigationBarSize > 0) {
    // system bar
    try {
        NavigationBar navigationBar = new NavigationBar(context,
                hardwareConfig.getDensity(), LinearLayout.VERTICAL); // was LinearLayout.HORIZONTAL originallly
        navigationBar.setLayoutParams(
                new LinearLayout.LayoutParams(
                        LayoutParams.MATCH_PARENT, mNavigationBarSize));
        topLayout.addView(navigationBar);
    } catch (XmlPullParserException e) {

    }
}

原始的AOSP代码段如下.

Original AOSP code snippets are below.

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

但是屏幕布局没有区别.有什么见解吗?错误的文件编辑或错误的逻辑? 我知道不建议进行这种调整,但我确实需要这样做.

But the screen layout shows no difference. Any insight for this? Wrong file to edit or wrong logic? I know this kind of tweak is not recommended but I really need to do it.

推荐答案

通过编辑在PhoneWindowManager中将mNavigationBarOnBottom设置为false,然后将运行以下代码.

Set mNavigationBarOnBottom to false in PhoneWindowManager then the following code will run.

// PhoneWindowManager.java
// if mNavigationBarOnBottom = false
// Landscape screen; nav bar goes to the right
int left = displayWidth - mNavigationBarWidthForRotation[displayRotation];
mTmpNavigationFrame.set(left, 0, displayWidth, displayHeight);
mStableRight = mStableFullscreenRight = mTmpNavigationFrame.left;
if (navVisible) {
    mNavigationBar.showLw(true);
    mDockRight = mTmpNavigationFrame.left;
    mRestrictedScreenWidth = mDockRight - mDockLeft;
} else {
    // We currently want to hide the navigation UI.
    mNavigationBar.hideLw(true);
}
if (navVisible && !mNavigationBar.isAnimatingLw()) {
    // If the nav bar is currently requested to be visible,
    // and not in the process of animating on or off, then
    // we can tell the app that it is covered by it.
    mSystemRight = mTmpNavigationFrame.left;
}

这将在右侧而不是底部创建导航栏框架,现在需要编辑布局以垂直显示系统按钮(navigation_bar.xml).

This creates the frame for navigation bar on right instead of bottom, now layout needs to be edited to display system buttons vertically(navigation_bar.xml).

<!--  navigation bar for sw600dp (small tablets) -->
<com.android.systemui.statusbar.phone.NavigationBarView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    android:background="#FF000000"
    >    
    <FrameLayout android:id="@+id/rot0"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        >    
        <LinearLayout
            android:layout_height="match_parent"
            android:layout_width="match_parent"
            android:orientation="vertical"
            android:clipChildren="false"
            android:clipToPadding="false"
            android:id="@+id/nav_buttons"
            android:animateLayoutChanges="true"
            >    
            <!-- navigation controls -->
            ~
            <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
                android:layout_width="match_parent"
                android:layout_height="128dp"
                android:src="@drawable/ic_sysbar_back"
                systemui:keyCode="4"
                android:layout_weight="0"
                systemui:glowBackground="@drawable/ic_sysbar_highlight"
                android:contentDescription="@string/accessibility_back"
                />
            ~
        </LinearLayout>
    </FrameLayout>
</com.android.systemui.statusbar.phone.NavigationBarView>

这篇关于通过编辑AOSP来支持Android导航栏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆