androidxmlmaterial-designfloating-action-buttonandroid-bottomappbar

BottomAppBar 4 Icons not align properly


how can I align the icons properly as it?

This is my activity main xml with bottom app bar and floating action button.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".activities.MainActivity">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <FrameLayout
            android:id="@+id/fragmentview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <com.google.android.material.bottomappbar.BottomAppBar
            android:id="@+id/bottom_app_bar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom"
            app:backgroundTint="@color/bluPrincipale"
            app:fabAlignmentMode="center"/>


        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/fab"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/ic_icona_menu_mappa"
            app:layout_anchor="@id/bottom_app_bar" />

    </androidx.coordinatorlayout.widget.CoordinatorLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

This is my activity main that make work for fragments I think.

MainActivity.java

package com.example.test.activities;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;

import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;

import com.example.test.R;
import com.example.test.fragments.ConvenzioniFragment;
import com.example.test.fragments.DoveAndareFragment;
import com.example.test.fragments.HomeFragment;
import com.example.test.fragments.MappaFragment;
import com.example.test.fragments.MoreFragment;
import com.google.android.material.bottomappbar.BottomAppBar;
import com.google.android.material.floatingactionbutton.FloatingActionButton;

public class MainActivity extends AppCompatActivity {

    private FloatingActionButton floatingActionButton;
    private BottomAppBar bottomAppBar;
    private boolean isFabTabbed = false;


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

        floatingActionButton = findViewById(R.id.fab);
        bottomAppBar = findViewById(R.id.bottom_app_bar);

        setSupportActionBar(bottomAppBar);

        if(savedInstanceState == null) {
            handleFrame(new HomeFragment());
        }

        handleFab();
    }

    private void handleFab() {
        floatingActionButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                isFabTabbed = !isFabTabbed;
                if(isFabTabbed) {
                    handleFrame(new MappaFragment());
                }
                else
                {
                    handleFrame(new HomeFragment());
                }
            }
        });
    }

    private void handleFrame(Fragment fragment) {
        FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
        fragmentTransaction.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
        fragmentTransaction.replace(R.id.fragmentview, fragment);
        fragmentTransaction.commit();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.bottomappbar_menu, menu);
        return true;
    }

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

        switch(item.getItemId()) {
            case R.id.app_bar_home:
                handleFrame(new HomeFragment());
                return true;
            case R.id.app_bar_dove_andare_sagre_eventi:
                handleFrame(new DoveAndareFragment());
                return true;
            case R.id.app_bar_convenzioni:
                handleFrame(new ConvenzioniFragment());
                return true;
            case R.id.app_bar_more:
                handleFrame(new MoreFragment());
                return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

This is my custom bottom app bar menu.

bottomappbar_menu.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/app_bar_home"
        android:icon="@drawable/ic_icona_menu_home"
        android:title="Home"
        app:showAsAction="always"
       />

    <item
        android:id="@+id/app_bar_dove_andare_sagre_eventi"
        android:icon="@drawable/ic_icona_menu_dove_andare_sagre_eventi"
        android:title="Dove Andare"
        app:showAsAction="always"

       />
    <item
        android:id="@+id/app_bar_convenzioni"
        android:icon="@drawable/ic_icona_menu_convenzioni"
        android:title="Convenzioni"
        app:showAsAction="always"
        />

    <item
        android:id="@+id/app_bar_more"
        android:icon="@drawable/ic_icona_menu_more"
        android:title="More"
        app:showAsAction="always"
       />


</menu>

This is my gradle code. It's correct for me.

Gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId "com.example.test"
        minSdkVersion 16
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'com.google.android.material:material:1.1.0-beta01'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}

But the bottom bar result not is as this:

picture correct

It's mine result :|

mineresult

I'm using latest material design.

Thanks for any helps! Cris


Solution

  • Remove menu from BottomAppBar and add it in BottomNavigationView then add BottomNavigationView inside BottomAppBar, like this:

    <androidx.coordinatorlayout.widget.CoordinatorLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <FrameLayout
                android:id="@+id/fragmentview"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />
    
            <com.google.android.material.bottomappbar.BottomAppBar
                android:id="@+id/bottom_app_bar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="bottom"
                app:fabAlignmentMode="center">
            <com.google.android.material.bottomnavigation.BottomNavigationView
                android:id="@+id/bottomNavigationView"
                style="@style/MyBottomNavigationView"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:itemIconTint="@color/selector_bottom_navigation"
                app:itemTextColor="@color/selector_bottom_navigation"
                app:labelVisibilityMode="labeled"
                app:menu="@menu/activity_home_bottom_nav" />
            </com.google.android.material.bottomappbar.BottomAppBar>
    
            <com.google.android.material.floatingactionbutton.FloatingActionButton
                android:id="@+id/fab"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@drawable/ic__right_arrow"
                app:layout_anchor="@id/bottom_app_bar" />
    
        </androidx.coordinatorlayout.widget.CoordinatorLayout>
    

    If you do this, your items will appear in centre according to your expectation, but you may experience that icon of 2nd and 3rd item overlapped by FAB, to refrain from this situation, add an empty item in centre of your menu, like this:

    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <item
            android:id="@+id/itemRenewals"
            android:icon="@drawable/menu_renewals"
            android:title="Renewals" />
    
        <item
            android:id="@+id/itemViewOwner"
            android:icon="@drawable/menu_view_owner"
            android:title="View User" />
    
        <item
            android:id="@+id/itemEmpty"
            android:title=""/>
    
        <item
            android:id="@+id/itemEnquiry"
            android:icon="@drawable/menu_enquiry"
            android:title="Enquiry" />
    
        <item
            android:id="@+id/itemProfile"
            android:icon="@drawable/menu_profile"
            android:title="Profile" />
    </menu>