Scrolling a viewpager header above the recyclerview not working - android-recyclerview

I tried two ways to scroll a viewpager header above a recyclerView. The id of the layout is android:id="#+id/rel_promotions_parent" with the viewPager to be scrolled.
Using CoordinatorLayout where the viewpager root layout having app:layout_scrollFlags="scroll|exitUntilCollapsed" and recyclerView with app:layout_behavior="#string/appbar_scrolling_view_behavior"
<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"
android:background="#color/white_one"
android:fitsSystemWindows="true"
>
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
>
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
>
<RelativeLayout
android:id="#+id/rel_promotions_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
>
<com.loopingviewpager.LoopingViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible"
app:autoScroll="true"
app:isInfinite="true"
app:scrollInterval="2000"
/>
<com.loopingviewpager.indicator.CustomShapePagerIndicator
android:id="#+id/indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#id/viewpager"
android:layout_centerHorizontal="true"
android:layout_marginBottom="#dimen/_5sdp"
android:visibility="visible"
app:indicator_spacing="4dp"
/>
</RelativeLayout>
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:clipToPadding="false"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:paddingBottom="10dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
/>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
Using motionLayout as an example in the link https://medium.com/#alex.gabor applying the constrainSet to the layout android:id="#+id/rel_promotions_parent"
<RelativeLayout 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_one"
>
<androidx.constraintlayout.motion.widget.MotionLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutDescription="#xml/scrollable_header_above_recycler_view_scene"
>
<RelativeLayout
android:id="#+id/rel_promotions_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
>
<com.loopingviewpager.LoopingViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="visible"
app:autoScroll="true"
app:isInfinite="true"
app:scrollInterval="2000"
/>
<com.loopingviewpager.indicator.CustomShapePagerIndicator
android:id="#+id/indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#id/viewpager"
android:layout_centerHorizontal="true"
android:layout_marginBottom="#dimen/_5sdp"
android:visibility="visible"
app:indicator_spacing="4dp"
/>
</RelativeLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="5dp"
android:clipToPadding="false"
android:paddingStart="5dp"
android:paddingEnd="5dp"
android:paddingBottom="10dp"
app:layout_constraintTop_toBottomOf="#id/rel_promotions_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
/>
</androidx.constraintlayout.motion.widget.MotionLayout>
</RelativeLayout>
In both the cases only the recyclerView is scrolling, and the viewPager is laying still. If we try to touch and drag the viewpager it will scroll, but not with the help of the recyclerView.
Does anyone knows how to scroll a viewpager header above a recyclerView..?

NestedScrollView was not able to catch the scroll change when recyclerView is placed inside. So while pagination is implemented a lot of memory space is allocated and scrolling is pretty lag. The solution I did is to incorporate the header inside the recyclerView as the first element and then removed the nestedsrollview. Also I implemented the diffUtil class callback for the recyclerview also which did a lot of work for me.
Hope it helps for anyone.

Related

Add Constraints to ConstraintLayout - Android Studio

I've been trying to use constraints with a ConstraintLayout with an ID of card_details to position it on the screen, but the constraints are not working, and the IDE is not recommending them as available attributes as well.
Here's the code I'm using.
<com.google.android.material.card.MaterialCardView
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/product_card"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="15dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="#+id/product_image"
android:layout_width="match_parent"
android:layout_height="280dp"
android:scaleType="centerCrop"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="ImageContrastCheck"
tools:srcCompat="#tools:sample/backgrounds/scenic" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="#+id/card_details"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="15dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/product_image">
<TextView
android:id="#+id/product_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="#+id/product_price"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="15dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/product_title" />
</androidx.constraintlayout.widget.ConstraintLayout>
</com.google.android.material.card.MaterialCardView>
Here's how they look like:
How the constraints look
The highlighted item should be placed beneath the image with these constraints, but they don't for some reason.
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/product_image"
Any idea why? Help is appreciated.
Thanks.
Because the ImageView is not inside the ConstraintLayout. You can only put constraints with respect to other views inside that ConstraintLayout. Try moving the ImageView inside the ConstraintLayout

Recyclerview multiple viewtype causes first row item expanded unexpectedly

I want to make something like this
so I am using a recyclerview which has two viewtype ( for the first item I am using one kind of viewholder and rest of item I am using another viewholder).
But on my device, it is showing like this
For the first viewholder I am using this layout file
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<de.hdodenhof.circleimageview.CircleImageView
android:id="#+id/attach_circle_imageview"
android:layout_width="80dp"
android:layout_height="80dp"
android:src="#drawable/attach_photo"
app:civ_border_color="#607D8A"
app:civ_border_width="1dp"
android:layout_marginLeft="14dp"
android:layout_marginBottom="14dp"/>
and for others, I am using this layout file
<android.support.v7.widget.CardView
android:layout_width="90dp"
android:layout_height="90dp"
android:layout_marginLeft="14dp"
android:layout_marginBottom="14dp"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:cardCornerRadius="10dp">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/gallary_iv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/white_bg_iv"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="#drawable/pic_photo_number_bg"
app:layout_constraintBottom_toBottomOf="#+id/gallary_iv"
app:layout_constraintEnd_toEndOf="#+id/gallary_iv"
app:layout_constraintStart_toStartOf="#+id/gallary_iv"
app:layout_constraintTop_toTopOf="#+id/gallary_iv" />
<TextView
android:id="#+id/pic_count_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1"
android:textSize="16sp"
android:textColor="#506876"
app:layout_constraintTop_toTopOf="#+id/white_bg_iv"
app:layout_constraintBottom_toBottomOf="#+id/white_bg_iv"
app:layout_constraintStart_toStartOf="#+id/white_bg_iv"
app:layout_constraintEnd_toEndOf="#id/white_bg_iv"/>
</android.support.constraint.ConstraintLayout>
In the first-row pictures height is expanded unexpectedly, how can I solve this problem?
set the first viewholder layout
android:layout_width="match_parent"
android:layout_height="match_parent"
change to
android:layout_width="90dp"
android:layout_height="90dp"

How to scroll a nested scroll view programmatically

I am using AppBarLayout and NestedScrollView inside a CoordinatorLayout to have CollapsingToolbar effect in my app. My problem is to display the imageview 40% initially and once user scroll down i need to expand the imageview to display full image(Like Whatsapp Profile).
I have tried below links for reference.
Programmatically scroll to the top of a NestedScrollView
top-of-a-nestedscrollview
Here is the xml.
<?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"
android:id="#+id/main_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true">
<android.support.design.widget.AppBarLayout
android:id="#+id/appbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fitsSystemWindows="true"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="#+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="50dp"
app:expandedTitleMarginStart="35dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<ImageView
android:id="#+id/userProfilePicture"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:scaleType="centerCrop"
app:layout_collapseMode="parallax"
app:layout_collapseParallaxMultiplier="1.0"/>
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView
android:id="#+id/nestedScroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Dr Srikant Reddy"
android:textAppearance="#style/TextAppearance.AppCompat.Title"/>
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp">
<LinearLayout
style="#style/Widget.CardContent"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Info"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/cheese_ipsum" />
</LinearLayout>
</android.support.v7.widget.CardView>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>

Put a button at the end of a recyclerview with swiperefreshlayout

i want to to put a button at the end of a scrollview, i know that i can achieve this if i modify my adapter but i don't want to do it in that way because i think there's an easier way. So i tried modifying my layout like this:
<!-- Not important stuff -->
<android.support.v4.widget.SwipeRefreshLayout
android:id="#+id/refreshIndicatorCoins"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/rvCoinsFull"
android:clickable="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</android.support.v7.widget.RecyclerView>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.v4.widget.SwipeRefreshLayout>
This works almost perfect but swipeRefresh's animation freezes
Hope it helps.
After RecyclerView put this code.
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</RelativeLayout>

Android nestedscrollview not triggering nested fling

I'm using nestedscrollview in sliding card to pull it up and down, by extending coordinator layout behavior class and overriding its nested scrolling and flinging methods.
In my layout, I have on recylerview, and two nestedscroll view one to wrap the header and make it pull the card up and down, and one for the to wrap and error message which appears after any error message.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/slidinguppanel_slidingcontainer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
android:background="#android:color/white">
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_marginTop="?actionBarSize"
android:fillViewport="true"
android:fitsSystemWindows="true"
android:layout_gravity="fill_vertical"
android:layout_height="match_parent">
<include
android:id="#+id/blocking_error_panel"
layout="#layout/blocking_error_panel" />
</android.support.v4.widget.NestedScrollView>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v4.widget.NestedScrollView
android:id="#+id/nested_scroll_view"
android:layout_width="match_parent"
android:fillViewport="true"
android:layout_gravity="fill_vertical"
android:fitsSystemWindows="true"
android:layout_height="wrap_content">
<LinearLayout
android:id="#+id/choose_bus_headers"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:theme="#style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:clickable="false"
android:layout_height="?actionBarSize"
app:popupTheme="#style/AppTheme.PopupOverlay">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:orientation="horizontal">
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#color/colorPrimary"
android:src="#drawable/ic_publicbus_choosebus_bus" />
<com.wrzit.app.Utils.CustomTextView
android:id="#+id/txtPanelHeader"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/toolbar_text_margin_start"
android:text="#string/bus_panel_header_text"
android:textAlignment="center"
android:textColor="#android:color/white"
android:textSize="#dimen/card_header_text_size"
app:typeface="roboto_regular.ttf" />
</LinearLayout>
<ImageButton
android:id="#+id/btnSlider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginRight="#dimen/activity_horizontal_margin"
android:background="#color/colorPrimary"
android:padding="5dp"
android:src="#drawable/ic_expand_more_white_24dp" />
</android.support.v7.widget.Toolbar>
</android.support.design.widget.AppBarLayout>
<com.wrzit.app.Utils.CustomTextView
android:id="#+id/txtGPSNotification"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/notification_background"
android:padding="#dimen/notification_padding"
android:textAlignment="center"
android:textColor="#android:color/white"
android:textSize="#dimen/regular_text_size"
android:visibility="gone"
app:typeface="roboto_regular.ttf" />
<com.wrzit.app.Utils.CustomTextView
android:id="#+id/txtNetworkNotification"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/notification_background"
android:padding="#dimen/notification_padding"
android:textAlignment="center"
android:textColor="#android:color/white"
android:textSize="#dimen/regular_text_size"
android:visibility="gone"
app:typeface="roboto_regular.ttf" />
<ProgressBar
android:id="#+id/progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginTop="-7dp"
android:indeterminate="true"
android:visibility="visible" />
<LinearLayout
android:id="#+id/layoutFilterBusStop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="16dp"
android:orientation="horizontal"
android:visibility="gone">
<LinearLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="#+id/txtFilterBusStopName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Jalan Raja Chulan"
android:textColor="#android:color/black"
android:singleLine="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="12sp"
android:text="Filtered Bus Stop" />
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_weight="0.1"
android:layout_height="match_parent">
<ImageView
android:id="#+id/btnFilterBusStopClose"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center|right"
android:src="#drawable/ic_close_black_24dp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView
>
<android.support.v7.widget.RecyclerView
android:id="#+id/listChooseBus"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="#E7E8E7"
android:dividerHeight="1dp" />
</LinearLayout>
The behavior detects triggers onNestedPreFling() when I fling the recyclerview, or the nestedscrollview that wraps the header. The problem occurs when I fling the nestedscrollview that wraps the error layout, it triggers onNestedPreScroll(), but doesn't always triggers onNestedPreFling(), even though scroll amount larger than the touch slop.
I tried to identify what cause this issue, but unfortunately was not able to identify it. hopefully someone knows what prevents onNestedPreFling() from being called.