Related
I'm trying to implement a document tree using a RecyclerView. Because the tree is expandable, I'm using a custom adapter for it. All of the layout items in the RecyclerView are set to WRAP_CONTENT width, along with the RecyclerView itself. Because the labels in the items can be long and nested, I want the list to be horizontally scrollable to see the clipped items, and the list orientation to be vertical. Comment if you need anything else.
branch.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:orientation="vertical"
android:gravity="center"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<TextView
android:padding="10dp"
android:id="#+id/title"
android:gravity="center"
android:textStyle="bold"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="#+id/arrow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:src="#drawable/ic_baseline_keyboard_arrow_down_24"/>
</LinearLayout>
activity
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
tools:context=".TreeActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/list"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
</HorizontalScrollView>
Binding the view(The adapter is separately managed)
class BranchViewHolder(val branchBinding: BranchBinding) : TreeViewBinder.ViewHolder(branchBinding.root)
override fun getLayoutId(): Int = R.layout.branch
override fun provideViewHolder(itemView: View?): BranchViewHolder = BranchViewHolder(BranchBinding.bind(itemView!!))
override fun bindView(p0: BranchViewHolder?, p1: Int, p2: TreeNode<*>?) {
Log.i(TAG, "bindView: ${p2?.isExpand}")
val rotateDegree = if (p2?.isExpand == true) -90 else 0
p0?.branchBinding?.arrow?.rotation = rotateDegree.toFloat()
with(p2?.content as Branch) {
p0?.branchBinding?.title?.text = this.name
p0?.itemView?.layoutParams= RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT)
}
}
Screenshot
Problem - Want to horizontally scroll
Add app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" to your RecyclerView.
For example if you want to scroll the items horizontally, try this one :
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"/>
Don't forget to add the orientation for the vertical / horizontal scroll.
How to use RecyclerView inside NestedScrollView?
RecyclerView content is not visible after setting adapter.
UPDATE layout code updated.
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/keyline_1">
</RelativeLayout>
<View
android:id="#+id/separator"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#e5e5e5" />
<android.support.v7.widget.RecyclerView
android:id="#+id/conversation"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
Replace your recyclerView with,
<android.support.v7.widget.RecyclerView
android:id="#+id/conversation"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
here,
app:layout_behavior="#string/appbar_scrolling_view_behavior"
will manage the rest of things.
One more thing, no need to put your recyclerView inside NestedScrollView
You need to use support library 23.2.0 (or) above
and RecyclerView height will be wrap_content.
recyclerView.setNestedScrollingEnabled(false)
But by doing this the recycler pattern doesn't work. (i.e all the views will be loaded at once because wrap_content needs the height of complete RecyclerView so it will draw all child Views at once. No view will be recycled). Try not to use this pattern unless it is really required. Try to use viewType and add all other views that need to scroll to RecyclerView rather than using RecyclerView in Scrollview. The performance impact will be very high.
To make it simple "it just acts as LinearLayout with all the child views"
UPDATE 1
Since Android Support Library 23.2.0 there were added method setAutoMeasureEnabled(true) for LayoutManagers. It makes RecyclerView to wrap it's content and works like a charm.
http://android-developers.blogspot.ru/2016/02/android-support-library-232.html
So just add something like this:
LayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setAutoMeasureEnabled(true);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setNestedScrollingEnabled(false);
UPDATE 2
Since 27.1.0 setAutoMeasureEnabled is deprecated, so you should provide custom implementation of LayoutManager with overridden method isAutoMeasureEnabled()
But after many cases of usage RecyclerView I strongly recommend not to use it in wrapping mode, cause this is not what it is intended for. Try to refactor whole your layout using normal single RecyclerView with several items' types. Or use approach with LinearLayout that I described below as last resort
Old answer (not recommended)
You can use RecyclerView inside NestedScrollView.
First of all you should implement your own custom LinearLayoutManager, it makes your RecyclerView to wrap its content.
For example:
public class WrappingLinearLayoutManager extends LinearLayoutManager
{
public WrappingLinearLayoutManager(Context context) {
super(context);
}
private int[] mMeasuredDimension = new int[2];
#Override
public boolean canScrollVertically() {
return false;
}
#Override
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,
int widthSpec, int heightSpec) {
final int widthMode = View.MeasureSpec.getMode(widthSpec);
final int heightMode = View.MeasureSpec.getMode(heightSpec);
final int widthSize = View.MeasureSpec.getSize(widthSpec);
final int heightSize = View.MeasureSpec.getSize(heightSpec);
int width = 0;
int height = 0;
for (int i = 0; i < getItemCount(); i++) {
if (getOrientation() == HORIZONTAL) {
measureScrapChild(recycler, i,
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
heightSpec,
mMeasuredDimension);
width = width + mMeasuredDimension[0];
if (i == 0) {
height = mMeasuredDimension[1];
}
} else {
measureScrapChild(recycler, i,
widthSpec,
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
mMeasuredDimension);
height = height + mMeasuredDimension[1];
if (i == 0) {
width = mMeasuredDimension[0];
}
}
}
switch (widthMode) {
case View.MeasureSpec.EXACTLY:
width = widthSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}
switch (heightMode) {
case View.MeasureSpec.EXACTLY:
height = heightSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}
setMeasuredDimension(width, height);
}
private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
int heightSpec, int[] measuredDimension) {
View view = recycler.getViewForPosition(position);
if (view.getVisibility() == View.GONE) {
measuredDimension[0] = 0;
measuredDimension[1] = 0;
return;
}
// For adding Item Decor Insets to view
super.measureChildWithMargins(view, 0, 0);
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
int childWidthSpec = ViewGroup.getChildMeasureSpec(
widthSpec,
getPaddingLeft() + getPaddingRight() + getDecoratedLeft(view) + getDecoratedRight(view),
p.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(
heightSpec,
getPaddingTop() + getPaddingBottom() + getDecoratedTop(view) + getDecoratedBottom(view),
p.height);
view.measure(childWidthSpec, childHeightSpec);
// Get decorated measurements
measuredDimension[0] = getDecoratedMeasuredWidth(view) + p.leftMargin + p.rightMargin;
measuredDimension[1] = getDecoratedMeasuredHeight(view) + p.bottomMargin + p.topMargin;
recycler.recycleView(view);
}
}
After that use this LayoutManager for your RecyclerView
recyclerView.setLayoutManager(new WrappingLinearLayoutManager(getContext()));
But you also should call those two methods:
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(false);
Here setNestedScrollingEnabled(false) disable scrolling for RecyclerView, so it doesn't intercept scrolling event from NestedScrollView. And setHasFixedSize(false) determine that changes in adapter content can change the size of the RecyclerView
Important note: This solution is little buggy in some cases and has problems with perfomance, so if you have a lot of items in your RecyclerView I'd recommend to use custom LinearLayout-based implementation of list view, create analogue of Adapter for it and make it behave like ListView or RecyclerView
You can use android:fillViewport="true" to make NestedScrollView measure the RecyclerView. The RecyclerView will fill the remaining height. so if you want to scroll the NestScrollView, you can set the RecyclerView's minHeight.
Simply adding recyclerView.setNestedScrollingEnabled(false); before setAdapter itself worked for me. I didn't add app:layout_behavior="#string/appbar_scrolling_view_behavior" anywhere & didn't set any custom layout manager
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:text="Some Text..."
android:padding="15dp" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:padding="15dp"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Quick Links"
android:textColor="#color/black"
android:textStyle="bold"
android:textAllCaps="true"
android:paddingLeft="20dp"
android:drawableLeft="#drawable/ic_trending_up_black_24dp"
android:drawablePadding="10dp"
android:layout_marginBottom="10dp"
android:textSize="16sp"/>
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="#efefef"/>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
This is what working for me
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.v4.widget.NestedScrollView>
For androidx it's called androidx.core.widget.NestedScrollView - and it scrolls alike butter with properties isScrollContainer and measureAllChildren enabled:
<!-- Scrolling Content -->
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:isScrollContainer="true"
android:measureAllChildren="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fastScrollEnabled="true"
android:scrollbarStyle="insideInset"
android:scrollbars="vertical"
android:splitMotionEvents="false"
android:verticalScrollbarPosition="right"/>
</androidx.core.widget.NestedScrollView>
There is a simple and testing code u may check
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.NestedScrollView>
I used RecyclerView inside a NestedScrollView and it worked for me. The only gotcha I had to keep in mind was that a NestedScrollView takes only one child view. So in my case I used of LienearLayout viewgroup which was housing my RecyclerView plus a number of other views that I needed.
I experience one issue putting my RecyclerView inside the NestedScrollView. I realized that scrolling the content of my RecyclerView slacked.
I later realized that my RecyclerView was receiving the scrolling event and therefore was conflicting with the scrolling behavior of the NestedScrollView.
So to solve that problem, I had to disable the scroll functionality of my RecyclerView with this method movieListNewRecyclerView.setNestedScrollingEnabled(false);
You can checkout my Instagram for a short video of what I actually did. This is my instagram handle ofelix03
Try to use this library - https://github.com/serso/android-linear-layout-manager.
LayoutManager of the library makes RecyclerView wraps its contents. In this case RecyclerView will be "as big as inner views", so it will not have a scrollbars and user will use scrolling abilities of NestedScrollView. Therefore, it will not be ambiguous like "scrollable inside scrollable".
Here is the code that I'm using to avoid scrolling issues:
mRecyclerView = (RecyclerView) view.findViewById(android.R.id.list);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView.getLayoutManager().setAutoMeasureEnabled(true);
mRecyclerView.setNestedScrollingEnabled(false);
mRecyclerView.setHasFixedSize(false);
I have Viewpager and RecyclerView inside the NestedScrollView. After adding below lines
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(false);
I solved slow scroll and scroll lag issue.
if you want to use RecyclerView in NestedScrollView this is a simple tricky, just set :
RecyclerView
recyclerView.setHasFixedSize(false) (java/kt)
android:nestedScrollingEnabled="false"
android:layout_height="wrap_content"
android:overScrollMode="never"
NestedScrollView
android:fillViewport="true"
this is work for me, and you can use many RecyclerView in NestedScrollView with this too.
If you are using RecyclerView-23.2.1 or later. Following solution will work just fine:
In your layout add RecyclerView like this:
<android.support.v7.widget.RecyclerView
android:id="#+id/review_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" />
And in your java file:
RecyclerView mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager=new LinearLayoutManager(getContext());
layoutManager.setAutoMeasureEnabled(true);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setAdapter(new YourListAdapter(getContext()));
Here layoutManager.setAutoMeasureEnabled(true); will do the trick.
Check out this issue and this developer blog for more information.
If you are using RecyclerView ScrollListener inside NestedScrollView, addOnScrollListener listener not working properly if you are used both.
Use this code.
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(#NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
......
}
});
this code working fine RecyclerView ScrollListener inside NestedScrollView.
thanks
There are a lot of good answers. The key is that you must set nestedScrollingEnabled to false. As mentioned above you can do it in java code:
mRecyclerView.setNestedScrollingEnabled(false);
But also you have an opportunity to set the same property in xml code (android:nestedScrollingEnabled="false"):
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview"
android:nestedScrollingEnabled="false"
android:layout_width="match_parent"
android:layout_height="match_parent" />
You can't use a recycler view within a nested scroll view. It's not intended to contain further scrollable views but it's because it's a child of a scrolling layout itself that you need the nested scrolling view. I had the same issue but in the end I moved my textview to be a headerview within the recyclerview, made the recyclerview a direct child of the coordinator layout and deleted the nested scroll view. Then all my problems were gone.
One solution to keep the recycling feature of the recyclerview and avoiding the recyclerview to load all your data is setting a fix height in the recyclerview itself. By doing this the recyclerview is limited only to load as much as its height can show the user thus recycling its element if ever you scroll to the bottom/top.
do not use recyclerView inside NestedScrollView. it may cause cascading problems!
I suggest using ItemViewTypes in RecyclerView for handling multiple kinds of views.
just add a RecyclerView with match_parent width and height. then in your recyclerViewAdapter override getItemViewType and use position for handling what layout to be inflated. after that you can handle your view holder by using onBindViewHolder method.
https://stacklearn.ir
You can use my sample 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">
<LinearLayout
android:id="#+id/fl_all_brand"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".view.fragment.AllBrandFragment">
<androidx.core.widget.NestedScrollView
android:id="#+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:id="#+id/fl_all_brand1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!--<include layout="#layout/content_home" />-->
<TextView
android:id="#+id/tv_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="#dimen/_15sdp"
android:layout_marginTop="#dimen/_20sdp"
android:fontFamily="#font/lexend_semibold"
android:text="#string/DISPLAY_LIGHTS"
android:textColor="#color/gray_scale_placehold"
android:textSize="#dimen/_16ssp" />
<LinearLayout
android:id="#+id/recyclerLayout"
android:layout_width="match_parent"
android:layout_height="#dimen/_280sdp">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerviewobj"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="#dimen/_10sdp"
android:layout_marginTop="#dimen/_20sdp"
android:layout_marginEnd="#dimen/_10sdp"
android:orientation="horizontal"
android:nestedScrollingEnabled="false"
android:layout_marginBottom="#dimen/_20sdp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
/>
</LinearLayout>
<TextView
android:id="#+id/notfound"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="#dimen/_15sdp"
android:layout_marginTop="#dimen/_20sdp"
android:layout_marginBottom="#dimen/_20sdp"
android:fontFamily="#font/lexend_semibold"
android:text="#string/DISPLAY_LIGHTS"
android:gravity="center"
android:visibility="gone"
android:textColor="?attr/hintTextColors"
android:textSize="#dimen/_12ssp" />
<TextView
android:id="#+id/recommendTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/addDeviceLayout"
android:layout_below="#+id/recyclerviewobj"
android:layout_marginStart="#dimen/_16sdp"
android:layout_marginTop="#dimen/_7sdp"
android:fontFamily="#font/lexend_semibold"
android:text="#string/RECOMMENDATION"
android:textColor="#color/gray_scale_placehold"
android:textSize="#dimen/_16ssp" />
<LinearLayout
android:id="#+id/addDeviceLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/createRoomLayout"
android:layout_marginTop="#dimen/_14sdp"
android:background="?attr/buttonTextColor"
android:orientation="vertical"
tools:visibility="visible">
<ImageView
android:id="#+id/addBtn"
android:layout_width="#dimen/_28sdp"
android:layout_height="#dimen/_28sdp"
android:layout_marginStart="#dimen/_16sdp"
android:layout_marginTop="#dimen/_8sdp"
android:src="#drawable/ic_thermostates_icon"
app:tint="?attr/colorPrimaryDark" />
<TextView
android:id="#+id/addDevice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/_16sdp"
android:layout_marginTop="#dimen/_5sdp"
android:fontFamily="#font/lexend_bold"
android:text="#string/PROGRAM_DISPLAY_SENSOR_PLUGS"
android:textColor="?attr/colorPrimaryDark"
android:textSize="#dimen/_12ssp" />
<TextView
android:id="#+id/summry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/_16sdp"
android:layout_marginTop="#dimen/_8sdp"
android:layout_marginBottom="#dimen/_6sdp"
android:fontFamily="#font/lexend_medium"
android:text="#string/DISPLAY_SENSOR_SUB_TITLE"
android:textColor="?attr/secondaryTextColor"
android:textSize="#dimen/_9ssp" />
<RelativeLayout
android:id="#+id/container3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/_6sdp"
android:layout_marginTop="#dimen/_6sdp"
android:layout_marginBottom="#dimen/_10sdp">
<TextView
android:id="#+id/get_started"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="#dimen/_10sdp"
android:fontFamily="#font/lexend_semibold"
android:text="#string/RECOMMENDED_GROUP"
android:textAllCaps="true"
android:textSize="#dimen/_9ssp" />
<ImageView
android:id="#+id/forward_arrow"
android:layout_width="#dimen/_16sdp"
android:layout_height="#dimen/_16sdp"
android:layout_alignParentEnd="true"
android:layout_marginRight="#dimen/_20sdp"
android:src="#drawable/ic_forward_arrow"
app:tint="?attr/colorPrimary" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/createRoomLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginTop="#dimen/_9sdp"
android:layout_marginBottom="#dimen/_20sdp"
android:background="?attr/buttonTextColor"
android:orientation="vertical"
tools:visibility="visible">
<ImageView
android:id="#+id/addBtnRoom"
android:layout_width="#dimen/_28sdp"
android:layout_height="#dimen/_28sdp"
android:layout_marginStart="#dimen/_16sdp"
android:layout_marginTop="#dimen/_8sdp"
android:src="#drawable/rgb_light_new"
app:tint="?attr/colorPrimaryDark" />
<TextView
android:id="#+id/addRooms"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/_16sdp"
android:layout_marginTop="#dimen/_5sdp"
android:fontFamily="#font/lexend_bold"
android:text="#string/DISPLAY_RGBW"
android:textColor="?attr/colorPrimaryDark"
android:textSize="#dimen/_12ssp" />
<TextView
android:id="#+id/summry1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/_16sdp"
android:layout_marginTop="#dimen/_8sdp"
android:layout_marginBottom="#dimen/_6sdp"
android:fontFamily="#font/lexend_medium"
android:text="#string/PROGRAM_DISPLAY_RGB_MSG"
android:textColor="?attr/secondaryTextColor"
android:textSize="#dimen/_9ssp" />
<RelativeLayout
android:id="#+id/container99"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/_6sdp"
android:layout_marginTop="#dimen/_6sdp"
android:layout_marginBottom="#dimen/_10sdp">
<TextView
android:id="#+id/get_started_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="#dimen/_10sdp"
android:fontFamily="#font/lexend_semibold"
android:text="#string/RECOMMENDED_GROUP"
android:textAllCaps="true"
android:textSize="#dimen/_9ssp" />
<ImageView
android:id="#+id/forward_arrow1"
android:layout_width="#dimen/_16sdp"
android:layout_height="#dimen/_16sdp"
android:layout_alignParentEnd="true"
android:layout_marginRight="#dimen/_20sdp"
android:src="#drawable/ic_forward_arrow"
app:tint="?attr/colorPrimary" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
</layout>
here use this property of recyclerview
app:layout_behavior="#string/appbar_scrolling_view_behavior"
and turned off recyclerview nested scrolling like this
android:nestedScrollingEnabled="false"
I had to implement CoordinatorLayout with toolbar scrolling and it just took me all the day messing around this. I've got it working by removing NestedScrollView at all. So I'm just using RelativeLayout at the root.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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.support.v7.widget.RecyclerView
android:id="#+id/rv_nearby"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</RelativeLayout>
nestedScrollView.setNestedScrollingEnabled(true);
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
//...
}
});
<androidx.core.widget.NestedScrollView
android:id="#+id/nested"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:layout_below="#id/appBarLayout_orders"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<androidx.constraintlayout.widget.ConstraintLayout ...
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
In my case, this is what works for me
Put android:fillViewport="true" inside NestedScrollView.
Make the height of RecyclerView to wrap_content, i.e android:layout_height="wrap_content"
Add this in RecyclerView android:nestedScrollingEnabled="false"
OR
Programmatically, in your Kotlin class
recyclerView.isNestedScrollingEnabled = false
mRecyclerView.setHasFixedSize(false)
For my case the child of NestedScrollview is ConstraintLayout. It is not working as expected i replaced it to LinearLayout. Maybe it helps someone.
<androidx.core.widget.NestedScrollView
android:id="#+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
I have used this awesome extension (written in kotlin but can be also used in Java)
https://github.com/Widgetlabs/expedition-nestedscrollview
Basically you get the NestedRecyclerView inside any package lets say utils in your project, then just create your recyclerview like
<com.your_package.utils.NestedRecyclerView
android:id="#+id/rv_test"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Check this awesome article by Marc Knaup
https://medium.com/widgetlabs-engineering/scrollable-nestedscrollviews-inside-recyclerview-ca65050d828a
At least as far back as Material Components 1.3.0-alpha03, it doesn't matter if the RecyclerView is nested (in something other than a ScrollView or NestedScrollView). Just put app:layout_behavior="#string/appbar_scrolling_view_behavior" on its top level parent that's a sibling of the AppBarLayout in the CoordinatorLayout.
This has been working for me when using a single Activity architecture with Jetpack Naviagation, where all Fragments are sharing the same AppBar from the Activity's layout. I make the FragmentContainer the direct child of the CoordinatorLayout that also contains the AppBarLayout, like below. The RecyclerViews in the various fragments are scrolling normally and the AppBar folds away and reappears as expected.
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:defaultNavHost="true"
app:navGraph="#navigation/mobile_navigation"/>
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:liftOnScroll="true">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:layout_scrollFlags="scroll|enterAlways|snap" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
liftOnScroll (used to for app bars to look like they have zero elevation when at the top of the page) works if each fragment passes the ID of its RecyclerView to AppBarLayout.liftOnScrollTargetViewId in Fragment.onResume. Or pass 0 if the Fragment doesn't scroll.
RecyclerView with NestedScrollView
<android.support.v7.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
I wrote an application and home page is LinearLayout and is in Fragment. In this LinearLayout there are two RecyclerViews and SearchBar etc. I want to scroll whole activity. I spent 2 days for it but cannot succeed. How can I do that in easy way? There are lots of adapters and connections in that LinearLayout. How can I achieve that without broke any code.
I want to scroll whole activity.
Thanks in advance.
Set Scroll/NestedScrollView as a parent view in xml to scroll whole layout.
Add below attribute in recycler view to stop recycler scroll:
android:overScrollMode="never"
Try below code:
<android.support.v4.widget.NestedScrollView
android:id="#+id/navigation_nested"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="#dimen/margin_15">
<TextView
android:id="#+id/video_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/margin_15"
android:drawableLeft="#drawable/ic_video_tutorial"
android:drawablePadding="#dimen/margin_20"
android:fontFamily="#font/poppins"
android:paddingLeft="#dimen/text_15"
android:text="#string/videos"
android:textColor="#color/blackTextColor"
android:textSize="#dimen/text_15" />
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
You just add this line:
//java
yourRecyclerView.setLayouManager(new LinearLayoutManager(this));
//kotlin
yourRecyclerView.layoutManager = LinearLayoutManager(this)
or from xml:
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
Notice that there is not only LinearLayoutManager. If you are using a Grid RecyclerView than you might want to use GridLayoutManager
I solved the problem.
Just write ScrollView over the LinearLayout
<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">
<LinearLayout>
.....
</LinearLayout>
</ScrollView>
Basically i have implemented recyclerview in nested scroll view which contains the arc seek bar in each item of recyclerview. So when i move seekbar recyclerview is also scrolling.
I tried using nestedscrollview and focusableInTouchMode option but did not worked.
device_list.apply {
device_list.layoutManager = GridLayoutManager(this#RoomActivity, 2)
device_list.adapter = DeviceAdapter()
}
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?android:attr/actionBarSize"
android:background="#color/colorWhite">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/device_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/marginSemiGlobal"
android:layout_marginBottom="#dimen/marginSemiGlobal"
android:overScrollMode="never"
android:nestedScrollingEnabled="false"
android:scrollbars="none" />
</androidx.core.widget.NestedScrollView>
<com.marcinmoskala.arcseekbar.ArcSeekBar
app:roundEdges="true"
android:layout_width="match_parent"
android:layout_below="#+id/top_layout"
app:progressBackgroundColor="#color/colorProgressBackground"
app:progressBackgroundWidth="8dp"
app:progressColor="#color/colorProgress"
android:id="#+id/dimmer"
app:progressWidth="8dp"
android:layout_height="100dp"
app:thumb="#drawable/ic_progress_thumb"
android:layout_centerHorizontal="true" />
I tried setting setNestedScrollview to ViewCompact and also used focus in touch mode but output was same.
How to use RecyclerView inside NestedScrollView?
RecyclerView content is not visible after setting adapter.
UPDATE layout code updated.
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/keyline_1">
</RelativeLayout>
<View
android:id="#+id/separator"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#e5e5e5" />
<android.support.v7.widget.RecyclerView
android:id="#+id/conversation"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
Replace your recyclerView with,
<android.support.v7.widget.RecyclerView
android:id="#+id/conversation"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
here,
app:layout_behavior="#string/appbar_scrolling_view_behavior"
will manage the rest of things.
One more thing, no need to put your recyclerView inside NestedScrollView
You need to use support library 23.2.0 (or) above
and RecyclerView height will be wrap_content.
recyclerView.setNestedScrollingEnabled(false)
But by doing this the recycler pattern doesn't work. (i.e all the views will be loaded at once because wrap_content needs the height of complete RecyclerView so it will draw all child Views at once. No view will be recycled). Try not to use this pattern unless it is really required. Try to use viewType and add all other views that need to scroll to RecyclerView rather than using RecyclerView in Scrollview. The performance impact will be very high.
To make it simple "it just acts as LinearLayout with all the child views"
UPDATE 1
Since Android Support Library 23.2.0 there were added method setAutoMeasureEnabled(true) for LayoutManagers. It makes RecyclerView to wrap it's content and works like a charm.
http://android-developers.blogspot.ru/2016/02/android-support-library-232.html
So just add something like this:
LayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setAutoMeasureEnabled(true);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setNestedScrollingEnabled(false);
UPDATE 2
Since 27.1.0 setAutoMeasureEnabled is deprecated, so you should provide custom implementation of LayoutManager with overridden method isAutoMeasureEnabled()
But after many cases of usage RecyclerView I strongly recommend not to use it in wrapping mode, cause this is not what it is intended for. Try to refactor whole your layout using normal single RecyclerView with several items' types. Or use approach with LinearLayout that I described below as last resort
Old answer (not recommended)
You can use RecyclerView inside NestedScrollView.
First of all you should implement your own custom LinearLayoutManager, it makes your RecyclerView to wrap its content.
For example:
public class WrappingLinearLayoutManager extends LinearLayoutManager
{
public WrappingLinearLayoutManager(Context context) {
super(context);
}
private int[] mMeasuredDimension = new int[2];
#Override
public boolean canScrollVertically() {
return false;
}
#Override
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,
int widthSpec, int heightSpec) {
final int widthMode = View.MeasureSpec.getMode(widthSpec);
final int heightMode = View.MeasureSpec.getMode(heightSpec);
final int widthSize = View.MeasureSpec.getSize(widthSpec);
final int heightSize = View.MeasureSpec.getSize(heightSpec);
int width = 0;
int height = 0;
for (int i = 0; i < getItemCount(); i++) {
if (getOrientation() == HORIZONTAL) {
measureScrapChild(recycler, i,
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
heightSpec,
mMeasuredDimension);
width = width + mMeasuredDimension[0];
if (i == 0) {
height = mMeasuredDimension[1];
}
} else {
measureScrapChild(recycler, i,
widthSpec,
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
mMeasuredDimension);
height = height + mMeasuredDimension[1];
if (i == 0) {
width = mMeasuredDimension[0];
}
}
}
switch (widthMode) {
case View.MeasureSpec.EXACTLY:
width = widthSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}
switch (heightMode) {
case View.MeasureSpec.EXACTLY:
height = heightSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}
setMeasuredDimension(width, height);
}
private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
int heightSpec, int[] measuredDimension) {
View view = recycler.getViewForPosition(position);
if (view.getVisibility() == View.GONE) {
measuredDimension[0] = 0;
measuredDimension[1] = 0;
return;
}
// For adding Item Decor Insets to view
super.measureChildWithMargins(view, 0, 0);
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
int childWidthSpec = ViewGroup.getChildMeasureSpec(
widthSpec,
getPaddingLeft() + getPaddingRight() + getDecoratedLeft(view) + getDecoratedRight(view),
p.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(
heightSpec,
getPaddingTop() + getPaddingBottom() + getDecoratedTop(view) + getDecoratedBottom(view),
p.height);
view.measure(childWidthSpec, childHeightSpec);
// Get decorated measurements
measuredDimension[0] = getDecoratedMeasuredWidth(view) + p.leftMargin + p.rightMargin;
measuredDimension[1] = getDecoratedMeasuredHeight(view) + p.bottomMargin + p.topMargin;
recycler.recycleView(view);
}
}
After that use this LayoutManager for your RecyclerView
recyclerView.setLayoutManager(new WrappingLinearLayoutManager(getContext()));
But you also should call those two methods:
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(false);
Here setNestedScrollingEnabled(false) disable scrolling for RecyclerView, so it doesn't intercept scrolling event from NestedScrollView. And setHasFixedSize(false) determine that changes in adapter content can change the size of the RecyclerView
Important note: This solution is little buggy in some cases and has problems with perfomance, so if you have a lot of items in your RecyclerView I'd recommend to use custom LinearLayout-based implementation of list view, create analogue of Adapter for it and make it behave like ListView or RecyclerView
You can use android:fillViewport="true" to make NestedScrollView measure the RecyclerView. The RecyclerView will fill the remaining height. so if you want to scroll the NestScrollView, you can set the RecyclerView's minHeight.
Simply adding recyclerView.setNestedScrollingEnabled(false); before setAdapter itself worked for me. I didn't add app:layout_behavior="#string/appbar_scrolling_view_behavior" anywhere & didn't set any custom layout manager
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#color/white"
android:text="Some Text..."
android:padding="15dp" />
</LinearLayout>
<LinearLayout
android:orientation="vertical"
android:padding="15dp"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Quick Links"
android:textColor="#color/black"
android:textStyle="bold"
android:textAllCaps="true"
android:paddingLeft="20dp"
android:drawableLeft="#drawable/ic_trending_up_black_24dp"
android:drawablePadding="10dp"
android:layout_marginBottom="10dp"
android:textSize="16sp"/>
<View
android:layout_width="fill_parent"
android:layout_height="1dp"
android:background="#efefef"/>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
This is what working for me
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:id="#+id/rv_recycler_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</android.support.v4.widget.NestedScrollView>
For androidx it's called androidx.core.widget.NestedScrollView - and it scrolls alike butter with properties isScrollContainer and measureAllChildren enabled:
<!-- Scrolling Content -->
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:isScrollContainer="true"
android:measureAllChildren="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fastScrollEnabled="true"
android:scrollbarStyle="insideInset"
android:scrollbars="vertical"
android:splitMotionEvents="false"
android:verticalScrollbarPosition="right"/>
</androidx.core.widget.NestedScrollView>
There is a simple and testing code u may check
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</android.support.v4.widget.NestedScrollView>
I used RecyclerView inside a NestedScrollView and it worked for me. The only gotcha I had to keep in mind was that a NestedScrollView takes only one child view. So in my case I used of LienearLayout viewgroup which was housing my RecyclerView plus a number of other views that I needed.
I experience one issue putting my RecyclerView inside the NestedScrollView. I realized that scrolling the content of my RecyclerView slacked.
I later realized that my RecyclerView was receiving the scrolling event and therefore was conflicting with the scrolling behavior of the NestedScrollView.
So to solve that problem, I had to disable the scroll functionality of my RecyclerView with this method movieListNewRecyclerView.setNestedScrollingEnabled(false);
You can checkout my Instagram for a short video of what I actually did. This is my instagram handle ofelix03
Try to use this library - https://github.com/serso/android-linear-layout-manager.
LayoutManager of the library makes RecyclerView wraps its contents. In this case RecyclerView will be "as big as inner views", so it will not have a scrollbars and user will use scrolling abilities of NestedScrollView. Therefore, it will not be ambiguous like "scrollable inside scrollable".
Here is the code that I'm using to avoid scrolling issues:
mRecyclerView = (RecyclerView) view.findViewById(android.R.id.list);
mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
mRecyclerView.getLayoutManager().setAutoMeasureEnabled(true);
mRecyclerView.setNestedScrollingEnabled(false);
mRecyclerView.setHasFixedSize(false);
I have Viewpager and RecyclerView inside the NestedScrollView. After adding below lines
recyclerView.setNestedScrollingEnabled(false);
recyclerView.setHasFixedSize(false);
I solved slow scroll and scroll lag issue.
if you want to use RecyclerView in NestedScrollView this is a simple tricky, just set :
RecyclerView
recyclerView.setHasFixedSize(false) (java/kt)
android:nestedScrollingEnabled="false"
android:layout_height="wrap_content"
android:overScrollMode="never"
NestedScrollView
android:fillViewport="true"
this is work for me, and you can use many RecyclerView in NestedScrollView with this too.
If you are using RecyclerView-23.2.1 or later. Following solution will work just fine:
In your layout add RecyclerView like this:
<android.support.v7.widget.RecyclerView
android:id="#+id/review_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical" />
And in your java file:
RecyclerView mRecyclerView = (RecyclerView) view.findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager=new LinearLayoutManager(getContext());
layoutManager.setAutoMeasureEnabled(true);
mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setAdapter(new YourListAdapter(getContext()));
Here layoutManager.setAutoMeasureEnabled(true); will do the trick.
Check out this issue and this developer blog for more information.
If you are using RecyclerView ScrollListener inside NestedScrollView, addOnScrollListener listener not working properly if you are used both.
Use this code.
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(#NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
......
}
});
this code working fine RecyclerView ScrollListener inside NestedScrollView.
thanks
There are a lot of good answers. The key is that you must set nestedScrollingEnabled to false. As mentioned above you can do it in java code:
mRecyclerView.setNestedScrollingEnabled(false);
But also you have an opportunity to set the same property in xml code (android:nestedScrollingEnabled="false"):
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview"
android:nestedScrollingEnabled="false"
android:layout_width="match_parent"
android:layout_height="match_parent" />
You can't use a recycler view within a nested scroll view. It's not intended to contain further scrollable views but it's because it's a child of a scrolling layout itself that you need the nested scrolling view. I had the same issue but in the end I moved my textview to be a headerview within the recyclerview, made the recyclerview a direct child of the coordinator layout and deleted the nested scroll view. Then all my problems were gone.
One solution to keep the recycling feature of the recyclerview and avoiding the recyclerview to load all your data is setting a fix height in the recyclerview itself. By doing this the recyclerview is limited only to load as much as its height can show the user thus recycling its element if ever you scroll to the bottom/top.
do not use recyclerView inside NestedScrollView. it may cause cascading problems!
I suggest using ItemViewTypes in RecyclerView for handling multiple kinds of views.
just add a RecyclerView with match_parent width and height. then in your recyclerViewAdapter override getItemViewType and use position for handling what layout to be inflated. after that you can handle your view holder by using onBindViewHolder method.
https://stacklearn.ir
You can use my sample 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">
<LinearLayout
android:id="#+id/fl_all_brand"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".view.fragment.AllBrandFragment">
<androidx.core.widget.NestedScrollView
android:id="#+id/parent"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:id="#+id/fl_all_brand1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!--<include layout="#layout/content_home" />-->
<TextView
android:id="#+id/tv_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="#dimen/_15sdp"
android:layout_marginTop="#dimen/_20sdp"
android:fontFamily="#font/lexend_semibold"
android:text="#string/DISPLAY_LIGHTS"
android:textColor="#color/gray_scale_placehold"
android:textSize="#dimen/_16ssp" />
<LinearLayout
android:id="#+id/recyclerLayout"
android:layout_width="match_parent"
android:layout_height="#dimen/_280sdp">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerviewobj"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="#dimen/_10sdp"
android:layout_marginTop="#dimen/_20sdp"
android:layout_marginEnd="#dimen/_10sdp"
android:orientation="horizontal"
android:nestedScrollingEnabled="false"
android:layout_marginBottom="#dimen/_20sdp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
/>
</LinearLayout>
<TextView
android:id="#+id/notfound"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="#dimen/_15sdp"
android:layout_marginTop="#dimen/_20sdp"
android:layout_marginBottom="#dimen/_20sdp"
android:fontFamily="#font/lexend_semibold"
android:text="#string/DISPLAY_LIGHTS"
android:gravity="center"
android:visibility="gone"
android:textColor="?attr/hintTextColors"
android:textSize="#dimen/_12ssp" />
<TextView
android:id="#+id/recommendTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/addDeviceLayout"
android:layout_below="#+id/recyclerviewobj"
android:layout_marginStart="#dimen/_16sdp"
android:layout_marginTop="#dimen/_7sdp"
android:fontFamily="#font/lexend_semibold"
android:text="#string/RECOMMENDATION"
android:textColor="#color/gray_scale_placehold"
android:textSize="#dimen/_16ssp" />
<LinearLayout
android:id="#+id/addDeviceLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/createRoomLayout"
android:layout_marginTop="#dimen/_14sdp"
android:background="?attr/buttonTextColor"
android:orientation="vertical"
tools:visibility="visible">
<ImageView
android:id="#+id/addBtn"
android:layout_width="#dimen/_28sdp"
android:layout_height="#dimen/_28sdp"
android:layout_marginStart="#dimen/_16sdp"
android:layout_marginTop="#dimen/_8sdp"
android:src="#drawable/ic_thermostates_icon"
app:tint="?attr/colorPrimaryDark" />
<TextView
android:id="#+id/addDevice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/_16sdp"
android:layout_marginTop="#dimen/_5sdp"
android:fontFamily="#font/lexend_bold"
android:text="#string/PROGRAM_DISPLAY_SENSOR_PLUGS"
android:textColor="?attr/colorPrimaryDark"
android:textSize="#dimen/_12ssp" />
<TextView
android:id="#+id/summry"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/_16sdp"
android:layout_marginTop="#dimen/_8sdp"
android:layout_marginBottom="#dimen/_6sdp"
android:fontFamily="#font/lexend_medium"
android:text="#string/DISPLAY_SENSOR_SUB_TITLE"
android:textColor="?attr/secondaryTextColor"
android:textSize="#dimen/_9ssp" />
<RelativeLayout
android:id="#+id/container3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/_6sdp"
android:layout_marginTop="#dimen/_6sdp"
android:layout_marginBottom="#dimen/_10sdp">
<TextView
android:id="#+id/get_started"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="#dimen/_10sdp"
android:fontFamily="#font/lexend_semibold"
android:text="#string/RECOMMENDED_GROUP"
android:textAllCaps="true"
android:textSize="#dimen/_9ssp" />
<ImageView
android:id="#+id/forward_arrow"
android:layout_width="#dimen/_16sdp"
android:layout_height="#dimen/_16sdp"
android:layout_alignParentEnd="true"
android:layout_marginRight="#dimen/_20sdp"
android:src="#drawable/ic_forward_arrow"
app:tint="?attr/colorPrimary" />
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/createRoomLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginTop="#dimen/_9sdp"
android:layout_marginBottom="#dimen/_20sdp"
android:background="?attr/buttonTextColor"
android:orientation="vertical"
tools:visibility="visible">
<ImageView
android:id="#+id/addBtnRoom"
android:layout_width="#dimen/_28sdp"
android:layout_height="#dimen/_28sdp"
android:layout_marginStart="#dimen/_16sdp"
android:layout_marginTop="#dimen/_8sdp"
android:src="#drawable/rgb_light_new"
app:tint="?attr/colorPrimaryDark" />
<TextView
android:id="#+id/addRooms"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/_16sdp"
android:layout_marginTop="#dimen/_5sdp"
android:fontFamily="#font/lexend_bold"
android:text="#string/DISPLAY_RGBW"
android:textColor="?attr/colorPrimaryDark"
android:textSize="#dimen/_12ssp" />
<TextView
android:id="#+id/summry1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/_16sdp"
android:layout_marginTop="#dimen/_8sdp"
android:layout_marginBottom="#dimen/_6sdp"
android:fontFamily="#font/lexend_medium"
android:text="#string/PROGRAM_DISPLAY_RGB_MSG"
android:textColor="?attr/secondaryTextColor"
android:textSize="#dimen/_9ssp" />
<RelativeLayout
android:id="#+id/container99"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/_6sdp"
android:layout_marginTop="#dimen/_6sdp"
android:layout_marginBottom="#dimen/_10sdp">
<TextView
android:id="#+id/get_started_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginStart="#dimen/_10sdp"
android:fontFamily="#font/lexend_semibold"
android:text="#string/RECOMMENDED_GROUP"
android:textAllCaps="true"
android:textSize="#dimen/_9ssp" />
<ImageView
android:id="#+id/forward_arrow1"
android:layout_width="#dimen/_16sdp"
android:layout_height="#dimen/_16sdp"
android:layout_alignParentEnd="true"
android:layout_marginRight="#dimen/_20sdp"
android:src="#drawable/ic_forward_arrow"
app:tint="?attr/colorPrimary" />
</RelativeLayout>
</LinearLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</LinearLayout>
</layout>
here use this property of recyclerview
app:layout_behavior="#string/appbar_scrolling_view_behavior"
and turned off recyclerview nested scrolling like this
android:nestedScrollingEnabled="false"
I had to implement CoordinatorLayout with toolbar scrolling and it just took me all the day messing around this. I've got it working by removing NestedScrollView at all. So I'm just using RelativeLayout at the root.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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.support.v7.widget.RecyclerView
android:id="#+id/rv_nearby"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</RelativeLayout>
nestedScrollView.setNestedScrollingEnabled(true);
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
//...
}
});
<androidx.core.widget.NestedScrollView
android:id="#+id/nested"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:layout_below="#id/appBarLayout_orders"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<androidx.constraintlayout.widget.ConstraintLayout ...
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recycler"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
In my case, this is what works for me
Put android:fillViewport="true" inside NestedScrollView.
Make the height of RecyclerView to wrap_content, i.e android:layout_height="wrap_content"
Add this in RecyclerView android:nestedScrollingEnabled="false"
OR
Programmatically, in your Kotlin class
recyclerView.isNestedScrollingEnabled = false
mRecyclerView.setHasFixedSize(false)
For my case the child of NestedScrollview is ConstraintLayout. It is not working as expected i replaced it to LinearLayout. Maybe it helps someone.
<androidx.core.widget.NestedScrollView
android:id="#+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
I have used this awesome extension (written in kotlin but can be also used in Java)
https://github.com/Widgetlabs/expedition-nestedscrollview
Basically you get the NestedRecyclerView inside any package lets say utils in your project, then just create your recyclerview like
<com.your_package.utils.NestedRecyclerView
android:id="#+id/rv_test"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Check this awesome article by Marc Knaup
https://medium.com/widgetlabs-engineering/scrollable-nestedscrollviews-inside-recyclerview-ca65050d828a
At least as far back as Material Components 1.3.0-alpha03, it doesn't matter if the RecyclerView is nested (in something other than a ScrollView or NestedScrollView). Just put app:layout_behavior="#string/appbar_scrolling_view_behavior" on its top level parent that's a sibling of the AppBarLayout in the CoordinatorLayout.
This has been working for me when using a single Activity architecture with Jetpack Naviagation, where all Fragments are sharing the same AppBar from the Activity's layout. I make the FragmentContainer the direct child of the CoordinatorLayout that also contains the AppBarLayout, like below. The RecyclerViews in the various fragments are scrolling normally and the AppBar folds away and reappears as expected.
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="#+id/coordinatorLayout"
android:layout_width="match_parent"
android:layout_height="match_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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
app:defaultNavHost="true"
app:navGraph="#navigation/mobile_navigation"/>
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/appbar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:liftOnScroll="true">
<androidx.appcompat.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme"
app:layout_scrollFlags="scroll|enterAlways|snap" />
</com.google.android.material.appbar.AppBarLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
liftOnScroll (used to for app bars to look like they have zero elevation when at the top of the page) works if each fragment passes the ID of its RecyclerView to AppBarLayout.liftOnScrollTargetViewId in Fragment.onResume. Or pass 0 if the Fragment doesn't scroll.
RecyclerView with NestedScrollView
<android.support.v7.widget.RecyclerView
android:id="#+id/rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />