Zafar Kurbonov
Zafar Kurbonov

Reputation: 2077

How to make a fixed BottomNavigationView with title below, no shifted navigation

I am having difficulties in making fixed BottomNavigationView like in the Photo below: OriginalPhoto.png

Here is my own project's BottomNavigationView: MyPhoto.png

Also, I want the title below icons visible all the time, not just when clicked. How can I do this??

Note: I have read all stackoverflow articles and followed other external links but no tangible results have gained. Please help me to figure this subtle problem out. Would be better if only with XML to solve this problem, rather than java code.

Here is my source code for activity_menu.xml, btw, it is not activity_main.xml because i have used main activity for my login page. This activity is after login page: `

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="datasite.com.konnex.Menu"
    android:background="#ffffff">

    <android.support.v7.widget.Toolbar
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#3fc0ea">

        <ImageButton
            android:layout_width="120dp"
            android:layout_height="38dp"
            android:background="@drawable/lg1"
            android:layout_marginLeft="130dp"
            android:layout_marginStart="130dp"/>

        <android.support.v7.widget.SearchView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="90dp"
            android:layout_marginStart="90dp"/>
    </android.support.v7.widget.Toolbar>

    <RelativeLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
      <GridLayout
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:columnCount="2">
          <FrameLayout
              android:layout_width="191dp"
              android:layout_height="150dp"
              android:id="@+id/fm_cases"
              android:clickable="true"
              android:focusable="true"
              android:foreground="?attr/selectableItemBackground">
              <ImageView
                  android:layout_width="90dp"
                  android:layout_height="90dp"
                  android:src="@drawable/cases"
                  android:layout_marginLeft="50dp"
                  android:layout_marginStart="50dp"
                  android:layout_marginTop="35dp"
                  android:id="@+id/img_cases" />
              <TextView
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:text="@string/cases"
                  android:layout_marginLeft="70dp"
                  android:layout_marginStart="70dp"
                  android:layout_marginTop="128dp"
                  android:textSize="18sp"
                  android:textColor="#424242"/>
              <TextView
                  android:layout_width="22dp"
                  android:layout_height="wrap_content"
                  android:text="@string/string_1"
                  android:textColor="#FFFFFF"
                  android:textSize="17sp"
                  android:layout_marginLeft="122dp"
                  android:layout_marginStart="122dp"
                  android:layout_marginTop="35dp"
                  android:background="#E91E63"
                  android:id="@+id/notif_cases"/>
          </FrameLayout>

      </GridLayout>

    </RelativeLayout>

    <android.support.design.widget.BottomNavigationView
        android:id="@+id/navigation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#fffafa"
        app:menu="@menu/navigation"
        app:itemIconTint="@color/dark"
        app:itemTextColor="@color/dark"
        android:animateLayoutChanges="false"
        android:splitMotionEvents="false"
        android:fitsSystemWindows="true"/>

</LinearLayout>`

Here is the source code for menu.java. it is also after main.java activity which is for login used.

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v4.widget.TextViewCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;

public class Menu extends AppCompatActivity {

    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
            = new BottomNavigationView.OnNavigationItemSelectedListener() {

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {

            switch (item.getItemId()) {
                case R.id.nav_about:
                    return true;
                case R.id.nav_location:
                    return true;
                case R.id.nav_phone:
                    return true;
                case R.id.nav_home:
                    return true;
            }
            return false;
        }
    };

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_menu);

            FrameLayout fml = (FrameLayout) findViewById(R.id.fm_cases);
            fml.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Intent i = new Intent(Menu.this, Cases.class);
                    startActivity(i);

                }
            });
    }
}

Thank you in advance!!! I really need your help Guys)

My Navigation.xml:

`<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">


    <item
        android:id="@+id/nav_about"
        android:icon="@drawable/ic_dashboard_black_24dp"
        android:title="@string/title_about" />
    <item
        android:id="@+id/nav_location"
        android:icon="@drawable/nav_location"
        android:title="@string/title_location"
        />

    <item
        android:id="@+id/nav_phone"
        android:icon="@drawable/nav_call"
        android:title="@string/title_phone"
         />

    <item
        android:id="@+id/nav_home"
        android:icon="@drawable/ic_home_black_24dp"
        android:title="@string/title_home"
        />

</menu>

Upvotes: 0

Views: 1651

Answers (2)

Aalap Patel
Aalap Patel

Reputation: 2076

Try using AHBottomNavigation library, I suggest this because is has simple implementation considering your case and reduces your work to create another menu.xml file and handling menu option methods in your code. Just add this line in your gradle file.

compile 'com.aurelhubert:ahbottomnavigation:2.0.6'

It will take care of the layout issue you have moreover, it has lots of customization options. You can read further here, but for your case the simple use to keep titles is..

public class MyActivity extends AppCompatActivity{
     @BindView(R.id.bottom_navigationbar)
     AHBottomNavigation bottomNavigation;

   onCreate(){

    bottomNavigation.addItem(new AHBottomNavigationItem("Title1", iconID1);
    bottomNavigation.addItem(new AHBottomNavigationItem("Title2", iconID2);
    bottomNavigation.addItem(new AHBottomNavigationItem("Title3", iconID3);
    bottomNavigation.addItem(new AHBottomNavigationItem("Title4", iconID4);

    bottomNavigation.setAccentColor(ContextCompat.getColor(this, themeColor));

    //will always show titles
    bottomNavigation.setTitleState(AHBottomNavigation.TitleState.ALWAYS_SHOW); 
}}

setUpClickListener.

    bottomNavigation.setOnTabSelectedListener((position, wasSelected) -> {


                if (position == 0 && !wasSelected) {

                } else if (position == 1 && !wasSelected) {

                } else if (position == 2 && !wasSelected) {

                } else if (position == 3 && !wasSelected) {

                } else if (position == 4 && !wasSelected) {

                }
                return true;
            }
    );

Upvotes: 1

Mohit Suthar
Mohit Suthar

Reputation: 9395

Ok then try to add app:showAsAction in menu item

 <?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/nav_about"
        android:icon="@drawable/ic_dashboard_black_24dp"
        app:showAsAction="ifRoom"
        android:title="@string/title_about" />
    <item
        android:id="@+id/nav_location"
        android:icon="@drawable/nav_location"
        app:showAsAction="ifRoom"
        android:title="@string/title_location"
        />

    <item
        android:id="@+id/nav_phone"
        android:icon="@drawable/nav_call"
        app:showAsAction="ifRoom"
        android:title="@string/title_phone"
         />

    <item
        android:id="@+id/nav_home"
        android:icon="@drawable/ic_home_black_24dp"
        app:showAsAction="ifRoom"
        android:title="@string/title_home"
        />

</menu>

If your problem not resolve then replace this one showAsAction="always|withText"

after then you can use this method for disabling shifted menu

 public static void disableShiftMode(BottomNavigationView view) {
    BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
    try {
        Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
        shiftingMode.setAccessible(true);
        shiftingMode.setBoolean(menuView, false);
        shiftingMode.setAccessible(false);
        for (int i = 0; i < menuView.getChildCount(); i++) {
            BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
            //noinspection RestrictedApi
            item.setShiftingMode(false);
            // set once again checked value, so view will be updated
            //noinspection RestrictedApi
            item.setChecked(item.getItemData().isChecked());
        }
    } catch (NoSuchFieldException e) {
        Log.e("BNVHelper", "Unable to get shift mode field", e);
    } catch (IllegalAccessException e) {
        Log.e("BNVHelper", "Unable to change value of shift mode", e);
    }
}

Updated Menu.java: `package datasite.com.konnex;

    import android.content.Context;
    import android.content.Intent;
    import android.os.Bundle;
    import android.support.annotation.NonNull;
    import android.support.design.internal.BottomNavigationItemView;
    import android.support.design.internal.BottomNavigationMenuView;
    import android.support.design.widget.BottomNavigationView;
    import android.support.v4.widget.TextViewCompat;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.GridLayoutManager;
    import android.support.v7.widget.LinearLayoutManager;
    import android.support.v7.widget.RecyclerView;
    import android.util.Log;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.FrameLayout;
    import android.widget.ImageView;
    import android.widget.TextView;

    import java.lang.reflect.Field;

    public class Menu extends AppCompatActivity {

        private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
                = new BottomNavigationView.OnNavigationItemSelectedListener() {

            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {

                switch (item.getItemId()) {
                    case R.id.nav_about:
                        return true;
                    case R.id.nav_location:
                        return true;
                    case R.id.nav_phone:
                        return true;
                    case R.id.nav_home:
                        return true;
                }
                return false;
            }
        };

            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_menu);

//Add This           
disableShiftMode((BottomNavigationView)findViewById(R.id.navigation))

                FrameLayout fml = (FrameLayout) findViewById(R.id.fm_cases);
                fml.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        Intent i = new Intent(Menu.this, Cases.class);
                        startActivity(i);
                    }
                });
            }

                public static void disableShiftMode(BottomNavigationView view) {
                    BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
                    try {
                        Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
                        shiftingMode.setAccessible(true);
                        shiftingMode.setBoolean(menuView, false);
                        shiftingMode.setAccessible(false);
                        for (int i = 0; i < menuView.getChildCount(); i++) {
                            BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
                            //noinspection RestrictedApi
                            item.setShiftingMode(false);
                            // set once again checked value, so view will be updated
                            //noinspection RestrictedApi
                            item.setChecked(item.getItemData().isChecked());
                        }
                    } catch (NoSuchFieldException e) {
                        Log.e("BNVHelper", "Unable to get shift mode field", e);
                    } catch (IllegalAccessException e) {
                        Log.e("BNVHelper", "Unable to change value of shift mode", e);
                    }
                }
        }

Updated Navigation.xml:

`<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">


    <item
        android:id="@+id/nav_about"
        android:icon="@drawable/ic_dashboard_black_24dp"
        android:title="@string/title_about"
        app:showAsAction="always|withText"/>
    <item
        android:id="@+id/nav_location"
        android:icon="@drawable/nav_location"
        android:title="@string/title_location"
        app:showAsAction="always|withText" />

    <item
        android:id="@+id/nav_phone"
        android:icon="@drawable/nav_call"
        android:title="@string/title_phone"
        app:showAsAction="always|withText"/>

    <item
        android:id="@+id/nav_home"
        android:icon="@drawable/ic_home_black_24dp"
        android:title="@string/title_home"
        app:showAsAction="always|withText" />

</menu>
`

Upvotes: 1

Related Questions