Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Navigation Bar on side by editing 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.

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) {

    }
}

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.

like image 630
HUKS Avatar asked Nov 18 '14 03:11

HUKS


People also ask

Can you customize navigation bar?

Button order From Settings, tap Display, and then tap Navigation bar. Make sure Buttons is selected, and then you can choose your desired button setup at the bottom of the screen.

How do I hide the navigation bar while playing a game?

Touch “Settings” -> “Display” -> “Navigation bar” -> “Buttons” -> “Button layout”. Choose the pattern in “Hide navigation bar” -> When the app opens, the navigation bar will be automatically hidden and you can swipe up from the bottom corner of the screen to show it.

How do I invert navbar?

Complete HTML/CSS Course 2022 To create an inverted navbar with a black background and with white text, simply add the . navbar-inverse class to the . navbar class.


1 Answers

Navigation Bar can be placed on right side by editing PhoneWindowManager.java and navigation_bar.xml.

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;
}

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>
like image 192
HUKS Avatar answered Sep 22 '22 23:09

HUKS