Android Toolbar not showing when no layout_below in XML - android

I have a weird issue concerning the Android Toolbar in Samsung Galaxy Tab 4. Maybe it's the OS (4.4.2) or the device itself.
I am using the AppCompat-v7:23 library to display a Toolbar for pre-Lollipop devices.
Here is the XML code of my Activity where the Toolbar is displayed:
<LinearLayout 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"
android:fitsSystemWindows="true">
<include
layout="#layout/appbar_content_top"
android:layout_width="match_parent"
android:layout_height="match_parent" />
And here is appbar_content_top:
<FrameLayout 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=".CEMainActivity">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar_layout"
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:layout_alignParentTop="true"
android:background="?attr/colorPrimary"
app:popupTheme="#style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
As you can see, I did not put an android:layout_below attribute for #+id/content. That is one of my requirement. In my Activity, I get the Toolbar and set it as my supportActionToolbar.
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
Log.e("Viewer", "Toolbar is not null");
} else {
Log.e("Viewer", "Toolbar is null");
}
The Toolbar displays for other devices. But in Galaxy Tab 4, the Toolbar is not displayed, even though the snippet above says that the Toolbar is not null.
Weirdly, if I add an android:layout_below attribute to #+id/content, the Toolbar will show in the Galaxy Tab 4.
Any clues on why this could be happening?? Thanks!

Since you are using appbarlayout, use coordinator layout instead of Framelayout as the main viewgroup of appbar_content_top.xml, coordinator act the same way as framelayout, just think of it as a super framelayout ;) and one more thing layout_below work properly with relativelayout only as the parent viewgroup

Related

Toolbar not displaying from inside collapsing toolbar

Here is the code.
<?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"
android:id="#+id/main"
android:layout_height="match_parent"
android:layout_width="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="100dp">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|enterAlways|exitUntilCollapsed">
<android.support.v7.widget.Toolbar
android:id="#+id/mytoolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:title="#string/app_name"
app:layout_collapseMode="pin"
app:theme="#style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
android:id="#+id/main_tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:layout_collapseMode="none"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<!--<android.support.v4.widget.NestedScrollView-->
<!--android:id="#+id/nestedscroll"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="match_parent"-->
<!--android:fillViewport="true"-->
<!--android:scrollbars="horizontal"-->
<!--app:layout_behavior="#string/appbar_scrolling_view_behavior">-->
<android.support.v4.view.ViewPager
android:id="#+id/main_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
<!--</android.support.v4.widget.NestedScrollView>-->
<android.support.design.widget.FloatingActionButton
android:id="#+id/main_fab"
android:layout_margin="16dp"
android:src="#android:drawable/ic_media_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_anchor="#id/main_viewpager"
app:layout_anchorGravity="bottom|end"/>
</android.support.design.widget.CoordinatorLayout>
The problem:
1) Toolbar is not visible.
2) Collapsing toolbar doesn't collapse at all. [Solved]
3) Viewpager and FAB also not visible if put inside nestedScrollView. [Solved]
Extra detail:
Layout for fragments of Viewpager have Linearlayout as root and inside that have a recyclerview.
Everything seems to be alright as per the code. Unable to understand what is missing. A good explanation of how coordinator layout and collapsing toolbar work together would also indeed help.
1) Toolbar is not visible.
First of all you need define what Toolbar do you want to use in your activity class:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Change existing xml code:
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:title="#string/app_name"
app:layout_collapseMode="parallax">
</android.support.v7.widget.Toolbar>
to:
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" //set initial height
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" //this might be also useful
app:title="#string/app_name"
app:layout_collapseMode="parallax" />
2) Collapsing toolbar doesn't collapse at all.
Did your activity using correct theme. Set to your AppBarLayout:
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
as in this example: include_list_viewpager.xml
3) Viewpager and FAB also not visible if put inside nestedScrollView.
There's no reason to do that. Adding these lines:
android:layout_marginTop="?attr/actionBarSize"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
to ViewPager should be enough.
Both of them should be direct children of CoordinatorLayout.
Follow this example: http://blog.nkdroidsolutions.com/collapsing-toolbar-with-tabs-android-example/
If you're new to Material Design or feel a bit lost with some its behaviours, I highly recommend to check Chris Banes Material Design project cheesequare: https://github.com/chrisbanes/cheesesquare/
Hope it will help
First of all you should tell your activity that what toolbar you are using, so in onCreate method you should have:
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
your second and third problem should solve together. You should use NestedScrollView as the main layout for fragments inside ViewPager and then inside that, put your LinearLayout or anything else.

View jumps and blinks instantly, though animateLayoutChanges="true"

I am making my TabLayout animated by using android:animateLayoutChanges="true" in AppBarLayout. But when I set TabLayout.setVisibility(View.GONE), container for my fragment goes up to ActionBar instantly for a few milliseconds. And then it returns to the end of TabLayout and goes up with it to the ActionBar. I explained this on following gif.
The buttons Theory and Practice are behind the TabLayout for some reason but when hiding TabLayout animation starts FrameContainer that holds my view sticks to the bottom of TabLayout.
I have recorded a video that demostrates this behavior. Dropbox video player skip some frames and animation seems nice. Thats why, to notice the bug, you can load video on computer and watch 5 and 11 second in high quality. Video
My LayoutXML:
<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:orientation="vertical">
<SurfaceView
android:layout_width="0px"
android:layout_height="0px"/>
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:visibility="gone"
app:tabGravity="fill"
app:tabIndicatorColor="#android:color/white"
app:tabMode="fixed"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<!--
This FrameLayout holds my fragments.
-->
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/outer_background">
<ProgressBar
android:id="#+id/main_load_progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:indeterminate="true"/>
</FrameLayout>
<include
android:id="#+id/left_drawer_full"
layout="#layout/navigation_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"/>
</android.support.v4.widget.DrawerLayout>
</android.support.design.widget.CoordinatorLayout>
In addition I am using 23.2.1 support libraries.
How can I fix this blinks and jumps?
Try adding android:animateLayoutChanges="true" to your view with
app:layout_behavior="#string/appbar_scrolling_view_behavior
so that would be your DrawerLayout. Then enable Transition Type LayoutTransition.CHANGING on it like so:
ViewGroup layout = (ViewGroup) findViewById(R.id. drawer_layout);
LayoutTransition layoutTransition = layout.getLayoutTransition();
layoutTransition.enableTransitionType(LayoutTransition.CHANGING);
related: https://stackoverflow.com/a/22573099/1363742
I wasted all day to investigate this problem.
And I have found one possible solution for this problem.
Now i change visibility by this code
mTabLayout.postDelayed(new Runnable() {
#Override
public void run() {
switch (newMode) {
case MODE_CONTENTS:
mTabLayout.setVisibility(mContents.isTheoryAvailable() ? View.VISIBLE : View.GONE);
break;
default:
findViewById(R.id.content_frame).setVisibility(View.INVISIBLE);
mTabLayout.setVisibility(View.GONE);
findViewById(R.id.content_frame).setVisibility(View.VISIBLE);
}
}
}, 200);
It works well and views are not blinking now. But on old androids the bug is still presents.

How to add a TabView beneath AppBar without shadow

In my application I have an issue where I want to have high level navigational control from a navigation drawer, and page level control within a TabLayout within a fragment. This however causes issues with the shadow rendering from the AppBar onto the fragment.
Here's the basics of what my layouts and code does. At the root I have this simple 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" android:fitsSystemWindows="true"
tools:context=".MainAppActivity">
<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>
<include layout="#layout/content_main" />
</android.support.design.widget.CoordinatorLayout>
When my navigation drawer is selected I inflate the fragment into "content_main"
this.getSupportFragmentManager()
.beginTransaction()
.addToBackStack(tag)
.replace(R.id.content_main_layout, fragment, tag)
.commit();
The fragment being put into content_main contains a layout with my TabView and a view pager:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_github_issues"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<android.support.design.widget.TabLayout
android:id="#+id/github_issues_tab_layout"
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
android:layout_gravity="top"
android:background="?attr/colorPrimary"
android:theme="#style/AppTheme.AppBarOverlay"/>
<android.support.v4.view.ViewPager
android:id="#+id/github_issues_viewpager"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>
What's the a good best practice to fix the issue? Is including TabLayout to live within the top level AppBar and just disabling the view based on the page an acceptable implementation?
First you need to change the view hierarchy to something like this:
FrameLayout
-CoordinatorLayout -> content
-Toolbar
Fix Toolbar elevation to be exact with the AppBarLayout, too get rid of the shadow but keep the z-order of the Toolbar:
int appBarLayoutElevation = ViewCompat.getElevation(mAppBarLayout);
getActivity().getSupportActionBar().setElevation(appBarLayout);
Similar example I have worked in my blog post.

Content behind CoordinatorLayout AppBarLayout

I was creating a settings activity/layout for my app. I have a CoordinatorLayout with an AppBarLayout and Toolbar, then beneath that it includes content_settings.xml. When the content loads the .xml file is behind the app bar.
I'm using this same setup to load the main content and it works fine, but for some reason isn't rendering correctly within the Settings section.
activity_settings.xml
<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>
<include layout="#layout/content_setting" />
The content_settings.xml is just a FrameLayout that is replaced by a PreferenceFragment
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/settings_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
add this to your Recyclerview :
app:layout_behavior="#string/appbar_scrolling_view_behavior"
In my case the view under the toolbar wasn't scrollable so even though the accepted answer did stop the overlapping it pushed the content down by the height of the toolbar, pushing elements offscreen.
The solution in this case was to also remove the
app:layout_scrollFlags
from the Toolbar that I was including/sharing with other layouts that had scrolling views.

Overlaying content above AppBarLayout using new Material Design

I want to achieve something like that. (not the FAB or the Snackbar). How can i create a layout, overlaying the AppBarLayout? Like this! (For Example)
Like Play Store:
My AppBarLayout with CoordinatorLayout and NestedScrollView with RelativeLayout as content looks like this:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/rootLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="#dimen/_118sdp"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsingToolbarLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentScrim="#color/mpc_pink"
app:expandedTitleMarginStart="#dimen/_40sdp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<de.mypostcardstore.widgets.ItemImageView
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:src="#color/mpc_pink"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="0.7" />
<android.support.v7.widget.Toolbar
android:id="#+id/article_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:minHeight="?attr/actionBarSize"
app:contentScrim="#color/mpc_pink"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar" />
</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"
android:background="?android:colorBackground"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<RelativeLayout
android:layout_width="match_parent".....>
It would be awesome if someone could help me out. I can not find anything on the internet...
Thanks in advance!
Just add something like
app:behavior_overlapTop="64dp"
to your NestedScrollView and it will be placed above the expanded toolbar.
In addition, you should add something like
app:expandedTitleMarginBottom="70dp"
to your CollapsingToolbarLayout so the title does not appear under your overlaid scroll content.
It's quite simple, really. You could achieve that by using a combination of ToolBar, FrameLayout, and your content view (could be a ListView like your first example, or anything).
The idea is to make your FrameLayout possess the same color as your ToolBar, giving the illusion of ToolBar being much larger than it is. Then all that is left to do is to make your content view be the last (or in API 21 and above: possess the highest elevation attribute) so that it would appear as if it floats above the aforementioned FrameLayout.
See my illustration below:
Now that you got the big idea, below is some real live XML snippet for doing such thing. (I actually use this layout in one of my apps) :
<!-- Somewhere in your layout.xml -->
....
<android.support.v7.widget.Toolbar
android:id="#+id/tb_toolbar"
android:layout_width="match_parent"
android:layout_height="#dimen/abc_action_bar_default_height_material"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:contentInsetStart="72dp"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<!-- This is the 'faux' ToolBar I've been telling you about. This is the part that will be overlaid by the content view below. -->
<FrameLayout
android:id="#+id/v_toolbar_extension"
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_below="#+id/tb_toolbar"
android:background="?attr/colorPrimary"
android:elevation="2dp"/>
<!-- Normally, I use this FrameLayout as a base for inflating my fragments. You could just use put your content view here. -->
<FrameLayout
android:id="#+id/ly_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/tb_toolbar"
android:elevation="3dp"/>
....
Note that my ly_content has higher elevation value than that of v_toolbar_extension. This is what will give you that desired 'overlaid toolbar' effect.
Last but not least, you would want to add this line somewhere in your activity's onCreate() :
/* Assuming mToolbar exists as a reference to your ToolBar in XML. */
setSupportActionBar(mTbToolbar);
getSupportActionBar().setElevation(0);
What that codes woud do is to set your ToolBar elevation to zero; removing preset shadows that were given as a default to ToolBars. If you don't do this, said shadow will create a "seam" between your ToolBar and your FrameLayout, thus breaking the illusion of those two being the same.
p.s., It is also important to give your content view a padding on each side. Doing so, your content view will not cover the entire width of the screen (which would render this effect useless).
Note: I see some good answers here that mentioned the absence of FrameLayout and instead making the ToolBar taller. While in theory it might work as well as my proposed solution, you might have problems when trying to manipulate scrolling; by doing that, you won't be able to separate ToolBar and its extension. You'll be forced to either make the Toolbar static or scroll all of the ToolBar altogether (makes scrolling a bit weird).
Add to that, the fact that you can't easily assign a custom drawable into a Toolbar. Hence makes it hard to follow the Google Play example you've given above. While if you're using my solution, all you'd need to do is just make your Toolbar transparent and assign the drawable to the FrameLayout instead.
I had a similar requirement and I achieved it as below.
Your activity theme should extend Theme.AppCompat.Light.NoActionBar.
I created a Layout XML File as:
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_main"
android:layout_width="match_parent"
android:layout_height="#dimen/action_bar_size_x2"
android:background="#color/colorPrimary"
android:minHeight="?attr/actionBarSize" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:layout_marginTop="#dimen/action_bar_size"
android:orientation="vertical" >
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:text="#string/app_name"
android:textSize="24sp" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
And the Activity should be something like this:
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar maintoolbar = (Toolbar) findViewById(R.id.toolbar_main);
setSupportActionBar(maintoolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
}
I got a view like this :
I did try to implement effects like you referred which is called Card Toolbar in Android, and it did work as expected. Here is my layout, Take a look at it:
<FrameLayout 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:background="#color/background_material_light" >
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="#dimen/toolbar_double_height"
android:background="?attr/colorPrimary" />
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="#dimen/cardview_toolbar_spacer"
android:layout_marginRight="#dimen/cardview_toolbar_spacer"
android:layout_marginTop="?attr/actionBarSize"
app:cardBackgroundColor="#android:color/white">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:alpha="0.12"
android:background="#android:color/black" />
</LinearLayout>
</android.support.v7.widget.CardView>
</FrameLayout>
Hope you'll be inspired.

Categories

Resources