How to have an anchored view inside a ScrollView? - android

everyone. I'm doing an android app and I'm trying to replicate some of the facebook messenger behaviors. My activity has a coordinatorlayout, inside a tableyout and a viewpager. It's working fine but in a fragment I have a recyclerview inside a nestedscrollerview. Specifically some views, a textview then the recyclerview, I'd like that when scrolling down when it reaches the text above the reyclerview, this text stays anchored in the top and it never gets hidden by the nestedscrollview. Just like the facebook messenger app, like this:
facebook1
facebook2
I thought about having a hidden textview outside of the nestedscrollview that becomes visible when the scrollview reaches the other textview, so it looks anchored but I wanted to know if there is a better way of doing this. Thank you.
Here's a simplified version of the code:
Activity's layout:
<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="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/tool_bar"
android:layout_width="match_parent"
layout="#layout/tool_bar"
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/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"/>
</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" />
Fragment Layout:
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="30dp"
android:background="#color/background">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="25dp">
<TextView ..../>
<TextView ..../>
<!-- I need this textview to be anchored when it's reached by the scrollview -->
<TextView
android:id="#+id/anchored_textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent"
android:divider="#android:color/darker_gray"
android:dividerHeight="0.2dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>

Related

Hide toolbar on scroll and keep it hidden unless on far top

I am using the following code to hide my toolbar when I scroll on my main activity and it works perfectly. Though, I want to change its behavior a little:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/coordinatorLayout"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbarsdfs"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"/>
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:scrollbars="horizontal"
android:layout_below="#+id/toolbarsdfs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
app:tabTextColor="#android:color/white"
app:tabSelectedTextColor="#android:color/white"
app:tabIndicatorColor="#android:color/white"
app:tabIndicatorHeight="3dp" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/pager"
android:layout_width="match_parent"
android:layout_height="fill_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_below="#+id/tablayout"/>
</android.support.design.widget.CoordinatorLayout>
I want the toolbar to only show when the user reaches the far top of the view. I have a recyclerview that has a lot of rows. I want the user to be able to go up and down without being bothered by the toolbar unless he reaches the very top of the view. How can this be done? Thanks.
Edit: edited the code.
in content_main.XML use android.support.v4.widget.NestedScrollView instead of ScrollView.
also use app:layout_behavior="#string/appbar_scrolling_view_behavior" inside android.support.v4.widget.NestedScrollView like below.
<android.support.v4.widget.NestedScrollView
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/textone"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="hello world"
android:textSize="25dp"
android:textStyle="bold" />
/// Add your other code here
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
reference from hear : How to hide ToolBar when i scrolling content up in android

SwipeRefreshLayout in AppBarLayout not wrapping content

I am trying to implement pull to refresh but I'm having an issue with SwipeRefreshLayout not wrapping the child view's height. In the view preview and in a live build it appears to have 0 height.
The layout as as follows:
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
app:layout_collapseMode="pin">
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include layout="#layout/child_layout" />
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
I have also tried making the SwipeRefreshLayout the parent of the AppBarLayout without any success as well as putting a singular LinearLayout inside of the SwipeRefreshLayout. The only thing that seems to prevent the height of the swipe layout from being 0 is to set it statically but I want it to be dynamic based upon the height of the child view.
Is there something I'm missing here? It seems like there may be a bug with SwipeRefreshLayout because replacing it with a LinearLayout that also wraps the content works as expected.
The problem is your SwipeRefreshLayout is inside the Toolbar and AppBarLayout. You must wrap AppBarLayout with another layout and put SwipeRefreshLayout below the AppBarLayout. An example is at the below.
<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"
xmlns:tools="http://schemas.android.com/tools"
android:fitsSystemWindows="true"
tools:context="com.vsahin.moneycim.View.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="250dp"
android:theme="#style/ThemeOverlay.AppCompat.Dark"
android:fitsSystemWindows="true"
app:expanded="false">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:contentScrim="?attr/colorPrimary"
android:fitsSystemWindows="true"
android:background="#drawable/gradient_background">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:layout_scrollFlags="scroll|enterAlways" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.SwipeRefreshLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout>
</android.support.design.widget.CoordinatorLayout>
if your SwipeRefreshLayout height is wrapping the content of your child_layout, then your child_layoutheight should be set to match_parent OR both SwipeRefreshLayout and child_layout height should be set to match_parent as shown in the Android Documentation
<android.support.v4.widget.SwipeRefreshLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/swiperefresh"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--Child View-->
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</android.support.v4.widget.SwipeRefreshLayout>
SwipeRefreshLayout is a transparent View, so best solution to set it match_parent it will not conflict with other Views and don't include View or Layout within it, keep it clean
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent"
app:layout_collapseMode="pin">
<include layout="#layout/child_layout" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
SwipeRefreshLayout has to be in top to overlay other layers and be clickable

ViewPager extends over the bottom of the screen

I'm new to Android development and I'm facing the following issue.
This is the layout of my main activity:
<?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:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_main"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:elevation="4dp"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:layout_scrollFlags="scroll|enterAlways">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:tabIndicatorColor="#color/white"
app:tabTextColor="#color/selected_text"
app:tabSelectedTextColor="#color/white"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/main_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
For each tab in the ViewPager I have a fragment, and this is the layout of one of them
<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:orientation="vertical"
android:background="#color/colorPrimary"
android:id="#+id/linear_layout"
tools:context=".fragments.Reviews">
<RatingBar
android:id="#+id/review_totalRating"
style="?android:attr/ratingBarStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numStars="5"
android:stepSize=".5"
android:isIndicator="true"
android:progressTint="#color/golden"
android:layout_gravity="center"
android:paddingTop="10dp"
android:paddingBottom="5dp" />
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#android:color/transparent"
android:dividerHeight="8dp"
android:paddingLeft="8dp"
android:paddingRight="8dp"
android:id="#+id/listView_reviews" />
</LinearLayout>
Then I populate my ListView with items whose layout is defined in another xml file. My problem is with the ViewPager layout_height: it is now set to match_parent, but the element extends over the bottom of the screen, with the result that the last element of the ListView is covered by the navigation buttons.
This is what I see in the design editor
ViewPager overflow
How can I make the element stop before the navigation buttons?
I faced this issue too. It's because of AppBarLayout behavior in CoordinatorLayout. By default when you create a project from a template it will set up layout with hiding Toolbar. You can run your example and check it - just swipe toolbar up and it will hide and ViewPager will move up and then correctly sticks to the bottom of the screen.
It's not a solution for some cases so you can disable this behavior by removing app:layout_scrollFlags attribute from your Toolbar. After this, the toolbar will become unhideable and the ViewPager will calculate own height correctly.
I solved using a LinearLayout as the only child of the CoordinatorLayout, so everything else becomes a children of the LinearLayout. It seems to me to be just a simple workaround, not a final solution, but now it works. This is now the layout of my main activity:
<?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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar_main"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:elevation="4dp"
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="match_parent"
app:tabIndicatorColor="#color/orange_050"
app:tabSelectedTextColor="#color/orange_050"
app:tabTextColor="#color/orange_050"/>
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/main_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</LinearLayout>

set background for activity containing AppbBarLayout

I am trying to use androids CoordinatorLayout and FrameLayout. What I want to have is a
toolbar
LinearLayout showing some info
tablayout
listviews
when the listviews are scrolled the toolbar and the LinearLayouts should scrollup and hide and the tabs should go at the top.
I have a layout of the type:
<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:fitsSystemWindows="true">
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/coordinatorLayout"
android:layout_height="match_parent"
android:layout_width="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<-- stuff I want to hide on scrolling -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|enterAlways"
android:orientation="vertical">
<include
layout="#layout/toolbar"
app:layout_scrollFlags="scroll|enterAlways"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|enterAlways"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Gamercard content"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="More Gamercard content"
/>
</LinearLayout>
</LinearLayout>
<-- stuff I dont want to hide on scrolling -->
<android.support.design.widget.TabLayout
android:id="#+id/tabLayout"
android:scrollbars="horizontal"
android:layout_below="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</android.support.design.widget.AppBarLayout>
<!-- My Scrollable View -->
<include layout="#layout/nested_scrolling_container_view"/>
</android.support.design.widget.CoordinatorLayout>
</android.support.v4.widget.DrawerLayout>
What I want to do is have a picture as the background for the entire activity, but what I see is that the AppBarLayout part is always dark. Please help.
I could do it programmatically by setting the backgroundColor in code to Color.TRANSPARENT.
appbar.setBackgroundColor(Color.TRANSPARENT);

ViewPager with Coordinator Layout

I have an activity layout that looks like the following:
<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:app="http://schemas.android.com/apk/res-auto">
<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"
app:layout_scrollFlags="scroll|enterAlways"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary" />
<android.support.design.widget.TabLayout
android:id="#+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/view_pager"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="match_parent" />
The viewpager has two fragments, one with a RecyclerView and one with a LinearLayout.
The fragment with RecyclerView works as expected and the action bar scrolls off screen when the RecyclerView is scrolled.
The other fragment with the LinearLayout isn't displaying as I would like it to however. The LinearLayout is drawn below the TabLayout and extends offscreen. I would like it to be resize to fill the space available below the TabLayout without extending offscreen. The LinearLayout looks like this:
<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:orientation="vertical">
<LinearLayout
android:id="#+id/station_detail_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
layout="#layout/station_detail_title"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="3" />
<include
layout="#layout/station_detail_body"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2" />
</LinearLayout>
<TextView
android:id="#+id/text_view_station_detail_empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal|center_vertical"
android:text="#string/text_view_station_detail_empty"
android:visibility="gone" />
</LinearLayout>
Thanks for any help, much appreciated!
I think you need to add nested scroll view to your linearlayout.
Alex I thing you have to use two CoordinatorLayout in two fragment and you can include your linear layout inside it .

Categories

Resources