Android Studio

how to create custom navigation menu in android studio

In this post, I will create custom navigation menu in android studio with slide animation. So question is how I create custom navigation menu in android studio?. To create a custom navigation menu I used view pager ( build-in android studio services ) with fragments. A whole activity is divided into two fragments. One fragment is side bar menu and other is main menu. A view pager is responsible for switching between two fragments. In this post I will create two different custom navigation menu, one navigation menu will slide up 80 percent of screen and the other will slide up 100 percent of screen. Lets look to the practical example for your better understanding. 

Practical Example

Lets take example of custom navigation menu with 80 percent of screen

custom side navigation in android studio
custom side navigation in android studio

custom side navigation in android studio
custom side navigation in android studio

To create it , first add view pager to your main activity xml layout.

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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/main_content"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context=".Main2Activity">


    <android.support.v4.view.ViewPager
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />


</android.support.design.widget.CoordinatorLayout>

Then create two fragments, one for main menu and other side menu. To create a fragment you need to create first xml layouts first then create java classes for it and inherit your java class with fragment.

side_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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"
    android:background="@drawable/side_menu">

    <TextView
        android:id="@+id/t1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="SideMenu"
        android:textColor="@android:color/background_light"
        android:textSize="30sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/cross"
        android:layout_width="40dp"
        android:layout_height="50dp"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:layout_marginRight="16dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/cross"
        tools:ignore="VectorDrawableCompat" />
</android.support.constraint.ConstraintLayout>

main_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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"
    android:background="@drawable/main_menu">

    <TextView
        android:id="@+id/t2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="@font/autumn"
        android:text="Main Menu"
        android:textAllCaps="true"
        android:textColor="@android:color/background_light"
        android:textSize="30sp"
        android:textStyle="italic"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/side"
        android:layout_width="50dp"
        android:layout_height="45dp"
        android:layout_marginStart="16dp"
        android:layout_marginLeft="16dp"
        android:layout_marginTop="16dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@drawable/sidebar"
        tools:ignore="VectorDrawableCompat" />
</android.support.constraint.ConstraintLayout>

Now create a adapter called as myadapter class, this will handle both fragments using view pager. Then we need a communication between fragment and activity. In order to implement a communication we need create a interface, in my case, the interface I have is called as ‘ frag1_to_activity ‘. In the interface, there are two methods to implements, one is communicate1 and other is communicate2. Communicate1 method is used for main menu and communicate2 is used for side menu. The method is implemented in main activity.

public interface frag1_to_activity {
    void communicate1();
    void communicate2();
}
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

public class side_menu extends Fragment implements View.OnClickListener {

    private frag1_to_activity mCallback;
    TextView t1;
    ImageView cross;
    public side_menu() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.side_menu, container, false);
        t1 = (TextView) view.findViewById(R.id.t1);
        t1.setOnClickListener(this);
        cross = view.findViewById(R.id.cross);
        cross.setOnClickListener(this);
        return  view;
    }



    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        try{
            mCallback = (frag1_to_activity) context;
        }
        catch (ClassCastException e){

            throw new ClassCastException(context.toString()+ " must implement frag1_to_activity ");
        }
    }


    @Override
    public void onDetach() {
        mCallback = null;
        super.onDetach();
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()){

            case R.id.cross :
                mCallback.communicate2();
                break;

        }

    }

}
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

public class main_menu extends Fragment implements View.OnClickListener {


    private frag1_to_activity mCallback;
    TextView t1;
    ImageView side;

    public main_menu() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View view = inflater.inflate(R.layout.main_menu, container, false);
        t1 = view.findViewById(R.id.t2);
        t1.setOnClickListener(this);
        side = view.findViewById(R.id.side);
        side.setOnClickListener(this);
        return view;
    }


    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        try{
            mCallback = (frag1_to_activity) context;
        }
        catch (ClassCastException e){

            throw new ClassCastException(context.toString()+ " must implement frag1_to_activity ");
        }
    }


    @Override
    public void onDetach() {
        mCallback = null;
        super.onDetach();
    }

    @Override
    public void onClick(View v) {

        switch (v.getId()){

            case R.id.side :
            mCallback.communicate1();
            break;

        }

    }
}
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public class MyAdapter extends FragmentPagerAdapter {

    private Context myContext;
    int totalTabs;

    public MyAdapter(Context context, FragmentManager fm, int totalTabs) {
        super(fm);
        myContext = context;
        this.totalTabs = totalTabs;
    }

    // this is for fragment tabs
    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                side_menu side = new side_menu();
                return side;
            case 1:
                main_menu main_menu_Fragment = new main_menu();
                return main_menu_Fragment;
            default:
                return null;
        }
    }
    // this counts total number of tabs
    @Override
    public int getCount() {
        return totalTabs;
    }

    @Override
    public float getPageWidth(int position) {

        if(position ==0){
         //   return 0.8f;
            //
            return super.getPageWidth(position);

        }
        else{
            return super.getPageWidth(position);
        }

    }
}
import android.support.design.widget.TabLayout;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements frag1_to_activity {

    private ViewPager mViewPager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
         // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
       // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.container);
      //  mViewPager.setAdapter(mSectionsPagerAdapter);
       final MyAdapter adapter = new MyAdapter(this,getSupportFragmentManager(), 2);
        mViewPager.setAdapter(adapter);
        mViewPager.setCurrentItem(1);

    }

    @Override
    public void communicate1() {
        mViewPager.setCurrentItem(0);
    }

    @Override
    public void communicate2() {
      mViewPager.setCurrentItem(1);
    }
}

Last and important thing, you must know how to show or set  screen percentage for side menu. The answer is through overriding “getPagewidth” function. If you return 0.8 then 80 percent of screen will be covered with side menu and if you return 1 (default) it will cover 100 percent of screen with side menu

Leave a Reply

Your email address will not be published. Required fields are marked *