FloatingActionButton inside constraintLayout in ScrollView - android

i have a floatingActionButton inside a ConstraintLayout which is inside a ScrollView
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background_grey">
<androidx.constraintlayout.widget.ConstraintLayout>
----
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/bag_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
/>
-----
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
the problem is that the button is scrolling down and up with the UI
Ps: i don't know if it is important, but the scrollView is inside a drawerLayout

You can make Your root view as FrameLayout then inside it, you will but the ScrollView then the FAB button something like below
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background_grey">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/background_grey">
<androidx.constraintlayout.widget.ConstraintLayout>
<!-- your view xml here -->
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:src="#drawable/bag_background"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
/>
</FrameLayout>

To place the floating action button, use CoordinatorLayout. A CoordinatorLayout helps facilitate interactions between views contained within it, which will be useful to describe how to animate the button depending on scroll changes.
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left|bottom"
android:layout_margin="16dp" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

Related

Floating Action button is not showing in Android Coordinator Layout

I am new to Android and UI development. I have downloaded latest version of Windows Android studio and did some basic native UI, it worked well. Now, I am trying to develop floating action button UI.
I have added CoordinatorLayout inside ConstraintLayout. FAB is added inside CoordinatorLayout. My FAB is not visible in layout preview.
I see androidx.coordinatorlayout.widget.CoordinatorLayout text in that layout with background color. Please let me know how to fix this
implementation 'com.google.android.material:material:1.2.0'
<androidx.constraintlayout.widget.ConstraintLayout 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">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#F44336"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
tools:ignore="MissingConstraints">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#color/colorPrimary"
android:src="#drawable/ic_baseline_add_24"
android:layout_gravity="bottom|end"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
add constraintTop for your CoordinatorLayout for filling whole screen
app:layout_constraintTop_toTopOf="parent"
or even this will be better
android:layout_width="match_parent"
android:layout_height="match_parent"
with removing all constraints
for test you may also add fixed size FloatingActionButton. if you want to keep wrap_content for FAB then ensure that ic_baseline_add_24 is valid icon with proper size
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#F44336"
tools:ignore="MissingConstraints">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="80dp"
android:layout_height="80dp"
android:backgroundTint="#color/colorPrimary"
android:src="#drawable/ic_baseline_add_24"
android:layout_gravity="bottom|end"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
in above code ConstraintLayout isn't needed and you may remove it if you aren't planning to make some more complicated layout. RecyclerView may be placed inside CoordinatorLayout just before FAB - at first REcyclerView will be drawn, after that FAB on top of recycler
Try
<?xml version="1.0" encoding="utf-8"?>
<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:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#F44336"
android:layout_gravity="bottom"
tools:ignore="MissingConstraints">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:layout_width="104dp"
android:layout_height="107dp"
android:layout_gravity="center"
android:foregroundGravity="center"
android:visibility="visible"
android:src="#drawable/ic_baseline_add_24"
app:backgroundTint="#color/colorPrimary" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</LinearLayout>
Don't use a CoordinatorLayout with android:layout_height="wrap_content" to contain just the FAB:
<androidx.coordinatorlayout.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">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvItems"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
android:layout_margin="#dimen/fab_margin"
app:srcCompat="#drawable/ic_add_24px" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

How to prevent BottomAppBar from overlapping content

I would like to use a CoordinatorLayout to include a BottomAppBar at the bottom of the screen, and to display some content in the remaining space (for example using a ConstraintLayout).
If I add a ConstraintLayout to the CoordinatorLayout, and then I add a button which is placed at the bottom of the ConstraintLayout, the button is covered by the BottomAppBar.
I would like the ConstraintLayout to use up all the vertical space, except for where the BottomAppBar is located, so that the button is not covered.
I tried including app:layout_behavior="#string/appbar_scrolling_view_behavior" in the ConstraintLayout, as suggested on some sites, but it doesn't work.
Also, setting app:layout_insetEdge="bottom" in the BottomAppBar, and then setting app:layout_dodgeInsetEdges="bottom" in the ConstraintLayout does not work properly, since the ConstraintLayout then overflows at the top of the screen (but the bottom is not covered anymore).
Below is the xml layout file where the BottomAppBar covers the button.
Thank you
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="top"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<Button
android:id="#+id/myButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<com.google.android.material.bottomappbar.BottomAppBar
android:id="#+id/bottomAppBar"
style="#style/Widget.MaterialComponents.BottomAppBar.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
I haven't found a proper fix, but what works for me is adding a margin to the one overlapping the BottomAppBar,
android:layout_marginBottom="?attr/actionBarSize"
e.g.
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="top"
android:layout_marginBottom="?attr/actionBarSize"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<Button
android:id="#+id/myButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

ScrollView isn't placed below ToolBar

I faced with the following problem: ScrollView in my activity should be placed below ToolBar. Here's the layout of this activity:
<?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"
tools:context=".SongLyricsActivity">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#0000FF"
tools:ignore="MissingConstraints" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toBottomOf="#id/toolbar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="16dp">
<TextView
android:id="#+id/lyrics_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</ScrollView>
</android.support.constraint.ConstraintLayout>
But when I run the app, I see this:
I don't understand, why it happens, as I position it below the toolbar, so, what's the matter?
I solved this problem using a marginTop parameter (equals to toolbar height), like this:
<ScrollView
android:id="#+id/activity_show_scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="?attr/actionBarSize"
android:background="#color/transparent_background"
>
This works for my app.
This is happening because your scroll views height is match_parent and not 0dp - so your scroll view will not respect your constraints and will spread all over your screen.
Please notice that you are using tools:ignore="MissingConstraints" and the tool attribute will only affect the preview so you will see your layout in a different way from the preview.
In addition, you were missing some constraint - app:layout_constraintTop_toTopOf="parent"
Now with that constraint, it should work:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#0000FF"
app:layout_constraintTop_toTopOf="parent"
tools:layout_editor_absoluteX="0dp" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="#id/toolbar"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginTop="16dp">
<TextView
android:id="#+id/lyrics_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
you might try:
<LinearLayout>
vertical
<RelativeLayout>
<Toolbar>
someID
parent top
parent left
<Scrollview>
below someID
parent left

How I can use horizontal scroll view in fragments?

I am working with fragments I have a requirement to use horizontal scroll view inside a fragment. I know how to add it in activity but I have no idea how to add horizontal scroll view in a fragment?
I don't think there's a difference between create a horizontal scroll view on activity or fragment. Just remember that you should add a layout inside it. Some rare cases I got bug's using scrollview on activity and can't move the fragment scrollview, so, I've the practice to use scrollview only on fragment.
An exemple:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView 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:background="#f1f1f1"
tools:context=".Fragments.Example">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.CardView
android:layout_width="900dp"
android:layout_height="300dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Example"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.v7.widget.CardView>
</android.support.constraint.ConstraintLayout>
</HorizontalScrollView>
</android.support.constraint.ConstraintLayout>
</ScrollView>
It worked successfully. (Tested)

Implementing app:hideOnScroll for BottomAppBar in Android

I have an app with the one Activity, many Fragments model, where several Fragments have a RecyclerView to show cards with content. I also have implemented the BottomAppBar from Material Design 2.0, and everything is fine except when the AppBar blocks the last CardView in the RecyclerView.
In terms of layout, I have a RecyclerView inside ConstraintLayout inside a Fragment, which sits in a FrameLayout in the main activity.
The documentation shows that for the BottomAppBar to be hidden on Scroll, we need to implement RecyclerView inside a NestedScrollView. There is one question here on SO where the answer has stated the same as well, but there seems to be no actual documentation or examples to demonstrate how this is to be done, except for this article on Medium, which uses the NestedScrollView in an Activity directly, holding a CoordinatorLayout which holds a ConstraintLayout.
Note: I think it also works on magic, because duplicating the layout in my fragment doesn't have any effect at all in my app.
How do I use NestedScrollView here?
PS : I need to have the TextView, as I set the RecyclerView to VISIBILITY.GONE and set the TextView to VISIBLE when I have no data to display.
Fragment Layout
<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:id="#+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="in.domain.APPNAME.Fragments.FragmentList">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerViewIncident"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingBottom="30dp"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.0" />
<TextView
android:id="#+id/emptyView"
android:layout_width="wrap_content"
android:layout_height="17dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:text="No Incidents to display"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.503"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
Activity 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:id="#+id/uberLayout"
tools:context=".APPNAME">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/containerFrameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</android.support.constraint.ConstraintLayout>
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.bottomappbar.BottomAppBar
android:id="#+id/bottom_app_bar"
style="#style/Widget.MaterialComponents.BottomAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:backgroundTint="#color/colorPrimary"
app:fabAlignmentMode="center"
app:navigationIcon="#drawable/baseline_menu_white_24dp"
app:hideOnScroll="true"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
</android.support.design.bottomappbar.BottomAppBar>
<android.support.design.widget.FloatingActionButton
android:id="#+id/floatingActionButton"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:clickable="true"
android:src="#drawable/baseline_add_white_24dp"
app:backgroundTint="#color/brightred"
app:fabSize="normal"
app:layout_anchor="#+id/bottom_app_bar"
tools:layout_editor_absoluteX="160dp"
tools:layout_editor_absoluteY="465dp" />
</android.support.design.widget.CoordinatorLayout>
</android.support.design.widget.CoordinatorLayout>
you shouldn't put the BottomAppBar and the FloatingActionButton in a separate CoordinatorLayout. Ditch the CoordinatorLayout they're in, the ConstraintLayout around your FrameLayout and that may already solve the problem.
<?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:id="#+id/uberLayout"
tools:context=".APPNAME">
<FrameLayout
android:id="#+id/containerFrameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
<android.support.design.bottomappbar.BottomAppBar
android:id="#+id/bottom_app_bar"
style="#style/Widget.MaterialComponents.BottomAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:backgroundTint="#color/colorPrimary"
app:fabAlignmentMode="center"
app:navigationIcon="#drawable/baseline_menu_white_24dp"
app:hideOnScroll="true"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light"
app:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/floatingActionButton"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:src="#drawable/baseline_add_white_24dp"
app:backgroundTint="#color/brightred"
app:fabSize="normal"
app:layout_anchor="#+id/bottom_app_bar" />
</android.support.design.widget.CoordinatorLayout>
I'm using a similar layout, the only difference being a <fragment> instead of a <FrameLayout>, and the BottomAppBar hides on scroll just fine. We don't need to use a NestedScrollView, if our scrolling content is a RecyclerView anyway, because RecyclerView implements NestedScrollingChild.
This interface should be implemented by View subclasses that wish to support dispatching nested scrolling operations to a cooperating parent ViewGroup.

Categories

Resources