I'm developping a Android app, and I got a vertical NestedScrollView, who take all my screen, and inside multiple hoizontal RecyclerView. It's work, but the horizontal scroll is really hard to achieve.
I mean, when I scroll horizontally the gesture is catch by the NestedScrollView, and the view move up/down. I need to focus and do a real horizontal movement to scroll the RecyclerView, it's killing UX...
Here my NestedScrollView :
<android.support.v4.widget.NestedScrollView
android:id="#+id/scrollView"
android:scrollbars="none"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:layout_marginRight="5dp"
android:layout_marginLeft="5dp"
android:layout_marginStart="5dp">
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:id="#+id/scrollLayout"
android:orientation="vertical" />
</android.support.v4.widget.NestedScrollView>
I'm inflating RecyclerView programmatically, because the number is define in network data, here the inflated layout :
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:textSize="#dimen/secondary_text_size"
android:textAllCaps="true"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="#dimen/recycler_view_size" />
</LinearLayout>
And how I set my RecyclerView in Java :
LayoutInflater inflater = LayoutInflater.from(context);
LinearLayout layout = (LinearLayout) inflater.inflate(R.layout.recycler_view_layout, null, false);
RecyclerView recyclerView = (RecyclerView) layout.findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
recyclerView.setHasFixedSize(false);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(this);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.setNestedScrollingEnabled(false);
I tried to change the "velocity" NestedScrollView, but I can't find good advice/post, maybe I don't find the good one. Someone can help ?
Hope you find it useful, as I think you need to implement one of these libraries (on GitHub you would find more):
View Flow for Android: https://github.com/pakerfeldt/android-viewflow
HorizontalListView: https://github.com/MeetMe/Android-HorizontalListView
TwoWayGridView https://github.com/jess-anders/two-way-gridview
If you want to do it with standard Android libraries, RecyclerView might be useful if you want to scroll horizontally
To prove that it has horizontally scrolling support, take a look at:
public boolean canScrollHorizontally ()
Query if horizontal scrolling is currently supported. The default
implementation returns false.
Returns True if this LayoutManager can scroll the current contents horizontally
or
public int computeHorizontalScrollExtent (RecyclerView.State state)
Override this method if you want to support scroll bars.
Read computeHorizontalScrollExtent() for details.
Default implementation returns 0.
From: https://developer.android.com/reference/android/support/v7/widget/RecyclerView.LayoutManager.html
Check also subclass of RecyclerView called HorizontalGridView
Hope it help.
Related
How to trigger a recyclerview scroll listener when it is inside a scroll view?
Here the scroll view listener is alone triggering
1. Set nested scrolling enabled false of recycler view.
recyclerView.setNestedScrollingEnabled(false);
2. Add scroll listner to nested scrollview.
mScrollView.getViewTreeObserver().addOnScrollChangedListener(new
ViewTreeObserver.OnScrollChangedListener() {
#Override
public void onScrollChanged()
{
View view = (View)mScrollView.getChildAt(mScrollView.getChildCount() - 1);
int diff = (view.getBottom() - (mScrollView.getHeight() + mScrollView
.getScrollY()));
if (diff == 0) {
// your pagination code
}
}
});
Try with NestedScrollView instead of ScrollView.
NestedScrollView is just like ScrollView, but it supports acting as both a nested scrolling parent and child on both new and old versions of Android. Nested scrolling is enabled by default.
Note: You have to set setNestedScrollingEnable(false) to your recylerview.
in xml add android:nestedScrollingEnabled="false" in recyclerview
OR
programmatically yourRecylerview.setNestedScrollingEnabled(false);
See this article.
You can try this one, but still I assuming you may have the same code like mine as you didnot post your needed code into your question.
Try this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.widget.NestedScrollView
android:id="#+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
</LinearLayout>
Use NestedScrollView with <android.support.v7.widget.RecyclerView as I have mention above.
Its ScrollListener will not work as all the rows gets layed when recyclerview is inside scrollview whole purpose of recyclerview gets destroyed when you put it inside scroll view.
For Example as the recyclerview will stretch to full fill its parent ,when you will put it inside scroll view , in case of scroll view it will stretch to its fullest. if there are 1000 items in recyclerview all it will draw 1000 different rows which is also a performance issue.
You should remove it from a scroll view to make its scroll listener working
How do you display a list of item that is very large on one side (either horizontally / vertically), and allow it to be freely scrolled / dragged - like Google Sheets?
I've tried using a NestedScrollView with a RecyclerView, but you can only scroll in one direction at a time, and I need it to be able to be freely dragged around (no pinch / zoom functionality is required, but if it can be done it's a bonus).
Here's a GIF of what I've tried, it works but it's definitely not what I'm looking for.
This is the layout file:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<include
layout="#layout/include_toolbar"
android:id="#+id/toolbar" />
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/recycler_biscroll"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.v4.widget.NestedScrollView>
</LinearLayout>
I finally got an answer: Use a custom LayoutManager implementation.
I removed the outer ScrollView, added FixedGridLayoutManager on my code, then used it as the RecyclerView's layout manager:
FixedGridLayoutManager layoutManager = new FixedGridLayoutManager();
layoutManager.setTotalColumnCount(adapter.getItemCount()); // This probably needs to update when item count is changed
recyclerView.setLayoutManager(layoutManager);
Have you tried putting the recycler view inside a scroll view?
I am using a Recycler view inside a Horizontal Scroll View to display threaded comments like below:
Comment1
Comment1Child1
Comment1Child2
Comment1Child2Child1
Comment1Child3 Comment2
etc.
I have done this with the following XML:
<HorizontalScrollView
android:id="#+id/horizontalScrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fillViewport="true"
android:scrollbarSize="2dp">
<android.support.v7.widget.RecyclerView
android:id="#+id/commentRV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_marginLeft="47dp"
android:minWidth="200dp" />
</HorizontalScrollView>
You'll see I set a min width of 200dp so that the comments never get too small and the deeper down the thread they go the further off screen it will be pushed.
It is displaying perfectly but I am unable to scroll horizontally. I can see the scroll bars but I cannot scroll horizontally.
I have fiddled with disabling Touch and nestedScrollingEnabled in the RV but not sure what the real solution is. Nothing seems to work?
Any help would be much appreciated! Thank you
Remove HorizontalScrollView you can give LinearLayoutManager with horizontal orientation like this
LinearLayoutManager layoutManager= new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false);
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
reclyclerView.setLayoutManager(layoutManager);
//recyclerView.setMinimumWidth(200); optional for width if u need
I am using RecyclerView inside NestedScrollView and it works. But when I use RecyclerView inside LinearLayout or something, it scroll in various speed depending on gesture. The scroll listen to gesture and if I slide up only a bit, then it scroll a little bit while if I slide up really fast, then it scroll really fast. Now my problem is that RecyclerView inside NestedScrollView certainly scroll but fast scroll does not work. However I slide up fast or slow, RecyclerView or NestedScrollView only scroll a little bit.
How can I make my NestedScrollView or RecyclerView inside that scroll view scroll in various speed?
try
recyclerView.setNestedScrollingEnabled(false);
By default setNestedScrollingEnabled works only after API-21.
You can use ViewCompat.setNestedScrollingEnabled(recyclerView, false); to disable nested scrolling for before and after API-21(Lollipop). Link to documentation.
I was working on android 16 where this was not possible to use setNestedSCrollEnabled method,
What I end up doing to stop RecyclerView from handling Scrolls.
Like in LinerLayoutManager i made canScrollHorizontally, canScrollVertically to return false by default.
myRecyclerView.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false){
#Override
public boolean canScrollHorizontally() {
return false;
}
#Override
public boolean canScrollVertically() {
return false;
}
});
After several iterations, I came up with a solution.
If you are using RecyclerView, then:
recyclerView.setNestedScrollingEnabled(false);
If you are using LinearLayout inside NestedScrollingView, take the LinearLayout inside a normal ScrollView and then set its scrolling to
scrollView.setNestedScrollingEnabled(false);
android:overScrollMode="never
<android.support.v4.widget.NestedScrollView
android:id="#+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:overScrollMode="never">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
You can use ScrollView with ExtendRecyclerView class that overrides the onMeasure method. That works for me!
#Override
protected void onMeasure(int widthSpec, int heightSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthSpec, expandSpec);
}
recyclerView.setNestedScrollingEnabled(false);
Will be useful sometimes.But it is not advisable for all the times.because it disables view recycling feature in recylcer view.
Alternatives:
Try CollapsiveToolbarLayout with Recycler view.
put other views in collapsiveTollbar layout.
I also met this problem.
And upgrade to 26.1.0 fix it.
In My Case i placed all images in drawable folder insted of drawable-xxxhdpi folder thats why my screen UI is lagging.
This is WAI. The NestedScrollView measures its children with the Spec "Unspecified". The child can grow as much as it wants too.
This essentially equates the height of NSV and RV. So as far as the RV is concerned, it believes that it is completely displayed.
Wrap your RV with an LL and give your RV a height. The LL would not set the measure spec to be UNSPECIFIED so the RV would correctly scroll within its set height of whatever DPs you provide.
The only downside of this method is that you will not be able to do a match parent on your RV.
You should wrap recycler view in any layout like LinearLayout and set RecyclerView size to constant, like 800dp. This will enable smooth scroll and recycler view will still recycler views during scroll.
<android.support.v4.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:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="800dp"
app:layout_behavior="#string/appbar_scrolling_view_behavior"/>
</LinearLayout>
Im creating RecyclerView and ListView inside ScrollView and im getting problems with the scroll.. The scroll is Jerking (unable to get smooth scroll), I know its the problem with the RecyclerView inside the ScrollView, because layout is scrolling without any problem when swiping until the ListView exists but once RecyclerView items enter the layout it starts to jerk( only scrolling with the finger, no proper scroll when finger is taken off). Here is the code in the xml
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ListView
android:id="#+id/lv_home_dropdown"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="#color/colorWhite"
android:dividerHeight="0.5dp"
android:visibility="gone"/>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/recycleView"
android:background="#color/colorWhite">
</android.support.v7.widget.RecyclerView>
</LinearLayout>
</ScrollView>
Nested views that scroll along the same axis have always been
problematic on Android. Recently Google has added nested scrolling
support. In order to have this on older platform levels, you should
use the views in the support library like NestedScrollView and
RecyclerView.
ListView does not work with wrap_content as its height. You can do
this with RecyclerView if you have the latest version of the
RecyclerView support library. Besides, you are already using RecyclerView in one place, you might as well use them exclusively.
ListView is not really meant to be a "drop down". Perhaps you should consider a Spinner instead.
I have it finally.!!
Just add the following line of code in you class where you are calling the RecyclerView
mRecyclerView = (RecyclerView)tmpView.findViewById(R.id.recycleView);
mRecyclerView.setNestedScrollingEnabled(false);
It works for me!