Android Studio navigation drawer like Gmail app - java

We're making an android app, and there is something we want to add.
Which is the effect the Gmail app has.
You can choose which account you want to view (and the rest of the app will behave accordingly).
EDIT:
I now already have a (working) navigation bar, but the things I want are the round icons in the header. I want someone to be able to choose the user they are viewing.

The effect you want can be achieved by using NavigationView from the com.android.support:design support lib.
You can find a full tutorial on that here. And you can download the full source code from that tutorial here.
And here's another nice tutorial that you could follow.
But long story short, that view is split between two main parts, a header and a menu part, and each one of those you'll have to define on XML.
As from that tutorial:
Header View
This View is basically the top part of the navigation
drawer, which holds the profile picture, name and email etc. You need
to define this in a separate layout file we would look into that in
just a moment.
Menu
This is the menu you want to show below your header, we define
menu in a menus folder, just like you define menu for your overflow
menu. So basically NavigationView is a container for the Header View
and Menu which you are going to use in your sliding drawer. So now
that you understand the NavigationView we can start building our
Navigation Drawer.
With that in mind, build your header as you would do with any other layout. And the Menu is defined somewhat like the Toolbar/ActionBar menu. e.g.:
navigation_menu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group
android:checkableBehavior="single">
<item
android:id="#+id/drawer_home"
android:checked="true"
android:icon="#drawable/icon_home"
android:title="#string/title_home"/>
<item
android:id="#+id/drawer_content"
android:icon="#drawable/icon_content"
android:title="#string/title_content"/>
<item
android:id="#+id/drawer_about"
android:icon="#drawable/icon_about"
android:title="#string/title_about"/>
<item
android:id="#+id/drawer_exit"
android:icon="#drawable/icon_exit"
android:title="#string/title_exit"/>
</group>
</menu>
Then, on your Activity you'll just have to make a layout like the one found in the tutorial, using the DrawerLayout along with NavigationView.
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
>
<include
android:id="#+id/toolbar"
layout="#layout/tool_bar"/>
<FrameLayout
android:id="#+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="start"
app:headerLayout="#layout/header"
app:menu="#menu/navigation_menu"/>
</android.support.v4.widget.DrawerLayout>
You'll also have to create some Fragments for each screen you want to display with this NavigationView. After you've done that, on your Activity you can handle the selection events by implementing NavigationView.OnNavigationItemSelectedListener, like this:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
// Your Activity
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
Fragment fragment = null;
switch(menuItem.getItemId()) {
case R.id.drawer_home:
fragment = new YourFragment();
break;
case R.id.drawer_content:
fragment = new AnotherFragment();
break;
case R.id.drawer_about:
fragment = new AboutFragment();
break;
case R.id.drawer_exit:
// TODO - Prompt to exit.
finish();
break;
}
if (fragment == null) {
fragment = new YourFragment();
}
drawerLayout.closeDrawers();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame, fragment)
.commit();
return true;
}
}
As for your edit, the icons could be represented by an ImageView. And to navigate between multiple profiles, it depends on how you've implemented that logic on your app, but as a "generic" answer, you could switch those profiles using something like a Spinner.
Those tutorials will help you through that step:
Android spinner (drop down list) example
Android - Spinner
Basic Spinner example (Stackoverflow question)
Spinners (Android dev guide)
Once you've set that up on your header, handle the item selection and change the user profile accordingly. (This last part depends ENTIRELY on how you've implemented user profiles on your app). But just as a head start, you could check the android training site, more specifically, this part.

You should use NavigationView
It provides the framework for easy to implement material navigation
drawer with the help of inflate navigation items through menu
resource. Befor Navigation View, we have hard way to make material
navigation drawer using listview or linearlayout with custom adapter,
but now we just need to add Navigation View in DrawerLayout,
everything else will be handled by Navigation View.
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!-- Your contents -->
<android.support.design.widget.NavigationView
android:id="#+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="#menu/my_navigation_items" />
</android.support.v4.widget.DrawerLayout>
For this requirement You can check sample
MaterialDrawer
How To Make Material Design Navigation Drawer
Playing with NavigationView
Hope this helps .

I think this MaterialDrawer is what you're looking for. This library has a lot of examples. You can either use this library directly or read the source code and implement your own drawer.

You can implement this Material Navigation drawer using MaterialNavigation library.
Article about implementation is here.
You will just have to import that library and you're done. See demo code on below site:.
https://github.com/PatilShreyas/MaterialNavigationView-Android

Related

Replace fragment by another using default navigation drawer activity template

I have a navigation drawer using fragments created from the default "Navigation Drawer Activity" template in Android Studio. Inside a fragment A, I want to open another fragment B. So the fragment B must replace fragment A. I saw on google, that I should use FrameLayout to Dynamically change the current displayed fragment.
<FrameLayout
android:id="#+id/nav_host_frame_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/mobile_navigation" />
</FrameLayout>
To change fragment, I am using the code below, when I am clicking on a button in the fragment that I want to be replaced
NewCalendarEvent newEventFrag = new NewCalendarEvent();
getActivity().getSupportFragmentManager().beginTransaction()
.replace(R.id.nav_host_frame_layout, newEventFrag)
.addToBackStack(null)
.commit();
Currently, when I click on the button, the two fragments are show. Is because I am using fragment and frameLayout together ? What I am doing wrong ?
If you are using a NavHostFragment and the Navigation Component, then you never use a FragmentTransaction. Instead you navigate to a screen by using the APIs on NavController.

Android fragment preloading data

Hello I'm trying to make an application that has multiple bottomnaviagtion tabs.
Currently it works because fragment data (for example, images) are static. However, if I want to make them dynamic, I'll have to create a preloader.
So I want to display a loading layout (for example R.layout.loading) UNTIL (async) function has completed and obtained data from server. Then I want to replace the layout in the fragment with a new layout (R.layout.datafragment)
Fragment onCreateView:
return inflater.inflate(R.layout.loading, container, false);
In summary it should work exactly like youtube bottom tabs.
You should create in your activity layout a placeholder for those dynamic fragments and a loader which is by default gone, but when you start loading data from the server you should make it visible (loader). Then, when you load necessary data, just start fragment transition and place whatever fragment you have loaded.
Your parent activity's layout should be like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--Navigation View and Fragment Container-->
</RelativeLayout>
<RelativeLayout
android:id="#+id/progress_layout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
</RelativeLayout>
</RelativeLayout>
Then you simply show/hide progressLayout based on your requirement. Thanks

How can I change the way I display the fragments in differents display sizes?

I'm currently making an app for Android devices and I would like to know how can I change the way I display the fragments in differents display sizes (ex. Tablet).
At this point I have an activity for all my fragments and this causes me to replace the fragments when I change page but for tablets I would like to display 2 fragments inside that activity.
I've created a layout-large version for my main activity:
<?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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".PaginaInicial"
tools:showIn="#layout/app_bar_pagina_inicial">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
class="pt.ipp.estg.schoolhelperapp.apontamento.ListaApontFragment"
android:id="#+id/a_fragment"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="match_parent" />
<fragment
class="pt.ipp.estg.schoolhelperapp.apontamento.VerApontFragment"
android:id="#+id/b_fragment"
android:layout_weight="2"
android:layout_width="0dp"
android:layout_height="match_parent" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
The fragment container is inside layout-small version of the main activity.
One of the fragments displays a list of items (#+id/a_fragment) and the other one displays the information of one specific item that I previously selected (#+id/b_fragment).
For further details refer to this document: https://developer.android.com/training/multiscreen/screensizes
Create a default alias resource value file in res/values/refs.xml and place the following code inside it. This value will refer to your layout file that has only one fragment.
<resources>
<item name="activity_masterdetail" type="layout">#layout/layout_with_single_fragment</item>
</resources>
Now need to create an alternative resource so that the activity_masterdetail alias will point to layout_with_two_fragment.xml on larger devices.
Create a new file with same name refs.xml but with resource qualifiers for Smallest Screen Width under Available qualifiers. Use smallest dimension of 600dp or more (sw600dp qualifier)
<resources>
<item name="activity_masterdetail" type="layout">#layout/layout_with_two_fragment</item>
</resources>
Your goal here is to have logic that works like this:
For devices that are under a specified size i.e mobile phones, use layout_with_single_fragment.xml.
For devices that are over a specified size, use layout_with_two_fragment.xml.
Now in your man activity which shows a list, use setContentView(R.layout.activity_masterDetail) i.e the name of referenced layout
If this code will run on mobile phones, normal refs.xml file will be referenced by activity_masterDetailbut if this code runs on a tablet, resource qualified refs.xml file will be used.
In your activity logic, where you want to show master and detail layout on the same screen on tables but open another activity on phones, use the following logic inside onClick() of your list items
if (findViewById(R.id.a_fragment) == null) {
Intent intent = A_Activity.newIntent(this, listItem.getId());
startActivity(intent);
} else {
Fragment newDetail = B_Fragment.newInstance(list_item.getId());
getSupportFragmentManager().beginTransaction()
.replace(R.id.b_fragment, newDetail)
.commit();
}
You should take a look at this before link it should help you understand for sure more about supporting different screen sizes.
And here is an example that you can try.

Tabs+Swipe in Android for all API levels

My plan is creating an Activity includes Tabs+Swipe for all Android version. If we set it from a default Android project, it has just support for at least API 11.
In Sherlock we have two project named : Tab Navigation, Tab Navigation(collapsed) includes Tabs but not Swipe.
They have Issue #240 in their samples that has a bug (swipe left/right when the tabs are in collapsed mode (landscape) and the selected item does not update).
Do you know any sample code that solve this problem?
You made this now with the default Android Support Library (or the ABS), with a ViewPager and a PagerTabStrip:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.PagerTabStrip
android:id="#+id/tabStrip"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"/>
</android.support.v4.view.ViewPager>
</LinearLayout>
Then create an Adapter to the ViewPager that extends of FragmentStatePagerAdapter (for example) and override the method public CharSequence getPageTitle(int position) to provide a title for each tab.
Hope it helps.
I also happened to have same situation. Follow below links and you will get all what you need.
See this tutorial
http://droidista.blogspot.com/2012/08/making-actionbarsherlock-and.html
And get demo code from here
https://github.com/zmdominguez/vpi-abs-demo
I found these links which might help you out.
A page flipper control - like the android home screens
https://github.com/JakeWharton/Android-ViewPagerIndicator

How can I define a fragment's layout from XML?

I'm trying to define a fragment's layout in XML in the same way that I defined the layout of my view.
Is this possible? I tried several things, but none of them seem to work.
My activity layout looks as follows (main.xml):
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="full.lommeregner.Lommeregnerrv2Activity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/lommeregnerv2">
</fragment>
</ListView>
Now, since I'm not a big fan of generating layouts through raw Java code, I tried defining my fragment as follows (fragment_lommeregner.xml):
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="full.lommeregner.Lommeregnerrv2Activity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/lommeregnerv2">
<!-- my content was located here (some textviews, buttons and so on). -->
</fragment>
Am I doing something wrong? How can I define the layout of a fragment through XML?
A Fragment works much like an activity, in that you need a Java class file to go with it. you cannot create a Fragment just by creating a fragment layout - you need a class for your fragment:
Create a layout XML and an Activity subclass for your activity
Create a layout XML and a Fragment subclass for your fragment
Tie the two together in your Activity layout XML (or using FragmentTransaction if you want to do it in Java code)
If you haven't already done so, read, re-read and digest everything on this page:
https://developer.android.com/guide/components/fragments.html
There's a lot there, but Fragments are an essential part of Android apps now so it's required reading. The good news is that the basics of fragments is pretty simple.
Simply add into your <fragment> tag as property:
tools:layout="#layout/your_layout_xml"
And in your main.xml (or <fragment> tag container) into your parent container (in this case ListView):
xmlns:tools="http://schemas.android.com/tools"

Categories

Resources