How do I scroll content over an image? - android

I'm trying to implement the Play Store header image behaviour, without success.
I was able to have the entire page scrolled, but only along with the ImageView inside the CollapsingToolbarLayout.
I used the example at the announcement of Android Design Support library. The XML of the activity as of now looks like this:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.design.widget.AppBarLayout
android:layout_height="192dp"
android:layout_width="match_parent" xmlns:app="http://schemas.android.com/apk/res-auto"
layout_width="wrap_content" layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed" layout_width="wrap_content"
layout_height="wrap_content">
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/imageView" android:layout_gravity="center_vertical" android:src="#android:mipmap/sym_def_app_icon"/>
<android.support.v7.widget.Toolbar
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent"
app:layout_collapseMode="pin" layout_width="wrap_content" layout_height="wrap_content"/>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="New Text"
android:id="#+id/textView" android:layout_gravity="center_vertical"/>
</android.support.design.widget.CoordinatorLayout>
I'm pretty sure that something's missing here.

Instead of using ScrollView, you need to wrap your AppBarLayout inside a CoordinatorLayout.
You would also need to put app:layout_behavior="#string/appbar_scrolling_view_behavior" on the ViewGroup immediately following the AppBarLayout that is the main page content.
Here's a layout from Chris Banes' cheesesquare sample app.

Related

AppBar Layout Expands Automatically when View visibility is changed from Gone to Visible on runtime

As we can see from the below sample, on changing the visibility of the view from gone to visible and vice versa, the appbar automatically expands and scrim drawn is shown as well.
<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/crl_parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:fillViewport="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/abl_appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:contentScrim="#drawable/shape_rectangle_grdient_red_yellow"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_collapseMode="parallax">
<FrameLayout
android:id="#+id/fl_class"
android:layout_width="match_parent"
android:layout_height="#dimen/d_280dp"
android:background="#color/colorPlaceholderBg">
<ImageView
android:id="#+id/iv_class"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:scaleType="centerCrop"
android:src="#color/colorPlaceholderBg" />
<ProgressBar
android:id="#+id/pb_dp_progress"
android:layout_width="#dimen/d_20dp"
android:layout_height="#dimen/d_20dp"
android:layout_gravity="center"
android:visibility="visible" />
</FrameLayout>
<RelativeLayout
android:id="#+id/rl_toolbar"
android:layout_width="match_parent"
android:layout_height="#dimen/toolbar_default_height"
android:background="#drawable/shape_rectangle_transparent_grey_gradient">
<ImageView
android:id="#+id/iv_back"
... />
</RelativeLayout>
<android.support.v7.widget.Toolbar
android:id="#+id/tl_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:minHeight="#dimen/toolbar_default_height"
android:visibility="visible"
app:contentInsetStart="#dimen/d_0dp"
app:layout_collapseMode="pin">
<include layout="#layout/view_toolbar" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<include layout="#layout/fragment_class_details_content" />
</android.support.design.widget.CoordinatorLayout>
This the code for the outer layout. As can be seen from the above layout that the pattern is mostly standard. I have tried replicating the bug in new sample but of no use. The initial problem seem to be changing the height of nested scroll view on runtime seems to be the problem but that is not the case. I tried to setExpand(false) on the click of the button but that is not working as well.
<img src="https://i.imgur.com/YGTT3oL.gif" title="source: imgur.com" />
Link to demo gif is here: https://i.imgur.com/YGTT3oL.gif
I bet the problem is caused by app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
You have to define the behavior you want when scrolling, check out this article: https://medium.com/martinomburajr/android-design-collapsing-toolbar-scrollflags-e1d8a05dcb02
Since I dont know what behaviour do you want, read the article and choose yourself. Hiding and showing the view is triggering those flags.
In your #layout/fragment_class_details_content check if
app:layout_behavior="#string/appbar_scrolling_view_behavior"
is present in the parent layout.
Also change app:layout_scrollFlags="scroll|exitUntilCollapsed|snap" to
app:layout_scrollFlags="scroll|exitUntilCollapsed"
Add this attribute to the CollapsingToolbarLayout
app:toolbarId="#+id/tl_toolbar"
Add this attribute to Toolbar:
app:popupTheme="#style/AppTheme.PopupOverlay"
Extract your gone/visible layout from android.support.design.widget.CollapsingToolbarLayout.
Too much nesting you did so avoid nesting and Use constraint layout

coordinator layout anchor doesnt work

I can't get the anchor to work. it doesn't follow the app bar being scrolled to the top.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:background="#color/testGray">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_height="200dp"
android:layout_gravity="center_horizontal"
>
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:background="?attr/colorPrimary"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<FrameLayout
android:id="#+id/frame_info"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginTop="140dp"
android:elevation="11dp"
android:layout_gravity="center_horizontal"
app:layout_anchor="#id/appbar"
app:layout_anchorGravity="center|bottom"
>
</FrameLayout>
<team.semicolon.amizeh.CustomViews.SongsListView
android:id="#+id/songs_listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toBottomOf="#id/frame_info"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginTop="60dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
/>
</android.support.design.widget.CoordinatorLayout>
</android.support.constraint.ConstraintLayout>
plus, I can't get the minHeight to work, It scrolls all the way to the top.
I want the frame layout to follow the app bar and anchor it but the app bar scrolls but the frame layout doesn't.
the frame_info doesn't follow the appbar when I scroll, as it was
supposed to do. when I scroll SongsListView to the top, the appbar
moves to the top too, but frame_info stays in place
First of all, i don't suggest such a layout. Like i said, make the CoordinatorLayout as the root of the layout.
Also, if you are trying to achieve FrameLayout follow AppbarLayout when scrolling, you'll need to add it inside a NestedScrollView then setting the NestedScrollView:
app:layout_behavior="#string/appbar_scrolling_view_behavior"
To follow AppbarLayout.
Check my answer about where to using above code : appbar_scrolling_view_behavior https://stackoverflow.com/a/35181870/4409113

Empty FrameLayout Blocks Button Behind

as you can see the backButton is behind the frame layout.
but i want to make this button clickable unless its visible.
im using scrollview, which means i cannot place BackButton Above.
because it will colapse when i scroll it up.
Heres the XML
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="230dp"
android:src="#drawable/background"
android:scaleType="centerCrop">
</ImageView>
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/backButton"
android:clickable="true"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_alignParentTop="true"
android:layout_marginLeft="20dp"
android:layout_marginTop="20dp"
android:src="#drawable/ic_arrow_back_white"/>
</FrameLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="100dp"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:weightSum="1">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="0.74"
android:descendantFocusability="blocksDescendants">
//SOME CONTENT HERE, REMOVED FOR READABILITY
</FrameLayout>
</LinearLayout>
</ScrollView>
</FrameLayout>
Simple question. How?
The problem here seems to be that neither you have only a single child inside your FrameLayout nor do you use the `android:layout_gravity" attribute. See the docs:
FrameLayout is designed to block out an area on the screen to display a single item. Generally, FrameLayout should be used to hold a single child view, because it can be difficult to organize child views in a way that's scalable to different screen sizes without the children overlapping each other. You can, however, add multiple children to a FrameLayout and control their position within the FrameLayout by assigning gravity to each child, using the android:layout_gravity attribute.
From the image you have uploaded I can see that the whole layout can be easily implemented using new Support Libraries in Android.
And if that is your case the whole Layout can be converted changed to use a CoordinatorLayout instead of using the FrameLayout directly. Check the following image. If that is what you want then follow along and if it is not exactly what you want you can IGNORE this Answer:
If you want something like this then FrameLayout might be a hard way to go while there exist support design libraries that will make your job easier.
In this case its CoordinatorLayout and Collapsing Tool Bar but even if you do not want the Collapsing toolbar still Coordinator Layout is the best Alternative for this!
If you want to know more about support design Libraries then here is a post Android Developers Google Blog.
Coordinator Layout it is easily to make layout of the nature like yours and its a smart alternative, For the image I have uploaded the code will be something 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:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.sample.foo.usingcoordinatorlayout.FabAndSnackbarActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/appBar"
android:layout_width="match_parent"
android:layout_height="300dp"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsingToolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginStart="48dp"
app:expandedTitleMarginEnd="64dp"
app:title="#string/collapsing_toolbar">
<ImageView
android:id="#+id/toolbarImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
android:src="#drawable/bg"
app:layout_collapseMode="parallax" />
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:layout_collapseMode="pin" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="28sp"
android:lineSpacingExtra="8dp"
android:text="#string/long_latin"
android:padding="#dimen/activity_horizontal_margin" />
</android.support.v4.widget.NestedScrollView>
<android.support.design.widget.FloatingActionButton
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_margin="#dimen/activity_horizontal_margin"
android:src="#drawable/mascot_icon"
app:layout_anchor="#id/appBar"
app:layout_anchorGravity="bottom|end" />
</android.support.design.widget.CoordinatorLayout>
For Learning more about all this Support Library and more other interesting features, check this link its a good blog post about all these! Always remember you will always add support design in your app.gradle file just like appcompat. But the description from those links will consist all these information. Happy Coding!
Make your covering framework dont custom the touch event to let your underneath button be able to handle the touch event. So it is clickable.

Android Scroll View in fragment crops content

I created a Scroll View which should allow me to scroll through all the content which is inside Linear Layout (that is a child of Scroll View).
Code looks like this:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="pl.oakfusion.delegator.DomesticDelegationSecondFragment">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
....
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="25dp"
android:layout_marginTop="25dp"
android:background="#color/textDarkest"
android:text="Save"
android:textColor="#color/textColor"
android:layout_gravity="right" />
</LinearLayout>
Preview looks like this:
But in my app I have this:
I can't scroll down, this is all I can see.
If I allow to rotate I have horizontal view:
which now allows me to scroll but cuts the button entirely. (On the picture is bottom of view) I can pull down fast and I can see that the button is there but it goes up again (this android thing when you can pull slightly further but it scrolls back)
How can I fix this?
Hosting 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"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="pl.oakfusion.delegator.DomesticDelegationActivity">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/appbar_padding_top"
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:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/AppTheme.PopupOverlay">
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
try adding this to the scrollView in your xml layout
android:fillViewport="true"
I have experienced the same problem once. I tried adding padding for the ViewGroup inside ScrollView. Then it worked fine. Its a hacky solution and not an ideal one.
For the example mentioned above (by user3212350):
I have added some padding to the LinearLayout inside ScrollView to make the view completely visible. The amount of padding required may differ for various screen sizes.
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="pl.oakfusion.delegator.DomesticDelegationSecondFragment">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
##android:paddingBottom="50dp"##>
....
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="25dp"
android:layout_marginTop="25dp"
android:background="#color/textDarkest"
android:text="Save"
android:textColor="#color/textColor"
android:layout_gravity="right" />
</LinearLayout>

On Activity started layout jumps to RecyclerView's top

When the activity is opened, it shows the top of the RecyclerView layout instead of the top of the activity layout.
Activity layout .xml file:
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingBottom="20dp"
android:paddingTop="20dp">
...
<RelativeLayout/>
<View />
<LinearLayout/>
...
<android.support.v7.widget.RecyclerView
android:id="#+id/venue_place_info_gallery_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"/>
</LinearLayout>
</ScrollView>
Activity onCreate:
RecyclerView galleryRecyclerView = (RecyclerView) findViewById(R.id.venue_place_info_gallery_recycler_view);
galleryRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(gridLayoutColumns, StaggeredGridLayoutManager.VERTICAL));
VenueGalleryAdapter venueGalleryAdapter = new VenueGalleryAdapter(VenuePlaceInfoActivity.this, images);
galleryRecyclerView.setAdapter(venueGalleryAdapter);
The adapter is very simple. It receives the images as an argument in the constructor and the data cannot be changed later on.
I've tried to apply all kinds of settings to the RecyclerView layout, but it works the same with or without them. For example:
galleryRecyclerView.setNestedScrollingEnabled(false);
galleryRecyclerView.setHasFixedSize(true);
galleryRecyclerView.setLayoutFrozen(true);
galleryRecyclerView.setPreserveFocusAfterLayout(false);
UPDATE:
I have found more info on the subject in the answer of another question. It's all because of the ScrollView and RecyclerView not being capable to live together even if you set setNestedScrollingEnabled to true. But it still doesn't give me the resolution of my problem. I need to have some stuff above the gallery RecyclerView and I want to scroll down through all the images (not putting them in a container).
If you want your layout to look good, I would use a CoordinatorLayout with an AppBarLayout as the first element inside it, and the RecyclerView as the second. Inside the AppBarLayout, you should put whatever it is that you would like to have above the RecyclerView. Something similar to this:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#color/white">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:elevation="0dp">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|enterAlways"
app:titleEnabled="false">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
android:orientation="vertical"
android:paddingTop="20dp"
app:layout_collapseMode="parallax">
<!-- stuff you want above your recyclerview -->
</LinearLayout>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
</LinearLayout>
Someone does something similar here, just instead of using a toolbar in the appbarlayout, you may use whatever view layouts you'd like. AppBarLayout is an extended Vertical LinearLayout: http://www.basagee.tk/handling-scrolls-with-coordinatorlayout/
just add the following tag on your activity/fragment root layout and you are good to go.
android:descendantFocusability="blocksDescendants"

Categories

Resources