How to scroll whole activity - android

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>

Related

Nested RecyclerView with nestedscrollview is not scrolling

I have a row that has a recyclerview inside another recyclerview, like this image
I need the inner recyclerview to be able to scroll it, I have tried this (this is inside a ConstrainLayout)
<androidx.core.widget.NestedScrollView
android:id="#+id/nested_scroll"
android:layout_width="match_parent"
android:layout_height="150dp"
android:fillViewport="true"
app:layout_constraintTop_toBottomOf="#+id/constraintLayout">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/rv_order_items"
android:layout_width="match_parent"
android:layout_height="0dp" />
</androidx.core.widget.NestedScrollView>
And
rv_order_items.isNestedScrollingEnabled = true
But I cant scroll inside the inner recyclerview, any suggestion?
Please add whole code of your layout in this post so I will get idea about constraintlayout.
Otherwise this is solution if you want full screen to scroll...
Please set android:layout_height="match_parent" of NestedScrollView
<androidx.core.widget.NestedScrollView
android:id="#+id/nested_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">

RecyclerView inside Scroll View in the fragment is not working? [duplicate]

For my app I am using a RecyclerView inside a ScrollView where the RecyclerView has a height based on its content using this library. Scrolling is working but it's not working smoothly when I scroll over the RecyclerView. When I scroll over the ScrollView itself it is scrolling smoothly.
The code I am using to define the RecyclerView:
LinearLayoutManager friendsLayoutManager = new LinearLayoutManager(getActivity().getApplicationContext(), android.support.v7.widget.LinearLayoutManager.VERTICAL, false);
mFriendsListView.setLayoutManager(friendsLayoutManager);
mFriendsListView.addItemDecoration(new DividerItemDecoration(getActivity().getApplicationContext(), null));
The RecyclerView in the ScrollView:
<android.support.v7.widget.RecyclerView
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:id="#+id/friendsList"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
Try doing:
RecyclerView v = (RecyclerView) findViewById(...);
v.setNestedScrollingEnabled(false);
As an alternative, you can modify your layout using the support design library. I guess your current layout is something like:
<ScrollView >
<LinearLayout >
<View > <!-- upper content -->
<RecyclerView > <!-- with custom layoutmanager -->
</LinearLayout >
</ScrollView >
You can modify that to:
<CoordinatorLayout >
<AppBarLayout >
<CollapsingToolbarLayout >
<!-- with your content, and layout_scrollFlags="scroll" -->
</CollapsingToolbarLayout >
</AppBarLayout >
<RecyclerView > <!-- with standard layoutManager -->
</CoordinatorLayout >
However this is a longer road to take, and if you are OK with the custom linear layout manager, then just disable nested scrolling on the recycler view.
Edit (4/3/2016)
The v 23.2 release of the support libraries now includes a factory “wrap content” feature in all default LayoutManagers. I didn’t test it, but you should probably prefer it to that library you were using.
<ScrollView >
<LinearLayout >
<View > <!-- upper content -->
<RecyclerView > <!-- with wrap_content -->
</LinearLayout >
</ScrollView >
I only needed to use this:
mMyRecyclerView.setNestedScrollingEnabled(false);
in my onCreateView() method.
Thanks a lot!
You can use this way either :
Add this line to your recyclerView xml file :
android:nestedScrollingEnabled="false"
Or in java code :
RecyclerView.setNestedScrollingEnabled(false);
Hope this helped .
You can try with both the ways with XML and programmatically. But the issue you may face is (below API 21) by doing it with XML will not work . So it's better to set it programmatically in your Activity / Fragment.
XML code:
<android.support.v7.widget.RecyclerView
android:id="#+id/recycleView"
android:layout_width="match_parent"
android:visibility="gone"
android:nestedScrollingEnabled="false"
android:layout_height="wrap_content"
android:layout_below="#+id/linearLayoutBottomText" />
Programmatically:
recycleView = (RecyclerView) findViewById(R.id.recycleView);
recycleView.setNestedScrollingEnabled(false);
Using Nested Scroll View instead of Scroll View solved my problem
<LinearLayout> <!--Main Layout -->
<android.support.v4.widget.NestedScrollView>
<LinearLayout > <!--Nested Scoll View enclosing Layout -->`
<View > <!-- upper content -->
<RecyclerView >
</LinearLayout >
</android.support.v4.widget.NestedScrollView>
</LinearLayout>
I had similar issues (I tried to create a nested RecyclerViews something like Google PlayStore design). The best way to deal with this is by subclassing the child RecyclerViews and overriding the 'onInterceptTouchEvent' and 'onTouchEvent' methods. This way you get complete control of how those events behave and eventually scrolling.
Replacing ScrollView with NestedScrollView resulted into smooth scrolling to the bottom.
Summary of all answers (Advantages & Disadvantages)
For single recyclerview
you can use it inside Coordinator layout.
Advantage - it will not load entire recyclerview items. So smooth loading.
Disadvantage - you can't load two recyclerview inside Coordinator layout - it produce scrolling problems
reference - https://stackoverflow.com/a/33143512/3879847
For multiple recylerview with minimum rows
you can load inside NestedScrollView
Advantage - it will scroll smoothly
Disadvantage - It load all rows of recyclerview so your activity open with delay
reference - https://stackoverflow.com/a/33143512/3879847
For multiple recylerview with large rows(more than 100)
You must go with recyclerview.
Advantage - Scroll smoothly, load smoothly
Disadvantage - You need to write more code and logic
Load each recylerview inside main recyclerview with help of multi-viewholders
ex:
MainRecyclerview
-ChildRecyclerview1 (ViewHolder1)
-ChildRecyclerview2 (ViewHolder2)
-ChildRecyclerview3 (ViewHolder3)
-Any other layout (ViewHolder4)
Reference for multi-viewHolder - https://stackoverflow.com/a/26245463/3879847
Kotlin
Set isNestedScrollingEnabled to false for every RecyclerView that is under the scrolling view
val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
recyclerView.isNestedScrollingEnabled = false
Using XML Layout
<android.support.v7.widget.RecyclerView
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:id="#+id/friendsList"
android:layout_width="match_parent"
android:nestedScrollingEnabled="false"
android:layout_height="wrap_content" />
Every answer is same here. and i already used what everyone is suggested. Then i found that NestedScrollView is faster then ScrollView so
use
<androidx.core.widget.NestedScrollView
Instead of
<ScrollView
And use this as usual
recycleView.setNestedScrollingEnabled(false);
If you are using VideoView or heavy weight widgets in your childviews keep your RecyclerView with height wrap_content
inside a NestedScrollView with height match_parent
Then scrolling will work smooth as perfectly as you want it.
FYI,
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:nestedScrollingEnabled="false"
android:layout_height="wrap_content"
android:clipToPadding="false" />
</android.support.v4.widget.NestedScrollView>
Thanks Micro this was from your hint!
karthik
you can use ScrollView as a parent and NestedScrollView as a child.
like this:-
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/CL1">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/eventRV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/CL1" />
</androidx.core.widget.NestedScrollView>
XML code:
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="false" />
</android.support.v4.widget.NestedScrollView>
in java code :
recycleView = (RecyclerView) findViewById(R.id.recycleView);
recycleView.setNestedScrollingEnabled(false);
Or you can just set android:focusableInTouchMode="true" in your recycler view
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<android.support.constraint.ConstraintLayout
android:id="#+id/constraintlayout_main"
android:layout_width="match_parent"
android:layout_height="#dimen/layout_width_height_fortyfive"
android:layout_marginLeft="#dimen/padding_margin_sixteen"
android:layout_marginRight="#dimen/padding_margin_sixteen"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<TextView
android:id="#+id/textview_settings"
style="#style/textviewHeaderMain"
android:gravity="start"
android:text="#string/app_name"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
<android.support.constraint.ConstraintLayout
android:id="#+id/constraintlayout_recyclerview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/padding_margin_zero"
android:layout_marginTop="#dimen/padding_margin_zero"
android:layout_marginEnd="#dimen/padding_margin_zero"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#+id/constraintlayout_main">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerview_list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:nestedScrollingEnabled="false"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.constraint.ConstraintLayout>
</android.support.v4.widget.NestedScrollView>
</android.support.constraint.ConstraintLayout>
This code is working for in ConstraintLayout android
Simple Add this line into your JAVA class
list.setNestedScrollingEnabled(false);
I myself had this issue, there is a recycler view within a scrollview and the scroll doesn't seem to be smooth. The cause for my issue was having the scrollview on top of the recycler view which was not needed for my requirement. So after I removed the scrollview and added the android:scrollbars="vertical" for recycler view, the scrolling was smooth.
After 3 days of research, I solved smooth scroll issue in my project.
The problem is <layer-list> drawable set in the background of item_user.xml file so it takes GPU time for rendering that's why scrolling not smooth. So please dont use complex <layer-list> drawable in the background of adapter item.
My problem is solved by above solution, below option is not useful for me
setNestedScrollingEnabled
setHasFixedSize
setItemViewCacheSize

ItemDecoration doesn't work inside NestedScrollView

I have implemented RecyclerView with sticky headers and I did it through ItemDecoration.
It works as expected in the case of stand-alone recycler view.
<LinearLayout ...>
<androidx.recyclerview.widget.RecyclerView .../>
<androidx.recyclerview.widget.RecyclerView ... /> // ItemDecoration is supposed to be here and it works excellent
</LinearLayout>
But I have two lists and I need to use NestedScrollView
<androidx.core.widget.NestedScrollView ...>
<LinearLayout ...>
<androidx.recyclerview.widget.RecyclerView .../>
<androidx.recyclerview.widget.RecyclerView ... /> // It doesn't work here
</LinearLayout>
</androidx.core.widget.NestedScrollView ...>
In this case ItemDecoration doesn't work.
I've found out next information:
onDrawOver's are not called on scrolling because RecyclerView.draw() is not called as well.
All items are created at same time (so Adapter creates view holders for all items in the data). It's bad, but it's not my main problem.
I tried to force calling recyclerview's redraw on scrolling but it doesn't work
Do you have any advice how to fix it?
UPD xml file:
<?xml version="1.0" encoding="utf-8"?>
<androidx.core.widget.NestedScrollView 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:fillViewport="true"
android:scrollbars="none">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/black_background_color"
android:focusableInTouchMode="true"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/menuNewsList"
android:layout_width="match_parent"
android:layout_height="170dp" />
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/listMenu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>
</androidx.core.widget.NestedScrollView>
Code initialization:
listMenu.apply {
adapter = dishAdapter
isNestedScrollingEnabled = false
}
listMenu.addItemDecoration(HeaderItemDecoration(listMenu, isHeader = isHeader()))
HeaderItemDecoration was copied from there
How can I make sticky headers in RecyclerView? (Without external lib)
Shouldn't you add an ItemDecoration to a RecyclerView using the addDecoration(ItemDecoration decoration) method?

RecyclerView containing CardView's won't scroll (not in focus?) unless after clicked once

My RecyclerView contains a list of CardView
xml for MainActivity:
<android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.AppBarLayout>
<android.support.v7.widget.Toolbar/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.widget.NestedScrollView>
<android.support.v7.widget.RecyclerView
android:id="#+id/view_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
</android.support.v7.widget.RecyclerView>
</android.support.v4.widget.NestedScrollView>
<FloatingActionButton/>
</android.support.design.widget.CoordinatorLayout>
I use an adapter for the RecyclerView above to contain the Cards.
xml used to inflate ViewHolder inside the adapter:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/relativeLayout"
android:paddingTop="2dp"
android:paddingRight="2dp"
android:paddingLeft="2dp"
android:orientation="vertical"
android:descendantFocusability="blocksDescendants">
<android.support.v7.widget.CardView
android:id="#+id/cardview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:foreground="?android:attr/selectableItemBackground"
card_view:cardBackgroundColor="#android:color/holo_red_light"
card_view:cardPreventCornerOverlap="true"
card_view:cardCornerRadius="2dp"
card_view:cardElevation="3dp"
card_view:contentPadding="7dp"
card_view:cardUseCompatPadding="true">
<RelativeLayout
android:id="#+id/relat"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:focusableInTouchMode="false"
android:padding="10dp">
<TextView/>
//...
</RelativeLayout>
</android.support.v7.widget.CardView>
</RelativeLayout>
To make the Cards clickable, I tried all solutions in these - two popular posts , but I always have this weird bug:
The list of Cards won't scroll when I start the app for the first time, unless I click on the RecyclerView once. It's as if the RecyclerView is not in focus initially.
Also, if I get rid of all click listeners or similar ways to make the CardView's clickable, and only keep the focusable code in xml:
android:focusable="true"
android:focusableInTouchMode="false"
, then it does scroll right away, but as soon as I add any click (listener) mechanism, or even include "android:clickable="true"" for the ViewHolder, that bug re-emerges.
Please advise. Thank you
You should never nest a RecyclerView inside a ScrollView. Just remove the NestedScrollView and the RecyclerView should take care of its scrolling behavoiur.
<android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.AppBarLayout>
<android.support.v7.widget.Toolbar/>
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="#+id/view_recycler"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
</android.support.v7.widget.RecyclerView>
</android.support.design.widget.CoordinatorLayout>
Turns out the scrolling issue is not related to the RecyclerView. It was due to an open source widget I used which anchored to the RV and somehow interfered with the focusing/scrolling/touch interception. Finally got rid of this bug after days of looking elsewhere..
thank you all the same

How to remove focus from RecyclerView inside ScrollView?

I have a Scrollview which contains an ImageView and RecyclerView.
if navigation drawer opened then closed the RecyclerView auto scrolling to top, How to stop this?
<RelativeLayout 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">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scrollViewMain"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView_main_icons_line"
android:src="#drawable/main_line" />
...
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView_activity_main_passenger_log"
android:paddingBottom="2dp"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
</RelativeLayout>
This problem because of recyclerView has default focus.
Solution
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants"
android:orientation="vertical">
Add android:descendantFocusability="blocksDescendants" to your immediate layout of scrollView
That is because RecyclerView ALWAYS set:
setFocusableInTouchMode(true);
this is hard coded in its constructor.
so if you apply those attribute in your XML for a RecyclerView
android:focusable="false"
android:focudeableInTouchMode="false"
that would be useless, you end up with recycleView.isFocusable() == true...
so the most elegant solution is to disable foucusable for RecyclerView's Parent.
<LinearLayout
android:focusable="false"
android:focusableInTouchMode="false"
android:descendantFocusability="blocksDescendants"
...
>
<android.support.v7.widget.RecyclerView
...
/>
/>
or you can just simply setFocusable(false)
Check out clearFocus() from here Android Dev Doc.
You can set a DrawerListener to your navigation drawer and use the onDrawerStateChanged() or some of the other options from here to call clearFocus() on your RecyclerView.
Adding android:descendantFocusability="blocksDescendants" can restrict scroll to recylerview but if you have edittext inside your layout, this property can block the focus of that particular edittext too. So if you are using this property please make sure you are removing this property in your kotlin/java class once the layout loaded.
parentLayout?.descendantFocusability = FOCUS_BEFORE_DESCENDANTS
(view as ViewGroup).descendantFocusability = FOCUS_BEFORE_DESCENDANTS
Just add the following code in your linear layout, works 100% ` android:descendantFocusability="blocksDescendants"
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<LinearLayout
android:descendantFocusability="blocksDescendants"
android:layout_width="match_parent"
android:layout_height="match_parent">

Categories

Resources