-
Notifications
You must be signed in to change notification settings - Fork 24
Android_Menu and Navigation
I'm getting to a point where I want to continue extending my application by adding new screens to it (e.g. - My Profile and Settings). However, before I start with that, I need to establish a way to navigate through those screens via the navigation drawer I already have implemented. So, this page will describe how I implemented this.
Before I start implementing the navigation, I need a place where my new screens will appear when I click on the navigation drawer options. When I generated the project with the Navigation Drawer Activity template, it generated an xml file for me called content_navigation.xml. This view represents the main part of the screen layout for the NavigationActivity
. It is highlighted in red in the image below, but keep in mind that it doesn't include the Floating Action Button
, that is actually a part of another layout, that includes the content_navigation.xml layout.
Initially, the content_navigation.xml contains a TextView
with a Hellow World!
text. I'm going to delete this view and instead add the FrameLayout
:
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
></FrameLayout>
This FrameLayout
is where my new screen layouts (e.g. - My Profile, Settings, etc) will appear (load into) when a user clicks on the Navigation Drawer option.
As per Android documentation:
FrameLayout
is designed to block out an area on the screen to display a single item. Generally, FrameLayout should be used to hold a single child view.
Child views are drawn in a stack, with the most recently added child on top. The size of the FrameLayout
is the size of its largest child (plus padding), visible or not (if the FrameLayout's parent permits).
We are now going to create a layout and a controller for the two new "screens" that are going to appear when the user clicks on the Navigation Drawer options. I'll walk you to creation of one of those screens, as the second one is completely the same, just with different names.
So, firstly, I'm going to create a layout part called profile_layout.xml inside the res/layout folder:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="My Profile Page" />
</LinearLayout>
Next, I'll create a controller for this layout. Usually this would be a new Activity
, but in this case it will be a Fragment
, since we are loading this into the FrameLayout
instead of inflating the whole new Activity
.
public class ProfileFragment extends Fragment{
View myView;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
myView = inflater.inflate(R.layout.profile_layout, container, false);
return myView;
}
}
As per Android documentation:
A Fragment
represents a behavior or a portion of user interface in an Activity
. You can combine multiple fragments in a single activity to build a multi-pane UI and reuse a fragment in multiple activities. You can think of a fragment as a modular section of an activity, which has its own lifecycle, receives its own input events, and which you can add or remove while the activity is running (sort of like a "sub activity" that you can reuse in different activities).
Interaction with fragments is done through FragmentManager
, which can be obtained via Activity.getFragmentManager()
and Fragment.getFragmentManager()
.
Now I need to remove the unnecessary menu options that were generated with the project, and define the appropriate IDs
so I can handle the navigation correctly. The menu options are defined inside the res/menu/activity_navigation_drawer.xml file. I'm going to remove all of the options and change the code to the one below:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group
android:id="@+id/menu_top"
android:checkableBehavior="single">
<item
android:checked="true"
android:id="@+id/nav_my_profile"
android:icon="@drawable/ic_menu_camera"
android:title="My Profile" />
</group>
<group
android:id="@+id/menu_bottom"
android:checkableBehavior="single">
<item
android:id="@+id/nav_settings"
android:icon="@drawable/ic_menu_manage"
android:title="Settings" />
<item
android:id="@+id/nav_send_feedback"
android:icon="@drawable/ic_menu_send"
android:title="Send Feedback" />
</group>
</menu>
Over time I'll add more options, but for now the ones I have will be enough.
Also, a useful thing to know is that by default, these group
elements don't have an id
assigned to them. But if you want to have a separator in the UI between different groups (sections) of your menu options, you need to add those id
fields and make them unique between all of the group
elements. You'll see the separator I'm talking about below in the screenshot between the first, and the last two buttons.
Finally, we need to implement the navigation logic.
We'll do this in NavigationActivity
by firstly importing the android.app.FragmentManager
package. Next, we'll define a class wide variable FragmentManager fragmentManager
at the start of the class definition, so we can access it from anywhere within our activity.
There is already a generated method onNavigationItemSelected
that is called whenever a user clicks on the Navigation Item (Menu Item), but the navigation logic wasn't implemented, so we are going to add it now, and remove the extra if
statements that we aren't going to use:
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_my_profile) {
fragmentManager.beginTransaction()
.replace(R.id.content_frame, new ProfileFragment())
.commit();
} else if (id == R.id.nav_settings) {
fragmentManager.beginTransaction()
.replace(R.id.content_frame, new SettingsFragment())
.commit();
} else if (id == R.id.nav_send_feedback) {
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
So, whenever a user clicks on the My Profile menu option, the MenuItem
will have an id
of value nav_my_profile
and the corresponding if
statement logic will be triggered. Same goes for Settings MenuItem
. The logic within those if
statements replaces the content of the FrameLayout
we defined in the content_navigation.xml file with one of the fragments, using the fragmentManager
object.
Finally, we need to make the "My Profile" view (fragment) as the default one when the user opens the application, before he even selects any of the options in the Navigation Drawer. We are going to do that by adding the code below at the end of the onCreate
method in NavigationActivity
.
//instantiate the fragmentManager and set the default view to profile
fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame ,new ProfileFragment())
.commit();
You can see the full source code of the NavigationActivity
class here
In the image below you can see the end results. There are the 3 menu options we defined, and the separator between the first and second option, which are contained in different groups
.
Implementing this navigation was pretty straightforward was I found the correct documentation and knew what to change.
- Android
- Getting Started
- Project Structure
- Gradle
- Menu
- Theming
- Login Screen
- Menu & Navigation
- Importing Library From GitHub
- Creating Reusable Layouts
- Adding New Icons
- Profile Screen
- Chat Screen
- Contacts Screen
- Pending Invites Screen
- Settings Screen
- Add Library Dependency
- Discover Users Screen
- Splash Screen
- Auth0
- Authentication Logic
- Profile Screen Logic
- Send Feedback
- Authenticated to Firebase via Auth0
- Saving User Info to Firebase
- Storing User Connection Info to Firebase
- Calculating Distance Between Users
- Chat Logic
- Handling Device Rotation
- Android Other
- Ionic
- Getting Started
- Project Structure
- Menu
- Theming
- Login Screen
- Adding Images
- Creating Reusable Layouts
- Adding New Icons
- Profile Screen
- Contact Screen
- Elastic Textarea
- Chat Bubble
- Chat Screen
- Contacts Screen
- Pending Invites Screen
- Settings Screen
- Discover Users Screen
- Splash Screen
- Animations
- Auth0
- Storing User Data
- Profile Screen Logic
- Send Feedback
- Update to Ionic RC0
- Reimplemented Auth0 with Ionic RC0
- Authenticated to Firebase via Auth0
- Saving User Info to Firebase
- Storing User Connection Info to Firebase
- Calculating Distance Between Users
- Chat Logic
- Handling Device Rotation
- Ionic Other
- Version Updating
- Cordova
- Other
- Messaging