I could not solve this problem.
Here my Main activity:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, AttendanceFragment.OnFragmentInteractionListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, R.string.nav_drawer_open, R.string.nav_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
navigationView.setNavigationItemSelectedListener(this);
showAttendanceFragment();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.nav_drawer, menu);
return true;
}
private void showAttendanceFragment() {
AttendanceFragment fragment = new AttendanceFragment();
FragmentManager fragmentManager = this.getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.fragment_container,fragment);
fragmentTransaction.commit();
}
#Override
public void onFragmentInteraction(Uri uri) {
}
}
Here the main xlm:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start"
android:background="#color/primary">
<include
layout="#layout/app_bar_main"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:itemTextColor="#color/accent"
app:itemIconTint="#color/accent"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer"
android:background="#color/primary"/>
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"/>
</android.support.v4.widget.DrawerLayout>
The bar:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/primary_darker"
app:popupTheme="#style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
and the fragment:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.hoangdang.diemdanh.Fragments.AttendanceFragment">
<TextView
android:id="#+id/id1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment" />
<TextView
android:id="#+id/id2"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="#string/hello_blank_fragment" />
</FrameLayout>
I tried use linear layout but not working
You should understand the DrawerLayout. You can check this here: Google DrawerLayout Guide. As the note from Google Guide:
The main content view (the FrameLayout above) must be the first child in the DrawerLayout because the XML order implies z-ordering and the drawer must be on top of the content.
The main content view is set to match the parent view's width and height, because it represents the entire UI when the navigation drawer is hidden.
The drawer view (the ListView) must specify its horizontal gravity with the android:layout_gravity attribute. To support right-to-left (RTL) languages, specify the value with "start" instead of "left" (so the drawer appears on the right when the layout is RTL).
The drawer view specifies its width in dp units and the height matches the parent view. The drawer width should be no more than 320dp so the user can always see a portion of the main content.
As we can see in your xml:
your main content view is AppBar, that's not good.
Both AppBar and FrameLayout have match_parent in layoutParams, that's the reason why you got the issue.
So, how to solve it? you have to combine AppBar and FrameLayout under 1 view only (Relative or LinearLayout) and put it as the first child of DrawerLayout
1. Remove your FrameLayout from activity_main.xml and place it to app_bar_main.xml under AppBarLayout.
2. Remove attribute android:layout_marginTop="?attr/actionBarSize" from FrameLayout
2. Add attribute app:layout_behavior="#string/appbar_scrolling_view_behavior" to FrameLayout.
Update your activity_main.xml as below:
<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start"
android:background="#color/primary">
<include
layout="#layout/app_bar_main"
android:layout_height="match_parent"
android:layout_width="match_parent"/>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:itemTextColor="#color/accent"
app:itemIconTint="#color/accent"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer"
android:background="#color/primary"/>
</android.support.v4.widget.DrawerLayout>
Update app_bar_main.xml as below:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="#color/primary_darker"
app:popupTheme="#style/AppTheme.PopupOverlay"/>
</android.support.design.widget.AppBarLayout>
<!-- Content :: Fragments-->
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
Hope this will work~
Add layout behavior and try...
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
Related
My problem is scrolling in ExpandableListView with coordinator layout design.
Toolbar works right and When it touched up, it gets hide, but ExpandableListView doesnt scroll
I need to use NestedScrollView because the layout_navigation_view is Common everywhere.
Take a look at the
picture http://info-sys.persiangig.com/noScroll.gif
My main code with Java AND My design code with XML is:
ActivityMain.java
public class ActivityMain extends ActivityNavigationView {
ArrayList<StructNote> group ; //StructNote public String id,title,icon; // StructNote = Filde Parametr
ArrayList<ArrayList<StructNote>> child ;
ActivityAdapter mAdapter; // class extends BaseExpandableListAdapter
ExpandableListView exListView ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// ---> content_frame => layout_navigation_view.xml
FrameLayout contentFrameLayout = (FrameLayout) findViewById(R.id.content_frame);
getLayoutInflater().inflate(R.layout.activity_main, contentFrameLayout);
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.getMenu().getItem(1).setChecked(true);
exListView = (ExpandableListView) findViewById(R.id.exListView);
//... Fill Group Child Adapter List
//...Other CODE ...
}
}
ActivityNavigationView.java
public class ActivityNavigationView extends AppCompatActivity {
DrawerLayout drawerLayout;
ActionBarDrawerToggle actionBarDrawerToggle;
Toolbar toolbar;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_navigation_view);
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
//...Other CODE ... Click menu and Open close NavigationView, Toolbar
}
}
layout_navigation_view.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/background_light"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/main.appbar"
android:layout_width="match_parent"
android:layout_height="300dp"
android:theme="#style/AppTheme.AppBarOverlay"
app:layout_scrollFlags="scroll|enterAlways">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/main.collapsing"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp">
<ImageView
android:id="#+id/main.backdrop"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
android:src="#drawable/bg_tool_bar"
app:layout_collapseMode="parallax"/>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay"
app:layout_collapseMode="pin">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_margin="#dimen/activity_horizontal_margin"
android:src="#android:drawable/ic_dialog_info"
app:layout_anchor="#id/main.appbar"
app:layout_anchorGravity="bottom|right|end" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_activity_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
activity_main.xml
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipeToRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ExpandableListView
android:id="#+id/exListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transcriptMode="disabled"
android:divider="#null"
android:dividerHeight="0dp"
android:minHeight="130dp">
</ExpandableListView>
</android.support.v4.widget.SwipeRefreshLayout>
</LinearLayout>
Edit :
activity_main.xml
<?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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ExpandableListView
android:id="#+id/exListView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:transcriptMode="disabled"
android:divider="#null"
android:dividerHeight="0dp"
android:minHeight="130dp">
</ExpandableListView>
</LinearLayout>
Toolbar works right and When it touched up, it gets hide, but ExpandableListView doesnt scroll
Yes it's because of SwipeRefreshLayout and using SwipeRefreshLayout inside of NestedScrollView.
Add the SwipeRefreshLayout Widget To add the swipe to refresh widget to
an existing app, add SwipeRefreshLayout as the parent of a single
ListView or GridView
Solution:
Place SwipeRefreshLayout outside of NestedScrollView in layout_navigation_view.xml first:
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipeToRefresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
...
</android.support.v4.widget.NestedScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
And remove SwipeRefreshLayout in activity_main.xml.
I would like to wrap into a DrawerLayout a FrameLayout (to replace it on demand with other FrameLayouts at runtime). The Code below is from the GitHub project over here.
But If I add a FrameLayout in the LinearLayout below the widget.Toolbar, I receive following exception
Unhandled Exception:
System.InvalidCastException: Unable to convert instance of type 'Android.Widget.FrameLayout' to type 'Android.Support.Design.Widget.NavigationView'.
Without the FrameLayout it works perfectly. Where should I place the FrameLayout to achieve my goal?
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/drawer_layout"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<android.support.design.widget.NavigationView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:id="#+id/nav_view"
app:menu="#menu/navmenu"
app:headerLayout="#menu/header" />
</android.support.v4.widget.DrawerLayout>
The MainAcitivty.cs
drawerLayout = FindViewById<DrawerLayout>(Resource.Id.drawer_layout);
// Init toolbar
var toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
// Attach item selected handler to navigation view
var navigationView = FindViewById<NavigationView>(Resource.Id.nav_view);
navigationView.NavigationItemSelected += NavigationView_NavigationItemSelected;
// Create ActionBarDrawerToggle button and add it to the toolbar
var drawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, Resource.String.open_drawer, Resource.String.close_drawer);
drawerLayout.AddDrawerListener(drawerToggle);
drawerToggle.SyncState();
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:background="#color/white"
tools:openDrawer="start">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="#layout/toolbar" android:id="#+id/drawer_toolbar"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/framelayout"/>
</LinearLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main">
<!-- app:menu="#menu/activity_main_drawer"-->
<ExpandableListView
android:id="#+id/navigationmenu"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start|right"
android:divider="#f0f0f0"
android:dividerHeight="1.5dp"
android:indicatorEnd="?android:attr/expandableListPreferredItemIndicatorRight"
android:layout_marginTop="170dp"
android:background="#android:color/white"
android:visibility="visible">
</ExpandableListView>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
I implemented the Navigation Drawer by using the template provided by Google in New Android Studio 1.4. Here it automatically created everything including the layout and class.
This is my activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent" android:layout_height="match_parent"
android:fitsSystemWindows="true" tools:openDrawer="start">
<include layout="#layout/app_bar_main" android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView android:id="#+id/nav_view"
android:layout_width="wrap_content" android:layout_height="match_parent"
android:layout_gravity="start" android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main" app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
app_bar_main.xml
<?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:layout_width="match_parent"
android:layout_height="match_parent" android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout android:layout_height="wrap_content"
android:layout_width="match_parent" android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar android:id="#+id/toolbar"
android:layout_width="match_parent" android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<RelativeLayout android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" tools:showIn="#layout/app_bar_main"
app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
tools:context=".MainActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/frame_container">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Hell World"/>
</FrameLayout>
</RelativeLayout>
</android.support.design.widget.CoordinatorLayout>
You could see fragment_container above. I simply replace this with different fragment based on item click in the Navigation drawer.
There's no issue in this too.
UpdatesFragment fragment = new UpdatesFragment();
android.support.v4.app.FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.frame_container,fragment);
fragmentTransaction.addToBackStack(null);
fragmentTransaction.commit();
Now, I would to have a different toolbar for each fragment. How could i get the different toolbar for each fragment in this new CoordinatorLayout?
Or, I mean I would like to have a different Scroll Behavior for each fragment. How can i achieve this
Is it possible to have a CoordinatorLayout / CollapsingToolbarLayout in the fragments shown in the main container of a DrawerLayout?
An answer to another question suggests that each fragment could have its own Toolbar. But this doesn't work well with the ActionBarDrawerToggle as it requires a Toolbar to link to the open/close drawer behaviour.
Has anybody achieved this, or do you have pointers about this? Thanks.
EDIT: I've been focusing some efforts in putting a single Toolbar in the DrawerLayout, meant to stay there all the time, but was not able to get it to scroll (on a Nexus5 API 22). In this question it is mentioned that the CoordinatorLayout needs to be the main view. So maybe inserting it in a DrawerLayout (as below) is not going to work.
<android.support.v4.widget.DrawerLayout ...>
<!-- main content -->
<android.support.design.widget.CoordinatorLayout ...>
<android.support.design.widget.AppBarLayout ...>
<android.support.design.widget.CollapsingToolbarLayout ...>
<ImageView .../>
<android.support.v7.widget.Toolbar .../>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView .../>
</android.support.design.widget.CoordinatorLayout>
<!-- navigation drawer -->
<android.support.design.widget.NavigationView ...>
<!-- drawer content -->
<fragment .../>
</android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
As a matter of fact, yes you can. I was looking for the same thing and the link from your question lead me to this from Google Blogpost
Anyhow, below are my layout files, as for java code I did not change anything and Fragment calling remains the same.
activity_main.xml (Main file)
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
</android.support.v4.widget.DrawerLayout>
app_bar_main.xml (NavigationBar 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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="192dp"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/toolbar_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_main" />
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:src="#android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView 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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="#layout/app_bar_main">
<FrameLayout
android:id="#+id/content_main_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.NestedScrollView>
And now you have "DrawerLayout + Fragments + CollapsingToolbarLayout"
This layout works for me
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_gravity="left"
android:layout_width="match_parent" android:layout_height="match_parent"
tools:context=".BaseDrawerActivity"
android:foregroundGravity="left">
<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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".myapp">
<android.support.design.widget.AppBarLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.design.widget.CoordinatorLayout>
<!-- The drawer -->
<se.emilsjolander.stickylistheaders.StickyListHeadersListView
android:id="#+id/drawer"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
style="#style/BaseStyle_Dark" />
Initialise the activity as normal
public class BaseDrawerActivity extends AppCompatActivity implements MenuInterface {
private DrawerLayout mDrawerLayout;
private StickyListHeadersListView menuItemListView;
private static MenuItemAdapter menuItemAdapter;
private ActionBarDrawerToggle mDrawerToggle;
private Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_drawer);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
menuItemListView = (StickyListHeadersListView) findViewById(R.id.drawer);
toolbar = (Toolbar) findViewById(R.id.toolbar);
if (savedInstanceState == null) {
}
mDrawerToggle = new ActionBarDrawerToggle(this,mDrawerLayout,toolbar,R.string.home_open,R.string.home_close);
mDrawerLayout.setDrawerListener(mDrawerToggle);
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
This will allow you to add the usual CoordinatorLayout features.
I had the same problem but I didn't need the ImageView, so here is my solution:
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer"
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:fitsSystemWindows="true"
tools:context=".MainActivity">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:elevation="#dimen/toolbar_elevation"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header"
app:menu="#menu/drawer_view"/>
</android.support.v4.widget.DrawerLayout>
Hope it helps!
When I click on my drawer toggle I get the following exception:
java.lang.IllegalArgumentException: No drawer view found with gravity
LEFT
This is my activity_drawer.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"/>
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<fragment
android:id="#+id/navigation"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:name="com.xyz.ui.navigation.NavigationFragment"
tools:layout="#layout/fragment_navigation" />
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
My fragment_navigation.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"
android:layout_gravity="start">
</ListView>
And my list item:
<?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:textAppearance="?android:attr/textAppearanceLarge"
android:text="Large Text"
android:id="#+id/navigation_item_text"
android:layout_gravity="center_horizontal" />
</LinearLayout>
From documentation
To use a DrawerLayout, position your primary content view as the first child with a width and height of match_parent. Add drawers as child views after the main content view and set the layout_gravity appropriately. Drawers commonly use match_parent for height with a fixed width.
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"/>
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
<fragment
android:id="#+id/navigation"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="right"
android:name="com.xyz.ui.navigation.NavigationFragment"
tools:layout="#layout/fragment_navigation" />
</android.support.v4.widget.DrawerLayout>
Ok. Let me make the things simple and clear here.
What is DrawerLayout?https://developer.android.com/reference/android/support/v4/widget/DrawerLayout.html
DrawerLayout
Acts as a top-level container for window content that allows for
interactive "drawer" views to be pulled out from the edge of the
window. Drawer positioning and layout is controlled using the android:layout_gravity
attribute on child views corresponding to which side of the view you
want the drawer to emerge from: left or right. (Or start/end on
platform versions that support layout direction.) To use a
DrawerLayout, position your primary content view as the first child with a width
and height of match_parent. Add drawers as child views after the main content view and set the
layout_gravity appropriately. Drawers commonly use match_parent for height with a fixed width.
What is DrawerLayout?, In Simple words:
The layout supported by Android that allows you to have an overlay screen, called as drawer, over your main screen.
DrawerLayout needs childviews to work, similar to the LinearLayout and RelativeLayout.
The childview must have either of the property set
android:layout_gravity="start" OR android:layout_gravity="left"
DrawerLayout uses this childView to know from where to start showing the Drawer i.e. From Left to Right or Right to
Left. There are countries where the text is read from Right to Left.
Techie Stuff:
EVENT#1: ActionBarDrawerToggle.java is set as the drawer listener for the DrawerLayout
DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
ActionBarDrawerToggle mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
toolbar,R.string.navigation_drawer_open,
R.string.navigation_drawer_close)
mDrawerLayout.setDrawerListener(mDrawerToggle);
EVENT#2: The user clicks on the Toolbar.navigationIcon that calls the toggle() function
ActionBarDrawerToggle.java (android-sdk\sources\android-22\android\support\v7\app\ActionBarDrawerToggle.java)
private void toggle() {
if (mDrawerLayout.isDrawerVisible(GravityCompat.START)) {
mDrawerLayout.closeDrawer(GravityCompat.START);
} else {
mDrawerLayout.openDrawer(GravityCompat.START);
}
}
Gravity.java (android-sdk\sources\android-22\android\view\Gravity.java)
/** Push object to x-axis position at the start of its container,
not changing its size.*/
public static final int START = RELATIVE_LAYOUT_DIRECTION | Gravity.LEFT;
EVENT#3: Toggle() function calls the mDrawerLayout.openDrawer(Gravity.START)
DrawerLayout.java (support-v4-22.1.1.jar library)
/*** Open the specified drawer by animating it out of view. **
#param gravity Gravity.LEFT to move the left drawer or Gravity.RIGHT
for the right. * GravityCompat.START or GravityCompat.END may also
be used. */
public void openDrawer(#EdgeGravity int gravity) {
final View drawerView = findDrawerWithGravity(gravity);
if (drawerView == null) {
throw new IllegalArgumentException("No drawer view found with gravity " +
gravityToString(gravity));
}
openDrawer(drawerView);
}
EVENT#4: If no childView of the DrawerLayout is set with the layout_gravity="start” or left the No drawer view found with gravity LEFT is thrown.
Solution:
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<!--This will appear when the drawer is closed (default view)-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary" />
</LinearLayout>
<!-- This will appear when the drawer is opened -->
<!-- the property,android:layout_gravity, is used internally to identify imageView as the view to be displayed when the drawer is opened -->
<ImageView
android:id="#+id/imageView"
android:layout_width="match_parent"
android:layout_height=" match_parent"
android:layout_gravity="left"
android:background="#drawable/img_shree_ganesha" />
</android.support.v4.widget.DrawerLayout>
I hope that helps. Happy Coding…
The "Android Drawer" needs to be a direct child node of the "DrawerLayout".
In your example above (re: original question example), you only have a single direct child node under "DrawerLayout" ("LinearLayout"), and no drawer view after it.
Move your drawer view out of your LinearLayout and place it after it.
in my case, because DrawerLayout attr: tools:openDrawer="start"
i added android:layout_gravity="start" for the second element
<android.support.v4.widget.DrawerLayout
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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:openDrawer="right"
tools:context=".map.MapFragment">
<include layout="#layout/fragment_map" />
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="right"
android:background="#color/white"
android:fitsSystemWindows="true"
app:menu="#menu/drawer_view"
app:headerLayout="#layout/drawer_nav_header"/>
</android.support.v4.widget.DrawerLayout>
add
android:layout_gravity="start"
to NavigationView
like this
<com.google.android.material.navigation.NavigationView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:headerLayout="#layout/drawer_menu"
android:layout_gravity="start"
android:foregroundGravity="right"
android:id="#+id/nv">
<include layout="#layout/drawer_menu"/>
</com.google.android.material.navigation.NavigationView>
Are you using right to left(RTL) layout? Setting gravity left on RTL layout would throw this exception. This can be fixed by setting gravity start instead of left
I solve this problem like this :
XML :
<?xml version="1.0" encoding="utf-8"?>
<androidx.drawerlayout.widget.DrawerLayout 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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:layoutDirection="rtl"
tools:openDrawer="end"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<include
layout="#layout/toolbar_main"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<include layout="#layout/content_main" />
</LinearLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/navigationView"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:layoutDirection="rtl"
android:background="#color/white"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/menu_drawer" />
</androidx.drawerlayout.widget.DrawerLayout>
AND IN JAVA:
if (mDrawerLayout != null && mDrawerLayout.isDrawerOpen(GravityCompat.END)) {
mDrawerLayout.closeDrawer(GravityCompat.END);
}
I hope this helps someone!
You should use the same gravity in DrawerLayout and NavigationView: for example: tools:openDrawer="right"in DrawerLayout tag and android:layout_gravity="right" in NavigationView tag
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout
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/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:openDrawer="right"
tools:context=".map.MapFragment">
<include layout="#layout/fragment_map" />
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="right"
android:background="#color/white"
android:fitsSystemWindows="true"
app:menu="#menu/drawer_view"
app:headerLayout="#layout/drawer_nav_header"/>
</android.support.v4.widget.DrawerLayout>
java.lang.IllegalArgumentException: No drawer view found with gravity LEFT
SOLUTION
Assign a layout_gravity = "start" or "left" attribute to one of your DrawerLayout child view if your drawer layout already have a child view. OR
Simply create a child view inside your DrawerLayout View and give it a layout_gravity = "start" or "left" attribute.
for example
<?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:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/mDrawer_Layout"
tools:context="com.rad5.matdesign.MainActivity">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<!-- Notice that here an image view as a child of the Drawer layout was -->
<!-- given a layout_gravity="start" -->
<ImageView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="start"/>
</android.support.v4.widget.DrawerLayout>
<android.support.design.widget.AppBarLayout
android:id="#+id/appBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"/>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header"
app:menu="#menu/menu_navigation_items" />
</android.support.design.widget.CoordinatorLayout>
The error fixed after replacing
<fragment
android:id="#+id/fragmentContainerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.example.MyFragment"/>
with
<androidx.fragment.app.FragmentContainerView
android:id="#+id/fragmentContainerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start" />
and added Fragment instance to the FragmentContainerView in onCreate()
supportFragmentManager.beginTransaction()
.add(R.id.fragmentContainerView, MyFragment())
.commit()