recyclerview inside nested scroll view is not scolling - android

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.

Related

Make RecycleView show items in the middle of the screen, if the items are few

I have programmed a simple linear RecycleView for my new alarm application. Since I am very new to Android programming I have run into such a question: now, all the items I have are shown from top to bottom, even if there are only, say 3 items at all. It doesn't look too good and not convenient also. Is there some way, if there are only few items in the list, to show them in the middle, rather than from top to bottom?
Thank you!!
My current main XML code is:
<?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"
android:background="#drawable/background"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fadeScrollbars="true"
android:scrollbars="vertical"
android:layout_marginTop="27dp"
android:layout_marginBottom="36dp"
android:requiresFadingEdge="vertical|horizontal"
tools:listitem="#layout/alarms_view" />
</androidx.constraintlayout.widget.ConstraintLayout>
You should change the recycleView android:layout_height="match_parent" to
android:layout_height="wrap_content"
then add these lines in your RecycleView.
app:layout_constraintCircleRadius="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
You can center all the recyclerView in the middle
for that change your recyclerView like the xml below
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:fadeScrollbars="true"
android:scrollbars="vertical"
android:layout_marginTop="27dp"
android:layout_marginBottom="36dp"
android:requiresFadingEdge="vertical|horizontal"
tools:listitem="#layout/alarms_view" />
and when you add new item your recyclerview expand up to the height of screen
Add layout gravity to parent layout and change recyclerview height to wrap content like this:
<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"
android:layout_gravity="center"
android:background="#drawable/background"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fadeScrollbars="true"
android:scrollbars="vertical"
android:layout_marginTop="27dp"
android:layout_marginBottom="36dp"
android:requiresFadingEdge="vertical|horizontal"
tools:listitem="#layout/alarms_view" />

ViewPager2 conflicting with SwipeRefreshLayout

I'm using Horizontal ViewPager2 which has 4 fragments inside. Each fragment has SwipeRefreshLayout on a RecyclerView. The issue that I'm facing is that when RecyclerView is at top position then onClick on any item is list is not working. If I scroll the RecyclerView a bit down then onClick works fine. And when RecyclerView is at top position then if SwipeRefreshLayout is in refreshing state then onClick works fine. It seems SwipeRefreshLayout is conflicting with ViewPager2 in touch events. It works fine with simple ViewPager. What could be the actual problem and how can we handle it? Any ideas would be appreciable.
Thanks
xml:
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/fragment_home"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<include
android:id="#+id/headerPanel"
layout="#layout/home_header"
app:viewModel="#{viewModel}" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/swipe_refresh_layout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:paddingStart="#dimen/home_post_side_spacing"
android:paddingEnd="#dimen/home_post_side_spacing"
app:colorScheme="#{#color/fayvo_color}"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#+id/headerPanel"
app:onRefreshListener="#{() -> viewModel.manualRefresh()}"
app:refreshing="#{viewModel.isRefreshing}"
android:background="#f0f0f0">
<RelativeLayout
android:id="#+id/rl_rv"
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_homePosts"
adapter="#{viewModel.postObservableArrayList}"
addToTop="#{viewModel.addToTop}"
clearList="#{viewModel.clearList}"
showLoader="#{viewModel.isPagingEnabled && viewModel.isLoading}"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
<FrameLayout
android:id="#+id/emptyFrameLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="#{viewModel.showEmptyLayout?View.VISIBLE:View.GONE}" />
<include
android:id="#+id/postUploadProgressLayout"
layout="#layout/item_post_upload_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:viewModel="#{viewModel}" />
</RelativeLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
<View
android:id="#+id/tooltipView"
android:layout_width="1dp"
android:layout_height=".1dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
I was also facing the same issue, it is due to nested scrolling. After a lot of searching i came to know that coordinator layout should be userd as parent layout. App bar also needs to be added and after that it should work perfectly.
It resolved the issue.
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="#+id/coordinateLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/fragmentAppBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#null"
app:elevation="0dp" />
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/swipeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rvMemberList"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
tools:listitem="#layout/holder_member_item" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
As i see you have also app bar so user constraint layout and include your app bar and coordinator layout inside that
so hierarchy should be like
ConstraintLayout
AppBar
CoordinatorLayout
A simpler solution is that Change Direct parent of ViewPager2 from CosntraintLayout to some other layout i.e. LinearLayout and it will work fine.

MotionLayout with Viewpager's Recyclerview

I have a layout as such;
<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/motion_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true"
android:orientation="vertical"
app:layoutDescription="#xml/motion_layout_details">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navigationIcon="#drawable/ic_back"
app:title="ToolbarTitle" />
<androidx.appcompat.widget.AppCompatImageView
android:id="#+id/image"
android:layout_width="0dp"
android:layout_height="244dp"
android:scaleType="fitXY" />
<com.google.android.material.tabs.TabLayout
android:id="#+id/tl_menu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="2dp"
app:tabIndicator="#null"
app:tabMode="scrollable"
app:tabRippleColor="#null" />
<androidx.viewpager.widget.ViewPager
android:id="#+id/vp_menu"
android:layout_width="0dp"
android:layout_height="0dp" />
</androidx.constraintlayout.motion.widget.MotionLayout>
With identical viewpager items that contain a recyclerview;
<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"
android:background="#color/white"
android:orientation="vertical"
android:paddingTop="#dimen/spacing_16dp">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="0dp"
android:layout_height="0dp"
android:clipToPadding="false"
android:orientation="vertical"
android:paddingBottom="#dimen/spacing_24dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
I have a motion scene that collapses the image when scrolled up (the configurations for this are correct). If in my viewpager items I wrap my RecyclerView in a nestedscrollview my transition -
<Transition
app:constraintSetEnd="#+id/end"
app:constraintSetStart="#+id/start"
app:duration="500"
app:motionInterpolator="linear">
<OnSwipe
app:dragDirection="dragUp"
app:touchAnchorId="#+id/vp_menu"
app:touchAnchorSide="top" />
</Transition>
Works just fine, and transitions as I'd expect. But removing that nested scrollview no longer triggers the motion layout at all. I've dug around for a good couple of hours and can't seem to find any explanation. I could put the nestedscrollview back in, but ideally I'd like to leave it out as A) it's not needed and B) breaks some stickheader stuff I'm using.
UPDATE
Fixed this as per my comment. .isNestedScrollingEnabled = false stops the recyclerview communicating with the motionlayout.
Turns out, from when I had my recyclerview in a nestedscrollview I had rv?.isNestedScrollingEnabled = false which must be stopping some kind of trigger for the motionlayout. Removing this has fixed the issue and works with the above code.

RecyclerView max_height with wrap_content

I have a Recycler View in a Constraint Layout that shows data from a database. I want the max height to be 500dp, but the problem is that when it exceeds that size, it cuts a portion from the bottom of the view.
I don't know what would be the problem.
Here is the xml of the RecyclerView:
<?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="fill_parent"
android:layout_height="wrap_content"
android:maxHeight="500dp"
tools:context=".histDialog">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:padding="3dp"
app:layout_constrainedHeight="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
The recyclerview appears in an activity styled as a dialog.
I've tried every possible thing i could think of but i can't get it to work.
I found the solution. This is the XML now:
<?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="wrap_content"
android:layout_height="wrap_content"
tools:context=".histDialog">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="#color/colorPrimary"
android:clipToPadding="true"
android:padding="3dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHeight_default="wrap"
app:layout_constraintHeight_max="500dp"
app:layout_constraintHeight_min="50dp"/>
</androidx.constraintlayout.widget.ConstraintLayout>
The important part is:
android:layout_height="0dp"
app:layout_constraintHeight_default="wrap"
app:layout_constraintHeight_max="500dp"
app:layout_constraintHeight_min="50dp"
for the RecyclerView. Took me long enough to realise it was this simple. Hope this can help others too.

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)

Categories

Resources