I'm using a fragment in a MotionLayout but the fragment view isn't filling the MotionLayout even though all constraints are set. Not only fragment, even any view, such as, LinearLayout doesn't expand and I get this :
If I change MotionLayout to ConstraintLayout it works fine and the fragment fills the parent.
Here is my layout xml code:
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<androidx.drawerlayout.widget.DrawerLayout
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="#+id/motion_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorPrimary"
app:layoutDescription="#xml/scene_drawer"
tools:context=".activity.MainActivity">
<fragment
android:id="#+id/nav_host"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="left"
app:defaultNavHost="true"
app:navGraph="#navigation/main"
/>
</androidx.constraintlayout.motion.widget.MotionLayout>
<com.google.android.material.navigation.NavigationView
android:id="#+id/navView"
android:layout_width="120dp"
android:layout_height="match_parent"
android:layout_gravity="start"
app:menu="#menu/navdrawer_menu"
app:headerLayout="#layout/nav_header"
/>
</androidx.drawerlayout.widget.DrawerLayout>
</layout>
I found the problem to be that in my motion scene xml, I needed to make the start and end constraint sets' width and height as match parent.
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetEnd="#+id/end"
motion:constraintSetStart="#+id/start"
motion:duration="500"
motion:motionInterpolator="linear"
/>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#id/nav_host"
android:layout_width="match_parent"
android:layout_height="match_parent"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintWidth_default="percent"
motion:layout_constraintWidth_percent="1"
/>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#id/nav_host"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="100dp"
android:scaleX="0.8"
android:scaleY="0.8"
android:translationX="100dp"
motion:layout_constraintWidth_default="percent"
motion:layout_constraintWidth_percent="1"
/>
</ConstraintSet>
</MotionScene>
Related
I'm having a lot of troubles figuring out how to use the MotionLayout to animate a Youtube-like bottom player bar.
After trying to understand how this layout works for a few hours using the official examples and a lot of googling, I stumbled upon this question which feature a GIF chowing exactly what I'm trying to achieve:
Unfortunately, the complete code is not there so I can't understand how the author did it.
All I have for now is this:
Two problems here: the animation instantly jumps from 0 to 100 and the view doesn't collapse, it keeps occupying the whole screen.
I don't know if it's related but that part of the UI is contained in a fragment. Here is the activity layout:
<?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:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/surface"
app:layout_constraintBottom_toTopOf="#id/appbar_wrapper"
app:layout_constraintTop_toTopOf="parent">
<!--
This is the fragment that contains the view that lies
beneath the player controls. It's not visible on the image above
-->
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="?attr/actionBarSize"
app:defaultNavHost="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:navGraph="#navigation/main_nav"
tools:layout="#layout/fragment_artists" />
<!--
This is the fragment that contains the fragemtn that contains
the controls that won't collapse
-->
<androidx.fragment.app.FragmentContainerView
android:id="#+id/now_playing"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="audio.funkwhale.ffa.fragments.NowPlayingFragment" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Here is my fragment's UI:
<?xml version="1.0" encoding="utf-8"?>
<layout
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">
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="#+id/now_playing_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/elevatedSurface"
android:orientation="vertical"
app:motionDebug="SHOW_ALL"
app:layoutDescription="#xml/fragment_now_playing_scene">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_constraintTop_toTopOf="parent" />
<SquareImageView
android:id="#+id/now_playing_details_cover"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
android:padding="8dp"
app:srcCompat="#drawable/cover"
tools:src="#tools:sample/avatars" />
<!-- The rest of the UI is stripped to keep the code short -->
</androidx.constraintlayout.motion.widget.MotionLayout>
</layout>
and my scene:
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetEnd="#id/end"
app:constraintSetStart="#+id/start"
app:duration="1000"
app:motionInterpolator="linear" >
<OnSwipe
app:dragDirection="dragUp"
app:touchAnchorId="#+id/header"
app:touchAnchorSide="top" />
<KeyFrameSet>
<KeyAttribute
android:alpha="0"
app:framePosition="75"
app:motionTarget="#id/now_playing_details_controls" />
</KeyFrameSet>
<ConstraintSet android:id="#+id/start">
<Constraint android:id="#+id/header" />
<Constraint
android:id="#id/now_playing_details_cover"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"/>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint android:id="#id/header" />
<Constraint
android:id="#id/now_playing_details_cover"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="#id/header"
app:layout_constraintBottom_toBottomOf="#id/header"
app:layout_constraintStart_toStartOf="#id/header" />
</ConstraintSet>
</Transition>
</MotionScene>
Edit
Thanks to hoford, I could resolve some of the problems. However, while animation works correctly, the layout itself doesn't move. This is how it should look like:
This implementation uses a simple FrameLayout in combination with BottomSheetBehavior instead of MotionLayout. The bottom sheet itself is fragment that uses databinding.
The current implementation using a MotionLayout looks like this:
As you can see, the parts of the UI in the fragment now animate correctly, but the FragmentContainerView itself doesn't collapse. I tried several combination of layout_height on the FragmentContainerView and the MotionLayout within but I can't replicate the behaviour of the BottomSheetBehavior implementation.
I feel like MotionLayout doesn't play well inside a FragmentContainerView and I couldn't find a case using fragments in Android's examples.
Here is the layout for the activity
<?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:layout_width="match_parent"
android:layout_height="match_parent">
<!-- The component displaying the albums list -->
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/surface"
app:layout_constraintVertical_weight="10"
app:layout_constraintTop_toTopOf="parent">
<androidx.fragment.app.FragmentContainerView
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="?attr/actionBarSize"
app:defaultNavHost="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:navGraph="#navigation/main_nav"
tools:layout="#layout/fragment_artists" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<!-- The fragment of the player controls bar that should collapse -->
<androidx.fragment.app.FragmentContainerView
android:id="#+id/now_playing"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="#id/appbar_wrapper"
android:name="audio.funkwhale.ffa.fragments.NowPlayingFragment" />
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="#+id/appbar_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent">
<com.google.android.material.bottomappbar.BottomAppBar
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:theme="#style/AppTheme.AppBar"
app:backgroundTint="#color/elevatedSurface"
app:layout_insetEdge="bottom"
app:navigationIcon="#drawable/funkwhaleshape"
tools:menu="#menu/toolbar" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
Here is the updated layout of the player controls bar that should collape:
<?xml version="1.0" encoding="utf-8"?>
<layout
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">
<data>
<!-- snip -->
</data>
<androidx.constraintlayout.motion.widget.MotionLayout
android:id="#+id/now_playing_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/elevatedSurface"
app:motionDebug="SHOW_ALL"
app:layoutDescription="#xml/fragment_now_playing_scene">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
<audio.funkwhale.ffa.views.SquareImageView
android:id="#+id/now_playing_details_cover"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="0dp"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="#drawable/cover"
tools:src="#tools:sample/avatars" />
<ImageButton
android:id="#+id/now_playing_details_info"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_margin="8dp"
app:layout_constraintRight_toRightOf="#id/now_playing_details_cover"
app:layout_constraintTop_toTopOf="#id/now_playing_details_cover"
style="#style/IconButton"
android:layout_gravity="top|end"
android:background="#drawable/circle"
android:contentDescription="#string/alt_track_info"
android:src="#drawable/more"
app:tint="#color/controlForeground" />
<!-- Snip -->
</androidx.constraintlayout.motion.widget.MotionLayout>
</layout>
And the updated scene:
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Transition
app:constraintSetEnd="#id/end"
app:constraintSetStart="#+id/start"
app:duration="1000"
app:motionInterpolator="linear" >
<OnSwipe
app:dragDirection="dragUp"
app:touchAnchorId="#+id/header"
app:touchAnchorSide="bottom" />
<KeyFrameSet>
<KeyAttribute
android:alpha="0"
app:framePosition="10"
app:motionTarget="#id/now_playing_details_info"
/>
<KeyAttribute
android:alpha="0"
app:framePosition="10"
app:motionTarget="#id/now_playing_details_controls"
/>
</KeyFrameSet>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#+id/header"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
/>
<Constraint
android:id="#id/now_playing_details_cover"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="#+id/now_playing_details_info"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_margin="8dp"
app:layout_constraintRight_toRightOf="#id/now_playing_details_cover"
app:layout_constraintTop_toTopOf="#id/now_playing_details_cover"
/>
<Constraint
android:id="#+id/now_playing_details_controls"
android:layout_width="0dp"
android:layout_height="0dp"
android:alpha="1"
app:layout_constraintTop_toBottomOf="#id/now_playing_details_cover"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#id/header"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
/>
<Constraint
android:id="#id/now_playing_details_cover"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="#id/header"
app:layout_constraintBottom_toBottomOf="#id/header"
app:layout_constraintStart_toStartOf="#id/header"
/>
<Constraint
android:id="#+id/now_playing_details_info"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_margin="0dp"
android:alpha="0"
app:layout_constraintRight_toRightOf="#id/now_playing_details_cover"
app:layout_constraintTop_toTopOf="#id/now_playing_details_cover"
/>
<Constraint
android:id="#+id/now_playing_details_controls"
android:layout_width="0dp"
android:layout_height="0dp"
android:alpha="0"
app:layout_constraintTop_toBottomOf="#id/parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
</ConstraintSet>
</Transition>
</MotionScene>
I suspect many things are wrong a few things I notice:
says to track the upward movement of the top of #id/header
But start and have the exact same
Which means the header does move
because app:layout_constraintTop_toTopOf="parent" + height="0dp"
implies it top is pinned.
In general before you think about the swipe part.
Focus on getting the two constraintSets to have the start and end state you want.
Which typically involves modifying constraints in the ConstraintSet
If it is laying out the way you want
Then the onSwipe anchor needs to be with the moving object
see https://youtu.be/XtnAZXM26wQ for a brief overview on onSwipe
The problem
You say "FragmentContainerView itself doesn't collapse"
But theFragmentContainerView is not a child of the MotionLayout.
Layouts can only control direct children. The only other thing a layout can do is change its wrap size. You seem to be trying to control the MotionLayouts Parent.
The way this would typically be done is motionLayout is at the base of everything you want to control.
You might be able to make the MotionLayout and the fragment transparent.
But you would still have touch handling missing.
I am trying to achieve a DrawerLayout like scene using MotionLayout. I have a home fragment and another card fragment that I want to come above home fragment when I swipe it from right. While everything works fine except that the card fragment comes in on swiping up instead of swiping left. For simplicity, I have replaced card fragment with a dummy ConstraintLayout. Below is my code:
Layout XML:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.motion.widget.MotionLayout 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/ml_home_card"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="#xml/home_fragment_scene"
app:motionDebug="SHOW_ALL">
<include
android:id="#+id/home"
layout="#layout/layout_home_fragment" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/card"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/theme_main"/>
</androidx.constraintlayout.motion.widget.MotionLayout>
MotionScene XML:
<?xml version="1.0" encoding="utf-8"?>
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:motion="http://schemas.android.com/tools">
<Transition
app:constraintSetEnd="#id/end"
app:constraintSetStart="#id/start"
app:motionInterpolator="easeInOut">
<OnSwipe
app:onTouchUp="autoComplete"
app:touchRegionId="#id/card"
motion:dragDirection="dragLeft"
motion:touchAnchorId="#id/card"
motion:touchAnchorSide="left" />
</Transition>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#+id/home"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="#+id/card"
android:layout_width="20dp"
android:layout_height="match_parent"
android:layout_marginStart="-20dp"
app:layout_constraintStart_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#+id/home"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleX="0.9"
android:scaleY="0.9"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Constraint
android:id="#+id/card"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</ConstraintSet>
</MotionScene>
I wanted to upload a screen recording as well but don't know why Logcat Screen Recorder doesn't seem to be working.
I tried many tutorials and documentations but none solved my issue. Please help. TIA!
I want to use MotionLayout to implement the Bottom Sheet in my activity.
Motion scene:
<MotionScene xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:motion="http://schemas.android.com/apk/res-auto">
<Transition
motion:constraintSetEnd="#+id/end"
motion:constraintSetStart="#id/start"
motion:duration="2000">
<OnSwipe
motion:dragDirection="dragUp"
motion:touchAnchorId="#id/bottomSheet"
motion:touchRegionId="#id/bottomSheet" />
</Transition>
<ConstraintSet android:id="#+id/start">
<Constraint
android:id="#+id/bottomSheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
motion:layout_constraintBottom_toBottomOf="parent"/>
</ConstraintSet>
<ConstraintSet android:id="#+id/end">
<Constraint
android:id="#+id/bottomSheet"
android:layout_width="match_parent"
android:layout_height="0dp"
motion:layout_constraintTop_toTopOf="parent"
motion:layout_constraintBottom_toBottomOf="parent"/>
</ConstraintSet>
</MotionScene>
Now, if I implement my MotionLayout like the following code, I can't dragUp in button area:
<androidx.constraintlayout.motion.widget.MotionLayout
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/ml"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/darker_gray"
app:layoutDescription="#xml/activity_main_scene"
tools:context=".MainActivity">
<com.google.android.material.card.MaterialCardView
android:id="#+id/bottomSheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="#android:color/black">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/holo_red_dark"
android:padding="40dp">
<Button
android:id="#+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="A button" />
</FrameLayout>
</com.google.android.material.card.MaterialCardView>
</androidx.constraintlayout.motion.widget.MotionLayout>
I can wrap the MaterialCardView with a NestedScrollView then because the NestedScrollView will properly handle onInterceptTouchEvent, it will work:
<androidx.constraintlayout.motion.widget.MotionLayout
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/ml"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/darker_gray"
app:layoutDescription="#xml/activity_main_scene"
tools:context=".MainActivity">
<androidx.core.widget.NestedScrollView
android:id="#+id/bottomSheet"
android:background="#android:color/holo_blue_dark"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.card.MaterialCardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardBackgroundColor="#android:color/black">
<!-- other views -->
</com.google.android.material.card.MaterialCardView>
</androidx.core.widget.NestedScrollView>
</androidx.constraintlayout.motion.widget.MotionLayout>
If I implement the MotionLayout like this, I will face another issue. The MaterialCardView height does not change when the user drags up the view, even if I set the height to match_parent:
How can I change the code in a way that the red area covers the whole blue area?
Finally, I found the solution. I only need to add
android:fillViewport="true"
to the NestedScrollView to fix the issue. It happens because the height of NestedScrollView is bigger than its children in the end state, so I need to set fillViewport to true to resolve the issue.
I have a fragment called PostsFragment which is used on two places.
HomeActivity
PostActivity
In the HomeActivity, I am attaching PostsFragment and everything is going well, but, In the second activity PostActivity, I have in the top some components -post details- and below them, there is FragmentContainerView where I want to attach it again, -I want to display the related posts-.
The PostActivity parent's view is NestedScrollView.
when I set nestedScrollingEnabled to true inside PostsFragment the scrollbar only works on the recyclerView but I want to make the whole view in PostActivity scrollable, which doesn't work if I set nestedScrollingEnabled to false.
I did lots of searches and nothing works.
Edit 1:
Here is the code of PostActivity
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<import type="android.view.View" />
<variable
name="viewModel"
type="com.trade.scope.ui.project.ProjectViewModel" />
</data>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:overScrollMode="never"
app:layout_behavior="android.support.design.widget.AppBarLayout$ScrollingViewBehavior">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.project.ProjectActivity">
<com.trade.scope.ui.custom.ViewPagerPauseAble
android:id="#+id/image_view_banner"
android:layout_width="match_parent"
android:layout_height="256dp"
android:layout_marginHorizontal="16dp"
app:layout_collapseMode="parallax"
app:layout_constraintTop_toTopOf="parent" />
<com.google.android.material.textview.MaterialTextView
android:id="#+id/text_view_title_"
style="#style/Auth.Sub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginStart="18dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="18dp"
android:fontFamily="#font/muller_bold"
android:text="#string/project_request"
android:textColor="#color/dark_text"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/image_view_banner" />
<FrameLayout
android:id="#+id/divider"
android:layout_width="0dp"
android:layout_height="2dp"
android:layout_marginTop="8dp"
android:background="#drawable/primary_line"
app:layout_constraintStart_toStartOf="#+id/text_view_title_"
app:layout_constraintTop_toBottomOf="#+id/text_view_title_"
app:layout_constraintWidth_percent="0.4" />
<androidx.fragment.app.FragmentContainerView
android:id="#+id/fragment_container_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false"
app:layout_constraintTop_toBottomOf="#+id/divider" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</layout>
The code of PostsFragment
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="viewModel"
type="com.trade.scope.ui.projects.ProjectsViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:orientation="vertical"
android:scrollbars="vertical"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="#layout/view_holder_project" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
You're building a complex view, I can recommend CoordinatorLayout with AppBarLayout and CollapsingToolbarLayout and don't miss the app:layout_behavior="#string/appbar_scrolling_view_behavior"
You have 2 options:
Put nestedScrollingEnabled programally like this:
yourRecyclerView.isNestedScrollingEnabled = false
Put into your recyclerview in xml file
android:nestedScrollingEnabled="false"
Hope it's help you
You have not posted your code so I am assuming this might be the case. You have to set the nestedScrollingEnabled to false for recyclerview not for NestedScrollView
I have a main activity which has the navigation drawer and a FrameLayout to add fragments dynamically. The layout of one of the fragments has a RecyclerView and I want the RecyclerView to take the entire height of the device so that the RecyclerView scrolls beneath the ToolBar and bottom navigation. I am adding fast scroll to the RecyclerView but the verticalscrolldrawable is also scrolling between the entire height of the device but I want that to restrict between bottom nav and ToolBar like in google photos.
Sample Image - https://i.stack.imgur.com/55sh7.jpg
activity_main
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<import type="android.view.View" />
<import type="com.nowfloats.laxmi.home.ui.HomeActivity" />
<variable
name="home"
type="HomeActivity" />
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".home.ui.HomeActivity">
<FrameLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white" />
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="#+id/extended_fab"
style="#style/Widget.MaterialComponents.ExtendedFloatingActionButton.Icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/dp_16"
android:backgroundTint="#color/laxmi_green"
android:text="#string/add_new_inventory"
android:textColor="#color/white"
android:textSize="#dimen/sp_12"
android:visibility="#{home.fabObservable ? View.VISIBLE : View.GONE}"
app:fabSize="mini"
app:icon="#drawable/ic_add"
app:iconPadding="#dimen/dp_4"
app:iconSize="#dimen/dp_20"
app:iconTint="#color/white"
app:layout_anchor="#id/bottom_navigation"
app:layout_anchorGravity="top|right"
app:layout_insetEdge="bottom" />
<com.google.android.material.bottomnavigation.BottomNavigationView
android:id="#+id/bottom_navigation"
android:layout_width="match_parent"
android:layout_height="#dimen/navigation_drawer_height"
android:layout_gravity="bottom"
android:alpha=".98"
android:background="#color/laxmi_light_green"
android:theme="#style/Widget.BottomNavigationView"
app:itemIconTint="#drawable/bottom_navigation_drawable_colors"
app:itemTextAppearanceActive="#style/BottomNavigationView.Active"
app:itemTextAppearanceInactive="#style/BottomNavigationView"
app:itemTextColor="#drawable/bottom_navigation_drawable_colors"
app:labelVisibilityMode="labeled"
app:menu="#menu/bottom_navigation_menu" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
product_fragment-
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.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_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:clipChildren="false">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:fastScrollEnabled="true"
android:paddingBottom="#dimen/navigation_drawer_height"
app:fastScrollHorizontalThumbDrawable="#drawable/thumb_drawable"
app:fastScrollHorizontalTrackDrawable="#drawable/line_drawable"
app:fastScrollVerticalThumbDrawable="#drawable/thumb_drawable"
app:fastScrollVerticalTrackDrawable="#drawable/line_drawable"
tools:listitem="#layout/product_list_single_item" />
<androidx.appcompat.widget.Toolbar
android:id="#+id/header_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:background="#color/white"
tools:context=".products.ui.ProductFragment">
</androidx.appcompat.widget.Toolbar>
</androidx.coordinatorlayout.widget.CoordinatorLayout>