Scrolling the android recyclerview inhibits clicking on the screen - android

i have this problem in my android mobile app, i am using kotlin.
In the main of the project I have a list of cards, made through RecyclerView, when the cards are of a greater number than the screen can accommodate, the vertical scrolling is rightly enabled. As soon as I scroll the list vertically, the action is completed, but upon release I can no longer click anywhere within my app. (clicks work outside the app)
This is the HTML of that piece of code:
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="#+id/itemsswipetorefreshSite"
android:layout_width="wrap_content"
android:layout_height="0px"
android:layout_weight="1">
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerViewSite"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
android:paddingBottom="#dimen/twenty">
</androidx.recyclerview.widget.RecyclerView>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
This piece of code is contained in a CoordinatorLayout inside which there is a ConstraintLayout which in turn has a LinearLayout that encloses the list.
The same problem does not occur in other parts of the app, or in other components / fragments I have other lists, made in the exact same way, but under this situation they do not produce this bug.
The log that is produced at the time of the bug (from the beginning of the scrolling) is the following:
I/HwViewRootImpl: removeInvalidNode all the node in jank list is out of time
W/HiTouch_PressGestureDetector: Touch pointer move a lot. The moving distance of X is:7.0, limit is:60The moving distance of Y is:61.94568, limit is:60
D/OverScrollerOptimization: fling time is flingTime = 1.9100340578075632 velocity = 1261
D/OverScrollerOptimization: fling time is flingTime = 1.9100340578075632 velocity = 1261
but the same is produced, very similar in the other lists for the same action.
Your every help is truly precious, thank you!

set layout_height to wrap_content in both swipeRefreshlayout and also in your recyclerView

[SOLVED]
Maybe it can help someone who is in the same situation as me: I found that in the adapter file of the list in question I found a
requireActivity (). window.setFlags (WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE)
that it didn't have to be there and every time I touched the list it was activated. Typical problem of a hasty copy and paste.

Related

Having RecyclerView inside a NestedScrollView calls onBindView for all the items

I have two RecyclerViews placed vertically in a LinearLayout. I need to make both of them scrollable and that is why I have put the LinearLayout inside NestedScrollView
This is the my layout file.
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
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:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="#+id/featured_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<android.support.v7.widget.RecyclerView
android:id="#+id/all_topic_list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
Also, I am disabling nested scrolling in Java code.
disableNestedScrolling(findViewById(R.id.all_topic_list));
disableNestedScrolling(findViewById(R.id.featured_list));
My RecylerView library version is 26.1.0
This works fine perfectly, but then onBindViewHolder method is getting called for all the items in the list. Ideally it should only be called for the visible items in the list.
I think the issue is happening because I am giving wrap_content to the RecyclerView. A lot of answers on this question suggest that the issue is solved in v23.2.1, but I am already using v26.1.0. How to solve this issue?
I had exactly the same problem. RecyclerViews are not meant to be placed inside scroll containers with the same scroll direction. The view recycling only works when the height is set to MATCH_PARENT.
Depending on the complexity of the content inside of the NestedScrollView and the anticipated amount of RecyclerView items:
Ignore the problem. If there are only a few simple items, you may
not need view recycling at all.
When I hit the problem, I analysed the layouts of other popular apps: For example, WhatsApp only uses RecyclerViews (or ListViews with view recycling) in some parts of their app.
Particularly, this group settings screen with hundreds of possible items is made of multiple ListViews wrapped by a ScrollView, without any view recycling.
Replace the NestedScrollView with a single
ReyclerView with multiple item types and put all of your scrollable content inside of it. This is the way to go if you need view recycling.
Beware that you also have to convert all the other content in the NestedScrollView (headers and footers, spacing) to RecyclerView items with their own ViewHolders.
If the setup is rather simple, I would recommend you to implement it without additional libraries, following the link above.
There are a few different libraries available to solve your problem (all of them follow the second approach with a single RecyclerView), but most come with a lot of extra features which you may not need:
RendererRecyclerViewAdapter
It comes with a ViewRenderer/ViewModel interface, which works like a
"partial" RecyclerView for a single item type. You would create one
for every item type and then register them in a single adapter.
Epoxy
A library/framework create by airbnb and used heavily in their app.
They have a lot of scrollable content (similar to a web page) with a
lot of different item types. Epoxy also helps with the composition of
the different items on a page, and it handles animations when the
content or its order changes. Too much if you only need it for a single screen.
Litho
A complete UI framework created by Facebook which comes with it's own rendering engine, a replacement for xml layouts and much more. As far as I understand, it allows you to do to handle large amounts of items (like the Facebook timeline) and the view recycling is handled automatically. Like Epoxy, you would only use this if your app includes things like endless scrolling with a lot of different item types and you really need the performance.
I tried Epoxy and RendererRecyclerViewAdapter, but after all I created my own multiple item type adapter. It can be created in less than 100 lines of code.
Starting from RecyclerView:1.2.0-alpha04 we can use ConcatAdapter to solve this problem
https://developer.android.com/reference/androidx/recyclerview/widget/ConcatAdapter
I tried your problem by adding 20 items in each recyclerview, with NestedScrollView application called onBindViewHolder method 40 times. As you disabling nested scrolling in Java code i suggest to use Scrollview. By using ScrollView application called onBindViewHolder 33 times.
If you fix your recyclerView's height to specific size instead of "match-parent" it will reduce call to onBindViewHolder greatly.
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="false">
<android.support.v7.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.example.vishal.my2.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="#+id/featured_list"
android:layout_width="match_parent"
android:layout_height="300dp" />
<android.support.v7.widget.RecyclerView
android:id="#+id/all_topic_list"
android:layout_width="match_parent"
android:layout_height="300dp" />
</android.support.v7.widget.LinearLayoutCompat>
</ScrollView>
If Specifying hardcoded value to recyclerView's height does not meet your application requirement then you can try using ListView instead of recyclerView. pardon me if i am wrong, This was my first time answering any question.
Add this to nested scroll view android:fillViewport="false"

NestedScrollView fling stopping bug on Nougat (API 25)

I have a strange issue with NestedScrollView fling on Nexus 5x (7.1.2) and Google Pixel (7.1.1). On other OS versions it works OK.
Fling animation sometimes stops right after lifting up a finger. It stucks and the next few flings may be stopping as well.
In order to reproduce it, you need to fling several times up and down.
In logs these flings look pretty much the same in terms of velocity, direction, etc, so I can't find a real cause of this bug.
Also NestedScrollView doesn't necessarily need to be inside of CoordinatorLayout, it also can have no NestedScrollingChild at all.
For example, this bug is reproducible with one of the following NestedScrollView children:
1) LinearLayout populated with TextViews
2) WebView
3) LinearLayout populated with RecyclerViews.
I know about possible issues with RecyclerView and Behaviours inside of CoordinatorLayout, but it's not related.
So please don't mention any
recyclerView.getLayoutManager().setAutoMeasureEnabled(true);
recyclerView.setNestedScrollingEnabled(false);
or things like that.
Code sample:
<android.support.v4.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="Put a super long text here"/>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:text="Put a super long text here"/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
So it's clearly a bug in NestedScrollView.
I have made a workaround for this, but still waiting for a proper fix from Google side.
https://github.com/Dimezis/FlingableNestedScrollView/
Edit:
Looks like the issue is fixed in support lib 26.0.0-beta2
https://chris.banes.me/2017/06/09/carry-on-scrolling/
Edit 2:
Although the scrolling works fine now, in my app I can constantly reproduce this bug:
https://issuetracker.google.com/issues/37051723
If someone encounters it as well, you can find a workaround in a thread mentioned.
according to Animating a Scroll Gesture training guide, while overriding computeScroll(), after using mScroller.computeScrollOffset() to calculate proper offset to scroll view, we need use:
ViewCompat.postInvalidateOnAnimation(this);
to animate next scroll.
However, in the NestedScrollView, the computeScroll() looks like this:
public void computeScroll() {
if (mScroller.computeScrollOffset()) {
...
}
}
It doesn't request next scroll animation! Which means that after using mScroller.fling(...), the computeScroll() method will sometimes only get called one time, and view doesn't keep fling.
To fix this problem, I have tried to replace the computeScroll in this way:
public void computeScroll(){
if(mScroller.computeScrollOffset()){
...
ViewCompat.postInvalidateOnAnimation(this);
}
}
It may not sound a good solution, but it just works fine for now.
Recent version of NestedScrollView has added the ViewCompat.postInvalidateOnAnimation(this).

Mapbox - Avoid automatic center

I use a Mapbox map in a scrollview. In this scrollview I have the main LinearLayout and inside this, I have 5 areas with different information. The Map is in the third area.
Due to the amount of data in the first and second area, while displaying, the Map area must not be visible and to see it, you'll need to scroll.
Unfortunatly, the Mapbox seems to have an "automatic center" sistem: as soon as the Scrollview start to be displayed, it's position is set automaticly to the center of the Map.
So the user has to scroll back to the top of the scrollview.
How to avoid this "initial position feature"?
Note: this is NOT a duplicate question from this: Using mapbox in scrollview, scrollview sliding to the position where mapbox is put in the page
as the problem is NOT "how to move the map and don't move the scrollview". The problem is the initial position of the scrollview. Also the answer "do mScrollView.scrollTo(0,0);" is NOT acceptable as with that, the scrollview is first centered to the map and AFTER, there is a scroll.
Edit: here are two pictures and more details.
This first snap show the scrollview in vertical mode. I've a first area named "INFORMAÇOES" a second one named "TIPO DE OCORENÇA", a third with the map and after than I have 2 others area.
Due to the size of area 1 and 2, in vertical mode, the map area is partially visible. This snap show the screen at start of display.
This second snap is taken at the same time so at start of display, but in horizontal mode. Of course, the amount of visible data is different. What we can see is that the map area seem to force a scroll in order to be displayed.
After making some test I discovered strange thinks: when you scroll, you commonly set the top of data at top of screen. In the case of the map it's not the case. The first element which appear quickly at start of the display is the Mapbox logo.
Here is the XML part:
<LinearLayout
android:layout_margin="5dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical"
android:layout_below="#id/linearLayout_type"
android:id="#+id/linearLayout_map">
<com.mapbox.mapboxsdk.maps.MapView
mapbox:zoom="12"
android:id="#+id/mapview_inter"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
The tests I've made:
1 - put a android:visibility="gone" in com.mapbox.mapboxsdk.maps.MapView. it's not allowed.
2 - put a android:visibility="invisible" in com.mapbox.mapboxsdk.maps.MapView. it's not allowed.
3 - put a android:visibility="invisible" in the linearlayout of the map (linearLayout). Change nothing. The map is not visible but the "scroll" happened.
4 - put a android:visibility="gone" in the linearlayout of the map (linearLayout). In that case, that's OK: the "INFORMAÇOES"part of the data is at top. But their is no rendering of the map. So when I perform a
LinearLayout tmp = (LinearLayout) findViewById(R.id.linearLayout_map);
tmp.setVisibility(View.VISIBLE);
to see the map, I see... nothing :(
Any suggestions?
First, you should give a either your LinearLayout a specific dp size or the MapView. Right now you are using match_parent for both. You can force the ScrollView to the top by using scrollView.fullScroll(ScrollView.FOCUS_UP); inside the OnMapReady callback which fixed the issue for me.

Prevent ImageView from receiving touch events when scrolling

I'm making an app with lots of ImageViews and I needed to attach a touch listener in some of them. While doing this, I encountered a problem. If the pointer was held down at the location where the ImageView with touch listeners attached to it and was about to produce a scrolling event, there seems a fighting scene between the Views and the ScrollView in w/c where the event was actually occured and in w/c the event is supposed to belong. The screen scrolls in a fast rate then return where the first pointer was touched down, so it means it is an unwanted behavior.
Setting an onTouchListener in the ImageView makes the scrolling uneasy and unwanted, how do I prevent ImageView from receiving touch events when scrolling?
Some of the codes
Layout: act_map_view.xml
<?xml version="1.0" encoding="utf-8"?>
<com.nkraft.mobiletomblocator.CustomVScroll
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/vScroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none" >
<com.nkraft.mobiletomblocator.CustomHScroll
android:id="#+id/hScroll"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:scrollbars="none" >
<com.nkraft.mobiletomblocator.CustomGridLayout
android:id="#+id/map_grid"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</com.nkraft.mobiletomblocator.CustomGridLayout>
</com.nkraft.mobiletomblocator.CustomHScroll>
</com.nkraft.mobiletomblocator.CustomVScroll>
Notes:
The GridLayout is populated with ImageViews at runtime.
I customized my horizontal and vertical ScrollView so that I can scroll in both directions concurrently i.e diagonal scrolling
From the notes I've mention, I figured a clue from the problem I'm currently facing. I think this issue had been thought before the standard android's scrollbar was implemented. The main reason this occurs to me is that I extended the class of the scrollbars and totally replacing the default behavior of it. So for me to achieve what I want (the scrollbar with diagonal scrolling) I follow this post and replace both my vertical and horizontal scrollview with this TwoDScrollView, also thanks for this post directing me to it.

Gridview disappear?

Am using gridview to display an image and a textview.
After implementing this,
1) some times the alignment seems to be dancing while moving the gridivew
2) Some times the gridview get disappeared.
Can u plz advise how to resolve it ?
Thanks in advance.
#Prasath, Set the Layout params for your images in Grid view.
Your issue will be resolved.
Since Grid view has issue with scrolling of uneven height objects. That's why your GridView disappears.
https://stackoverflow.com/a/5958097/2188257 this solution partialy solved the problem for me. When you set a fixed number of lines for the textview inside gridItems it doesnt fall apart anymore, but then you get the problem of having fixed number of lines for the text.
its a problem cause i would like to reuse the layout for a grid menu on more than one place, and in some i have grids with big labels with 4-5 lines, and in a main menu labelshave just one line, but have to have 5 fixed lines because of other grids. I guess the solution could be to measure each element in the adapter and later setting layoutParams for the grid with max values... or creating multiple xml files for different uses of the grid.
It means that the underlying item is not valid anymore; likely a null reference
i have solved this problem replaced by
<LinearLayout
android:orientation="horizontal"
android:layout_marginTop="#dimen/big_margin"
android:layout_width="match_parent"
android:layout_marginLeft="#dimen/big_margin"
android:layout_height="wrap_content">
to
<LinearLayout
android:orientation="horizontal"
android:layout_marginTop="#dimen/big_margin"
android:layout_width="match_parent"
android:layout_marginLeft="#dimen/big_margin"
android:layout_height="#dimen/workoutlist_itemheight">
but really i don't know how did my issue solved.
thanks

Categories

Resources