Scrollable Tab bar cannot restore when other tab clicked - android

Problem 2:
The Tab bar cannot restore back to original position when another tab is clicked (tab 1 with non-recyclerview). It sticked at the top until it can scrolls back using tab 2 that send it to the top
I'm using re-usable code that no need to re-write App Bar and Navigation Drawer everytime.
Problem 1 detail:
The app bar can scroll when scrolling recycler view but the tab bar is hiding behind app bar until app bar scroll out of the screen at top (tab bar cannot move and stay at 0 y-coordinate)
Problem 1 (fixed):
Solution: move the line "app:layout_behavior="#string/appbar_scrolling_view_behavior" from viewpager to framelayout
Motion 1 motion 2
←Screen capture
My code are:
activity_base.xml (acitivity to put every page in FrameLayout)
<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:id="#+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<!--Toolbar-->
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark">
<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_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<!--Activity container to put page content-->
<FrameLayout
android:id="#+id/flContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</android.support.design.widget.CoordinatorLayout>
<!--
NavigationView - place inside drawer
-->
<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"
/>
pg02_push.xml (page with few tabs)
<RelativeLayout 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"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".Pg02Push">
<!--
AppBarLayout > Toolbar, TabLayout
-->
<android.support.design.widget.AppBarLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark"
android:layout_below="#+id/toolbar"
>
<!--TabLayout-->
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"
app:tabGravity="fill"/>
</android.support.design.widget.AppBarLayout>
<!--VIewPager for Tab-->
<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"
/>
pg02tab02_allpush.xml (tab with recycler view)
<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="com.fcm.firsthandpptynoti.Pg02Tab02AllPush">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview_tab02_allpush"
android:divider="#FFB900"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
BaseActivity.java
#Override
public void setContentView(#LayoutRes int layoutResID){
/**
* This is going to be our actual root layout.
* Instantiates a layout XML file into its corresponding View objects.
* It is never used directly. Instead, use getLayoutInflater() or
* getSystemService(Class) to retrieve a standard LayoutInflater instance
* that is already hooked up to the current context and correctly configured for the device you are running on
* android.view.LayoutInflater#inflate(int, android.view.ViewGroup)
*/
mDrawerLayoutFull = (DrawerLayout) getLayoutInflater().inflate(R.layout.activity_base, null);
/**
* {#link FrameLayout} to inflate the child's view. We could also use a {#link android.view.ViewStub}
*
*/
FrameLayout activityContainer = (FrameLayout) mDrawerLayoutFull.findViewById(R.id.flContent);
getLayoutInflater().inflate(layoutResID, activityContainer, true);
/**
* Note that we don't pass the child's layoutId to the parent,
* instead we pass it our inflated layout.
*/
super.setContentView(mDrawerLayoutFull);
/*
Toolbar
Set a Toolbar to replace the ActionBar.
Initializing Toolbar and setting it as the actionbar
*/
mToolbar = (Toolbar) findViewById(R.id.toolbar);
if (useToolbar()) {
mToolbar.setTitle(setTitleOnToolbar());
setSupportActionBar(mToolbar);
}
else {
mToolbar.setVisibility(View.GONE);
}
/*
Navigation View
*/
//
mNavigationView = (NavigationView) findViewById(R.id.nav_view);
//Navigation View
setUpNavigationView();
//....
//...
//..
//.
}
//End of setContentView
Pg02Push.java
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.pg02_push);
/*
Tab
*/
//ViewPager - Layout manager that allows the user to flip left and right through pages of data.
mViewPager = (ViewPager) findViewById(R.id.viewpager);
//MyViewPagerAdapter
setupViewPager(mViewPager);
//...
//..
//.
mTabLayout = (TabLayout) findViewById(R.id.tabs);
//Assigns the ViewPager to TabLayout
//The one-stop shop for setting up this TabLayout with a ViewPager.
mTabLayout.setupWithViewPager(mViewPager);
} // End of onCreate

Related

How to pin view in fragment if I'm using CollapsingToolbarLayout?

I'm using AppBarLayout with CollapsingToolbarLayout that can change its height when the user scroll screen. Also, I have fragments under AppBarLayout. One of the fragment has a custom bottom navigation bar 1. And when CollapsingToolbarLayout is fully opened I can't see Bottom Nav Bar for this fragment. I want to pin it somehow.2
I tried to use layout_behavior="#string/appbar_scrolling_view_behavior" not on fragment but on view in this fragment but it didn't work.
Main.xml
<android.support.v4.widget.DrawerLayout>
<android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.AppBarLayout
android:layout_height="#dimen/app_bar_height">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/toolbar_layout"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:toolbarId="#+id/toolbar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:gravity="center_vertical|start"
app:layout_collapseMode="pin"
app:navigationIcon="#mipmap/burger"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/content_frame"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.design.widget.CoordinatorLayout>
</android.support.v4.widget.DrawerLayout>
some_fragment.xml
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--This view I want to pin-->
<View
android:id="#+id/bottom_navigation_bar"
android:layout_width="match_parent"
android:layout_height="63dp"
android:layout_alignParentBottom="true"
android:orientation="vertical">
</View>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="#+id/bottom_navigation_bar"
android:layout_alignParentTop="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</RelativeLayout>
I managed to find some strange solution for this. This code is for Xamarin Android C#. I just made the bottom margin according to AppBarLayout offset
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.home_view);
var appBar = FindViewById<AppBarLayout>(Resource.Id.app_bar);
appBar.AddOnOffsetChangedListener(this);
}
public void OnOffsetChanged(AppBarLayout appBarLayout, int verticalOffset)
{
var minHeight = Resources.GetDimension(Resource.Dimension.app_bar_min_height);
var fragment = SupportFragmentManager.FindFragmentById(Resource.Id.content_frame);
if (fragment is DashboardView) {
var layout = fragment.View.FindViewById<RelativeLayout>(Resource.Id.dashboard_layout);
var param = new FrameLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.WrapContent);
param.SetMargins(0, 0, 0, verticalOffset + (int)minHeight);
layout.LayoutParameters = param;
}
}

Material Design elevation issue when add a fragment with TabLayout

I'm currently working on an application for v22 and use the following libraries:
compile 'com.android.support:appcompat-v7:22.2.1'
compile 'com.android.support:support-v4:22.2.1'
compile 'com.android.support:design:22.2.1'
I have only one Activity called HomeActivity that has a Navigation Drawer Inside.
This is the activity_home.xml layout:
<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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<android.support.design.widget.CoordinatorLayout
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:fitsSystemWindows="false">
<android.support.design.widget.AppBarLayout
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"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.ActionBar" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/content_frame"
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/navigation_view"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_gravity="start"
app:menu="#menu/menu_navigation"/>
So, every time I choose an item from navigation Drawer I replace the FrameView #+id/content_frame with a new Fragment like this:
int id = menuItem.getItemId();
switch (id)
{
case R.id.gazzette:
fragmentManager.beginTransaction()
.replace(R.id.content_frame, new ListViewFragment())
.commit();
drawerLayout.closeDrawers();
break;
case R.id.concorsi:
// Insert the fragment by replacing any existing fragment
fragmentManager.beginTransaction()
.replace(R.id.content_frame, new ConcorsiFragment())
.commit();
drawerLayout.closeDrawers();
break;
Everything works fine and I have a toolbar with the right elevation.
But when I try to replace the #+id/content_frame Fragment with a new Fragment with a TabLayout and View Pager I see the elevation of the toolbar of the Home Activity.
The layout of this inner Fragment is:
<android.support.design.widget.CoordinatorLayout
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:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"
android:elevation="6dp"
android:background="#color/colorPrimary"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#FFFFFF"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.AppBarLayout>
Naturally, if I start a new Activity (without Fragment) with a TableLayout everything goes ok but I don't want create a new Activity and launch it with a selection of Navigation Drawer but I want use only Fragment items.
If a set app:elevation="0dp" from HomeActivity I have no shadow in all Application Fragment.
Is this the proper way to add a Fragment with TabLayout inside?
Is there a way to remove the shadow of toolbar only in this case?
I have solution, but not elegant. Simply remove elevation from toolbar in onViewCreated() and set it back in onDestroyView().
private Toolbar toolbar;
private float toolbarElevation;
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
toolbar = getActivity().findViewById(R.id.toolbar);
toolbarElevation = toolbar.getElevation();
toolbar.setElevation(0);
}
}
#Override
public void onDestroyView() {
super.onDestroyView();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
toolbar.setElevation(toolbarElevation);
}
}

Toolbar not being shown in child activity

I am working on having a single navigation drawer for all the activities, so I thought to add it in BaseActivity and then inherit it in other activities wherever I need the navigation drawer and I did indeed succeed in getting the navigation drawer working but for some reason the toolbar is not being displayed in the child activities that inherit the BaseActivity, The I tried a lot things and checkout lot of questions on stack overflow but I could not really figure out what is the issue.
Here is the code: layout file
activity_base.xml
<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/DrawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:elevation="7dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<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="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
</LinearLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/RecyclerView"
android:layout_width="320dp"
android:layout_height="match_parent"
android:layout_gravity="left"
android:background="#ffffff"
android:scrollbars="vertical">
</android.support.v7.widget.RecyclerView>
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.DrawerLayout>
I am using this layout file here in onCreate of BaseActivity:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mRecyclerView = (RecyclerView) findViewById(R.id.RecyclerView); mRecyclerView.setHasFixedSize(true); // Letting the system know that the list objects are of fixed size
mAdapter = new NavigationFragmentAdapter(TITLES,ICONS,NAME,EMAIL,PROFILE); // Creating the Adapter of MyAdapter class(which we are going to see in a bit)
// And passing the titles,icons,header view name, header view email,
// and header view profile picture
mRecyclerView.setAdapter(mAdapter); // Setting the adapter to RecyclerView
mLayoutManager = new LinearLayoutManager(this); // Creating a layout Manager
mRecyclerView.setLayoutManager(mLayoutManager); // Setting the layout Manager
Drawer = (DrawerLayout) findViewById(R.id.DrawerLayout); // Drawer object Assigned to the view
mDrawerToggle = new ActionBarDrawerToggle(this,Drawer,toolbar,R.string.drawer_open,R.string.drawer_close){
#Override
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
// code here will execute once the drawer is opened( As I dont want anything happened whe drawer is
// open I am not going to put anything here)
}
#Override
public void onDrawerClosed(View drawerView) {
super.onDrawerClosed(drawerView);
// Code here will execute once drawer is closed
}
}; // Drawer Toggle Object Made
Drawer.setDrawerListener(mDrawerToggle); // Drawer Listener set to the Drawer toggle
mDrawerToggle.syncState(); // Finally we set the drawer toggle sync State
}
Then I am inheriting this activity in other child activity (HomeActivity):
public class HomeActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_home);
ViewGroup content = (ViewGroup) findViewById(R.id.content_frame);
getLayoutInflater().inflate(R.layout.activity_home, content, true);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
The xml file for HomeActivity:
<LinearLayout 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/home_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="app.packman.activity.HomeActivity">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.design.widget.TabLayout
android:id="#+id/home_tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<include layout="#layout/content_home" />
<!-- other content of activity-->
</android.support.design.widget.CoordinatorLayout>
the output screenshot of HomeActivity which has no toolbar (which is the problem I am facing):
Any suggestions will of great help
You can try add
app:layout_behavior="#string/appbar_scrolling_view_behavior"
in your FrameLayout

Inflating AppBarLayout with Toolbar + TabLayout

I currently have a DrawerLayout in my main.xml. There's a Toolbar wrapped in an AppBarLayout, and then a simple LinearLayout to swap out fragments.
One of the fragments I navigate to, I want it to contain a TabLayout for a ViewPager of fragments. Currently, I have both of these in the fragment's layout file, but this causes a drop shadow to appear between the Toolbar and the TabLayout, which is something I don't want. I also don't want to use setElevation() because it won't work for pre-Lollipop devices.
A possible solution would be to inflate the AppBarLayout from my fragment, so that it holds both the Toolbar+Tabs. However, I'm not really sure how to do this, so any help would be appreciated.
Here is my main.xml file:
<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/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.lumivote.lumivote.ui.MainActivity">
<android.support.design.widget.CoordinatorLayout
android:id="#+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/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:background="?attr/colorPrimary"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
</android.support.design.widget.AppBarLayout>
<LinearLayout
android:id="#+id/flContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
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"
app:headerLayout="#layout/nav_header"
app:itemIconTint="#333"
app:itemTextColor="#333"
app:menu="#menu/navigation_drawer_items" />
</android.support.v4.widget.DrawerLayout>
And here is my fragment's xml file:
<LinearLayout 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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.alexdao.democracy.ui.candidate_tab.CandidateListFragment">
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/myPrimaryColor"
app:tabMode="fixed"
app:tabGravity="fill"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white" />
</LinearLayout>
You are able to have separate toolbar for each fragment. Its possible to set fragments toolbar as activity actionbar. Example code:
Toolbar toolbar = (Toolbar) v.findViewById(R.id.toolbar);
((AppCompatActivity) getActivity()).setSupportActionBar(toolbar);
It should be possible to have titles, icons and other stuff as well.
With it you can mimic shadow on pre lollipop devices, no matter what you have on them.
I modified the solution given by bleeding182 and got it to work for AppBarLayout as well (to resolve the problem pointed out by bopa).
#Override
public void onAttach(Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getActivity().findViewById(R.id.appbar).setElevation(0);
}
super.onAttach(context);
}
#Override
public void onDetach() {
super.onDetach();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getActivity().findViewById(R.id.appbar).setElevation(R.dimen.toolbar_elevation);
}
}
What I did was replace the call to getSupportActionBar() by giving an ID to my AppBarLayout and then calling findViewById() on it and then calling setElevation on its result. Tested on API 23.
I had a similar issue where I wanted a TabLayout just inside of one fragment.
Without changing any other code you can solve this by using onAttach and onDetach inside your fragment with the TabLayout.
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// todo add some further checks, e.g. instanceof, actionbar != null
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
((AppCompatActivity) activity).getSupportActionBar().setElevation(0);
}
}
#Override
public void onDetach() {
super.onDetach();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
((AppCompatActivity) getActivity()).getSupportActionBar()
.setElevation(getResources().getDimension(R.dimen.toolbar_elevation));
}
}
Be sure to set the same elevation on your TabLayout and everything works fine! ;D
You can simply add TabLayout programmatically from Fragment in wich you need TabLayout
tabLayout = (TabLayout) inflater.inflate(R.layout.tablay, null);
appBarLayout = (AppBarLayout) getActivity().findViewById(R.id.appbar);
appBarLayout.addView(tabLayout, new LinearLayoutCompat.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
and remove TabLayout from AppBar in onDetach()
#Override
public void onDetach() {
appBarLayout.removeView(tabLayout);
super.onDetach();
}
To fix my problem I ended up putting the Toolbar, TabLayout, and ViewPager all in my MainActivity.
main_activity.xml:
<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/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.CoordinatorLayout
android:id="#+id/rootLayout"
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:background="?attr/colorPrimary"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/white" />
</android.support.design.widget.AppBarLayout>
<RelativeLayout
android:id="#+id/flContent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
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"
app:headerLayout="#layout/nav_header"
app:itemIconTint="#333"
app:itemTextColor="#333"
app:menu="#menu/navigation_drawer_items" />
</android.support.v4.widget.DrawerLayout>
Then, in all of my fragments, I set the visibility for the TabLayout and the ViewPager programmatically in onCreateView:
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
TabLayout tabLayout = (TabLayout) getActivity().findViewById(R.id.tabLayout);
tabLayout.setVisibility(View.GONE);
ViewPager mViewPager = (ViewPager) getActivity().findViewById(R.id.viewpager);
mViewPager.setVisibility(View.GONE);
return inflater.inflate(R.layout.fragment_layout, container, false);
}
Of course, in the fragment with tabs, you would want to set the visibility to View.VISIBLE instead of View.GONE.
The Artem_lens approach worked for me with some modifications.
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
...
mTabLayout = (TabLayout) inflater.inflate(
R.layout.partial_tab_layout,
container,
false);
mAppBarLayout = (AppBarLayout) getActivity().findViewById(R.id.app_bar);
mAppBarLayout.addView(mTabLayout,
new LinearLayoutCompat.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
...
}
And removing the view at onDestroyView()
#Override
public void onDestroyView() {
mAppBarLayout.removeView(mTabLayout);
super.onDestroyView();
}
The solution is simple in the XML. Just add the following code to your AppBarLayout: app:elevation="0dp". So the AppBarLayout should look like this:
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp"
android:theme="#style/AppTheme.AppBarOverlay">

Toolbar buttons don't respond to touch when a Navigation Drawer is open

I'm working on a material design version of my app using the appcompat v7 libraries, and I've hit an issue with the navigation drawer. When it opens, buttons in the material design toolbar cease to function - any touch outside the navigation drawer just closes the drawer. A following is a gif of what I mean
Here is the xml layout I'm using for the activity:
<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">
<!-- The main content view -->
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
android:id="#+id/action_toolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:elevation="4dp"
/>
<FrameLayout
android:id="#+id/note_list_container"
android:layout_marginTop="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<net.rymate.notes.ui.FloatingActionButton
android:id="#+id/fabbutton"
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_gravity="bottom|right"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp" />
</FrameLayout>
<!-- The navigation drawer -->
<LinearLayout
android:id="#+id/left_drawer"
android:layout_width="300dp"
android:layout_marginTop="?attr/actionBarSize"
android:layout_height="match_parent"
android:layout_gravity="start"
android:orientation="vertical">
<ListView
android:id="#+id/cat_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="?catBackColour" />
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
And here is the onCreate code that initialises the drawer and the toolbar.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ROBOTO_LIGHT = Typeface.createFromAsset(this.getAssets(), "Roboto-Light.ttf");
ROBOTO_LIGHT_ITALICS = Typeface.createFromAsset(this.getAssets(), "Roboto-LightItalic.ttf");
setContentView(R.layout.activity_notes);
if (findViewById(R.id.note_container) != null) {
// The detail container view will be present only in the
// large-screen layouts (res/values-large and
// res/values-sw600dp). If this view is present, then the
// activity should be in two-pane mode.
mTwoPane = true;
// In two-pane mode, list items should be given the
// 'activated' state when touched.
FragmentManager fm = getSupportFragmentManager();
//list.setActivateOnItemClick(true);
}
if (!mTwoPane) {
final FloatingActionButton mFab = (FloatingActionButton) findViewById(R.id.fabbutton);
mFab.init(Color.parseColor("#1e90ff"));
mFab.setFabDrawable(getResources().getDrawable(R.drawable.ic_action_new));
mFab.showFab();
mFab.setOnClickListener(this);
list = new NotesListFragment(mFab);
} else {
list = new NotesListFragment();
}
Toolbar toolbar = (Toolbar) findViewById(R.id.action_toolbar);
setSupportActionBar(toolbar);
getSupportFragmentManager().beginTransaction()
.replace(R.id.note_list_container, list)
.commit();
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); // the layout
mDrawerLinear = (LinearLayout) findViewById(R.id.left_drawer);
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
mDrawerLayout.setScrimColor(getResources().getColor(android.R.color.transparent));
mDrawerToggle = new ActionBarDrawerToggle(
this, /* host Activity */
mDrawerLayout, /* DrawerLayout object */
toolbar, /* toolbar */
R.string.drawer_open, /* "open drawer" description */
R.string.drawer_close /* "close drawer" description */
) {
/** Called when a drawer has settled in a completely closed state. */
public void onDrawerClosed(View view) {
getSupportActionBar().setTitle("Rymate Notes");
supportInvalidateOptionsMenu();
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
getSupportActionBar().setTitle("Categories");
supportInvalidateOptionsMenu();
}
};
// Set the drawer toggle as the DrawerListener
mDrawerLayout.setDrawerListener(mDrawerToggle);
pref = getSharedPreferences("rymatenotesprefs", MODE_PRIVATE);
mDrawerList = (ListView) findViewById(R.id.cat_list);
mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
mDbHelper = new NotesDbAdapter(this);
mDbHelper.open();
if (mDbHelper.fetchAllNotes().getCount() == 0) {
IntroFragment fragment = new IntroFragment();
getSupportFragmentManager().beginTransaction()
.replace(R.id.note_list_container, fragment)
.commit();
}
getCategories(); // calls a function which populates the listview
}
Is there a way to possibly fix this?
Seems that touch event is stolen by the shadow of the drawer, i.e DrawerLayout keeps intercepting the touch events, because Toolbar is part of the content view, unlike the ActionBar being on top of the decor view.
Possible work around is intercepting the touch event:
If it s between 0 (top) and Toolbar height (bottom), dispatch the event directly to the Toolbar object. Otherwise keep the normal behaviour.
Is same case for drawer toggle clicks?
Turns out Nikola Despotoski had the right idea - the touch event was stolen by the DrawerLayout. However instead of intercepting the touch event I just adjusted the activity layout like so:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<android.support.v7.widget.Toolbar
android:id="#+id/action_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:minHeight="?attr/actionBarSize"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize" >
<!-- The main content view -->
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/note_list_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<net.rymate.notes.ui.FloatingActionButton
android:id="#+id/fabbutton"
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_gravity="bottom|right"
android:layout_marginBottom="16dp"
android:layout_marginRight="16dp" />
</FrameLayout>
<!-- The navigation drawer -->
<LinearLayout
android:id="#+id/left_drawer"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:orientation="vertical">
<ListView
android:id="#+id/cat_list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?catBackColour"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp" />
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
</FrameLayout>
This has the intended effect of allowing touch events to be registered by the Toolbar rather than the DrawerLayout.

Categories

Resources