RecyclerView nestedScrollingEnabled inside a FragmentContainerView with a NestedScrollView - android

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

Related

Displaying DialogFragment with NavHostFragment displays empty

Im trying to display a DialogFragment which after showing up on the screen should display a start destination from the nav_graph specified in the NavHostFragment. Here's DialogFragment layout:
<?xml version="1.0" encoding="utf-8"?>
<layout>
<!-- <androidx.constraintlayout.widget.ConstraintLayout -->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="800dp">-->
<androidx.coordinatorlayout.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">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:visibility="visible">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="8dp"
android:orientation="vertical">
<fragment
android:id="#+id/nav_host_home_bottom_sheet"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toTopOf="#+id/dismiss_registration_button"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="#navigation/membership_navigation" />
<com.google.android.material.button.MaterialButton
android:id="#+id/dismiss_registration_button"
style="#style/Widget.MaterialComponents.Button.TextButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="#font/open_sans_regular"
android:text="#string/all_dismiss"
android:textSize="14sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
<!-- </androidx.constraintlayout.widget.ConstraintLayout>-->
What happens is only Dismiss button displays in the DialogFragment. When I uncomment ConstraintLayout with layout_height fixed to 800dp then startDestination from NavHostFragment loads ok. The problem is that I don't want to hadrcode the layout_height - how can I display it with either CoordinatorLayou or ConstraintLayout without hardcoding the layout_height?
To make it work I simply changed DialogFragment layout to
<?xml version="1.0" encoding="utf-8"?>
<layout>
<androidx.coordinatorlayout.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">
<fragment
android:id="#+id/nav_host_fragment"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="#navigation/membership_navigation" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
and then handle scroll view and others in fragments where it's needed.

Swipe-to-Refresh inside a fragment display white fragment

I tried to add Swipe-to-Refresh inside a fragment that contains a RecyclerView but after adding it the fragment becomes white.
Tried with a simple textview and in fragment .setRefreshing(true) and still the fragment is white.
If I move the Swipe to refresh layout to the activity everything works like a piece of charm.
My questions is what am I doing wrong or why I can't have the Swipe to refresh inside the fragment?
My fragment XML:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/swipeToRefresh"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="test" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</layout>
Activity XML:
<?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.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.MainActivity">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="100dp">
<FrameLayout
android:id="#+id/screenContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.core.widget.NestedScrollView>
<!-- TODO REFACTOR COLORS -->
<com.google.android.material.bottomappbar.BottomAppBar
android:id="#+id/bottomAppBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
app:backgroundTint="#000000"
app:fabCradleMargin="10dp"
app:hideOnScroll="true"
app:menu="#menu/bottom_app_bar"
app:navigationIcon="#drawable/ic_menu_24dp" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/floatingActionButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:backgroundTint="#e0f2f1"
app:layout_anchor="#id/bottomAppBar"
app:shapeAppearance="#style/FabDiamondOverlay"
app:srcCompat="#drawable/ic_add_24dp" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
Gradle:
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
Emulator:
Uploaded a sample project on github.
https://github.com/tirlaovidiu/swipe-to-refresh-bug-example
Solved::
NestedScrollView replaced with a ConstraitLayout and the issue went away.

Vertical fast scroll drawable in recycler view to move only between bottom navigation drawer and below toolbar like in google photos

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>

Can't pass viewmodel in databinding to child include layout

this is some code in my parent xml
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bind="http://schemas.android.com/apk/res-auto">
<data>
<variable
name="viewModel"
type="(..).viewmodels.TestViewModel"/>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:theme="#style/AppTheme.AppBarOverlay"
>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent">
<include
android:id="#+id/layout"
bind:viewModel="#{viewModel}"
layout="#layout/test_content"/>
</ScrollView>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Here's the child include layout
<layout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="viewModel"
type="(..).TestViewModel" />
</data>
<LinearLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="horizontal"
tools:layout_editor_absoluteX="74dp"
tools:layout_editor_absoluteY="1dp"
xmlns:android="http://schemas.android.com/apk/res/android">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="#+id/disable"
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#color/orange"
android:text="#{viewModel.buttonText}"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</layout>
As you can see in this example I data binded text to the viewmodel and passed it down from parent to child via bind:viewModel="#{viewModel}"
Here's the code in the activity:
val binding:TestContentBinding = DataBindingUtil.setContentView(this, R.layout.test_content)
binding.setLifecycleOwner(this)
binding.viewModel = testViewModel
If I set the binding to the child xml then the data gets binded, however if i set the binding to the parent activity the viewmodel doesn't get passed down.
The back end certainly has the correct data however I don't know how to bind data to the child.
I've even tried manually setting the layout's viewModel however that doesn't work. How do I pass the viewmodel?
You could try changing the name of the variable in your included layout.
Here is a quick article explaining how to use include layout with ViewModel.

recyclerview inside nested scroll view is not scolling

I have a recyclerview inside a nestedScrollView and I have stopped the scrolling of recyclerview to allow nestedScrollView to scroll all the page, but the nestedScrollView is not working.
I have set the nestedScrollingEnabled of the recyclerview to false
I have tried to add a hidden view under the recyclerview but it has shown on top of the bottom items of recyclerview
My layout xml file code is:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="viewModel"
type="com.accad.accadgame.viewmodels.profile.ProfileViewModel" />
</data>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/circleImageView"
android:layout_width="75dp"
android:layout_height="0dp"
android:layout_marginStart="#dimen/default_dim"
android:layout_marginTop="#dimen/default_xxdim"
android:layout_marginEnd="#dimen/default_dim"
android:src="#drawable/profile"
app:layout_constraintDimensionRatio="h,1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/profile_name"
style="#style/HeadlineTextViewActiveStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/default_dim"
android:layout_marginStart="#dimen/default_dim"
android:layout_marginEnd="#dimen/default_dim"
android:text="#{viewModel.profileName}"
app:layout_constraintEnd_toEndOf="#+id/circleImageView"
app:layout_constraintStart_toStartOf="#+id/circleImageView"
app:layout_constraintTop_toBottomOf="#+id/circleImageView"
tools:text="#tools:sample/lorem" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/profile_details_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="#dimen/default_xxdim"
android:clipToPadding="false"
android:paddingBottom="#dimen/default_dim"
android:paddingStart="#dimen/default_dim"
android:nestedScrollingEnabled="false"
app:layout_constraintBottom_toBottomOf="parent"
android:focusable="false"
app:layout_constraintTop_toBottomOf="#id/profile_name"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
After many tries, I've found the solution
which is to change the recyclerView's height to be wrap_content instead of match_parent or 0dp so the recyclerView would be like this:
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/profile_details_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/default_xxdim"
android:clipToPadding="false"
android:paddingBottom="#dimen/default_dim"
android:paddingStart="#dimen/default_dim"
android:nestedScrollingEnabled="false"
app:layout_constraintBottom_toBottomOf="parent"
android:focusable="false"
app:layout_constraintTop_toBottomOf="#id/profile_name"
/>
Put your static content as the first item in the RV.
I know this might sound bad but trust me, it's so much better than having a nested RecyclerView.
This will fix recycling, scrolling, dragging and so many other issues with nested RV.

Categories

Resources