I have the following main page layout in my app:
<?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:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="#+id/mainPager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/app_bar_scrolling_view_behavior">
</android.support.v4.view.ViewPager>
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/actionToolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:title="#string/app_name"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways">
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:layout_scrollFlags="scroll|enterAlways">
</android.support.design.widget.TabLayout>
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
The scrollable content is the ViewPager. I use the ViewPager in conjunction with the TabLayout:
ViewPager viewPager = (ViewPager) v.findViewById(R.id.mainPager);
TabLayout tabLayout = (TabLayout) v.findViewById(R.id.tabLayout);
tabLayout.setupWithViewPager(viewPager);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
All fragments in the ViewPager's adapter has a RecyclerView inside.
When i first scroll up the RecyclerView's content (so that app bar is hidden), then switch to another page of data in the ViewPager and scroll RecyclerView's content down, the app bar is ... invisible.
The main steps leading to this problem:
running on devices with api level 11 or higher (on devices with api level less than 11 all is ok);
Scrolling content up;
Switching to another ViewPager's page;
Scrolling content down to make app bar visible;
app bar is invisible.
Where is my problem? Thanks.
EDIT1: Fragment's toolbar initialization
Toolbar toolbar = (Toolbar) view.findViewById(R.id.actionToolbar);
toolbar.setTitle(toolbarTitleResId);
toolbar.inflateMenu(menuResId);
toolbar.setOnMenuItemClickListener(listener);
EDIT2: Fragment's layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/actionToolbar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_alignParentTop="true"
android:minHeight="?attr/actionBarSize"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
android:background="?attr/colorPrimary">
</android.support.v7.widget.Toolbar>
<View
android:id="#+id/anchor"
android:layout_height="8dp"
android:layout_width="match_parent"
android:background="#drawable/shadow_gradient_drawable"
android:layout_below="#+id/actionToolbar">
</View>
<android.support.v7.widget.RecyclerView
android:id="#+id/verticalRecyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/anchor"/>
</RelativeLayout>
I was able to reproduce this on my API 16 device (still no issues on API 22). This is definitely a bug in the AppBarLayout, however, there is a quick work around. This is only an issue when the AppBarLayout becomes completely hidden. Add a view with 1dp height to the AppBarLayout and everything should work without really being noticeable on the view.
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<!-- Toolbar and tab bar code -->
...
<!-- Add this -->
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#color/colorPrimary" />
</android.support.design.widget.AppBarLayout>
We can also apply this solution for Switching to another ViewPager's page
appBarLayout.setExpanded(true, true);
Here 2nd parameter If it is true it AppBarLayout will expand with animation.
Related
I have a Toolbar and a TabLayout at the top of the screen, with a ViewPager below. The ViewPager shows a different fragment for each tab, but each of those fragments is essentially just a RelativeLayout with a ListView inside it.
I want to make it such that when the ListView is scrolled down, the Toolbar will hide itself (moves out of sight towards the top of screen), and when it is scrolled up, the Toolbar will appear again.
I tried following a few guides, but it doesn't seem to be working. Not to mention that everything I can find about this is either outdated or uses a RecyclerView just below the AppBarLayout. I need a ViewPager for the tabs, so I can't have a RecylerView there.
I'm using API level 30, and I'm testing on an emulated Pixel 2.
This is what my XML looks like:
<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.support.design.widget.AppBarLayout android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="enterAlways">
<android.support.v7.widget.Toolbar android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize">
<TextView android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"/>
</android.support.v7.widget.Toolbar>
<android.support.design.widget.TabLayout android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="32dp"
android:layout_below="#id/title"
android:layout_marginBottom="4dp"
app:tabMinWidth="96dp"
app:tabIndicatorHeight="4dp"
app:tabIndicatorFullWidth="false"
app:tabMode="scrollable">
<android.support.design.widget.TabItem android:text="#string/tab_1"/>
<android.support.design.widget.TabItem android:text="#string/tab_2"/>
<android.support.design.widget.TabItem android:text="#string/tab_3"/>
</android.support.design.widget.TabLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/appbar"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
Any help would be appreciated, thanks.
I have a TabLayout that I'm using along with AppBarLayout, ToolBar, and ViewPager in order to have scrollable tabs. At the moment, I have a single tab, but rather than being left aligned the tab is centered.
<?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: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: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.Light" />
<android.support.design.widget.TabLayout
android:id="#+id/tablayout"
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>
Set your TabLayout attributes to:
app:tabGravity="center"
app:tabMode="scrollable"
hope this help.
Try using the XML attribute set
android:layout_gravity="left"
This is all that I could find on this topic it is documented
that set layout_gravity is a value for a tabbed layout.
More documentation here. And here
Just change TabLayout widhth to wrap_content... that will make that single tab to be left aligned
I have a TabLayout that I want always pinned to the top, and a Toolbar below that, that when the view is scrolled, scrolls up into the TabLayout.
<android.support.design.widget.CoordinatorLayout
android:id="#+id/main_content"
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=".main.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:animateLayoutChanges="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"/>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/imageView2"
android:src="#drawable/music_content"
android:contentDescription="#string/image_chooser_title"
/>
</android.support.v4.widget.NestedScrollView>
</android.support.design.widget.CoordinatorLayout>
You can see here that I've set the Toolbar
app:layout_scrollFlags="scroll|enterAlways"
and not set any scrolling flags for the TabLayout above, since I want it to remain pinned. However, using these settings, the AppBarLayout doesn't scroll at all. If I add a scroll flag to the TabLayout, then they both scroll, and the TabLayout doesn't remain fixed. Is there a way to have the TabLayout remain fixed, while the Toolbar below scrolls up "off screen?"
Pictures can be provided if needed
As per the Android Design Support Library blog post:
One note: all views using the scroll flag must be declared before views that do not use the flag. This ensures that all views exit from the top, leaving the fixed elements behind.
So what you want is not possible with AppBarLayout.
I've an Activity with an NavigationDrawer and a Toolbar. I'm facing a problem when i want disappear a toobar when one of child fragment view is scrolled. Everything works fine except that there is some view coming up from the bottom which has the exact same size as the toolbar that is disappearing.
I made an GIF Animation that shows the problem. Due to my reputation i can not post the image directly but this gif and this gif shows the problem
I tried to figure out where this is coming from. It seems that its from my container FrameLayout where my fragment views are placed during runtime. I changed its background to green so i can identify it.
<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" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<include
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways"
layout="#layout/toolbar" />
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/darkGreen"
tools:context="org.cddevlib.breathe.MainActivity" />
</LinearLayout>
<fragment
android:id="#+id/navigation_drawer"
android:name="org.cddevlib.breathe.NavigationDrawerFragment"
android:layout_width="#dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
tools:layout="#layout/fragment_navigation_drawer" /> </android.support.v4.widget.DrawerLayout>
This is the Toolbars Layout that is included
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways"
android:fitsSystemWindows="true"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light">
</android.support.v7.widget.Toolbar>
And finally a snippet from the fragments view that is loaded:
<android.support.design.widget.AppBarLayout
android:id="#+id/appBarLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/black" >
<include
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways"
layout="#layout/toolbar" />
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/scrollView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:background="#color/white"
android:fillViewport="true" >
(...)
Note that i'm including the Toolbar again in that layout because i want different Toolbars for each fragment in my application by hiding / adding the toolbar.
toolbar = (Toolbar) ((View) vw).findViewById(R.id.toolbar);
if (toolbar != null) {
// // for crate home button
activity = (AppCompatActivity) getActivity();
activity.getSupportActionBar().hide();
toolbar.setBackgroundDrawable(new ColorDrawable((ColorUtils.getColorDark(DataModule.getInstance()
.getMainActivity()))));
activity.setSupportActionBar(toolbar);
activity.getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
SOLUTION
So thanks to sanat shukla answer is firgured out that my problem was that i used an AppBarLayout too much in my fragments view. In my fragments view, AppBarLayout was the main layout for all of my components, but it should not! Its intended to hold the toolbar content! Thanks
It's not an issue. It is the cool animation and support provided by android. When you use co-ordinator layout with Toolbar then it shows cool animation when scrolling the list.
The Design library takes this to the next level: using an AppBarLayout
allows your Toolbar and other views (such as tabs provided by
TabLayout) to react to scroll events in a sibling view marked with a
ScrollingViewBehavior
Read from here :
http://android-developers.blogspot.in/2015/05/android-design-support-library.html
If you don't want to hide your toolbar then don't use co-ordinator layout and appbar with toolbar.
Try this for fragment :
<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">
<! -- Your Scrollable View -->
<android.support.v4.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/scrollView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:background="#color/white"
android:fillViewport="true" >
<android.support.v4.widget.NestedScrollView/>
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways"
layout="#layout/toolbar" />
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
I am using the new TabLayout introduced in the design support library. I have the code like this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent">
<android.support.design.widget.CoordinatorLayout
android:id="#+id/lines_coordinator"
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: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:elevation="4dp"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.design.widget.CoordinatorLayout>
</LinearLayout>
The problem is, that the tabs overlap the top of the content the fragments display. How can I fix this? I am using the TabLayout like in the examples on Github, so I believe there is no issue with my code. I already have a Toolbar because I use the tabs in a fragment in a navigation drawer, so I removed it from the AppBarLayout.
You need to add app:layout_behavior="#string/appbar_scrolling_view_behavior" to your ViewPager: this is what changes the height of the View to be below the AppBarLayout rather than the full match_parent height.