In my application I have a three textview which I want to be scroll-able and then below that I want to place a recyclerView. Then after I want that I can scroll these three textview separately and when scrolling the recyclerView the whole layout scrolls so that the textview are scrolled up and recyclerView items gets displayed. I have tried a variour options but failed.
One way through which I am able to achieve this is:-
<ScrollView
<RelativeLayout
NestedScrollView
TextView1
TextView2
TextView3
</NestedScrollView>
<RecyclerView
</RecyclerView>
</RelativeLayout>
</ScrollView>
But while using this layout if recyclerView has less items (say 50-60 ) then it works well otherwise the application hangs and have to force close application.
After so many different tries I think when I place recyclerView inside ScrollView (or NestedScrollView) then such behavior occurs.
Please help me with layout setup
Related
I know it is not a good approach, but I have a layout with similar structure:
ScrollView
RelativeLayout (with TabLayout,textViews, ImageViews etc)
RecyclerView
RelativeLayout (with textViews, ImageViews etc)
The recyclerView part is dynamic, so it may have 1 TextView with ImageView, but it can have max. 4-5 lines of elements.
This is working fine, but when there are more items in recyclerView, then that section starts to scroll.
That's what I want to disable.
My RecyclerView part:
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerview2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
I added to the RecyclerView this line:
android:nestedScrollingEnabled="false"
So now the scrolling is disabled for that section, but now I don't see all items in RecyclerView.
How can I disable scrolling and keep the full height to see all the content there?
When I'm scrolling down, the items above the RecyclerView does not scroll unless I start touching from the layout above, and it only scrolls down when I have reached the end of the RecyclerView.
<NestedScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout>
<Some other items.../>
</LinearLayout>
<RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</NestedScrollView>
Note:
I actually use a fixed size for the RecyclerView, setting it via the code below:
float height_recyclerview = (ScreenUtil.getHeight(context) - (height_banner + height_bottom_navigation + height_create_post));
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, (int) height_recyclerview);
rv.setLayoutParams(layoutParams);
Why do I use fixed size if it works smoothly with wrap_content?
I will be displaying possibly thousands of items that may have
images, which will hurt performance if it does not actually do
recycling because of the issue that the RecyclerView is inside the
NestedScrollView
I have implemented an EndlessRecyclerViewScrollListener which has an
issue that it keeps loading more data from server continuously if
implemented with a RecyclerView that is within whatever scrollable
view, or if it is in a scrollable view, but does not have a fixed
height, even if you are not scrolling down.
I have tried the following:
set nested scrolling to false on the recycler view
try using scroll view instead of nested scroll view
a bunch of other code related to layouts and scrolling behaviors that others suggested which didn't work for me because I'm implementing it in a much more complicated layout and the fact that I use EndlessRecyclerViewScrollListener
What I want to fix?
I want to make the page scroll like a single page, not as a separate scrollable view.
Note that my recycler view has a fixed height that takes the entire screen's space meaning that its height is actually fit assuming that the linear layout above is not visible anymore if the user has scrolled down.
The ideal scenario is to make the scrollview scroll down first, to make the recycler view take the entire screen, so that the recyclerview will scroll however the user wants to.
Then the linearlayout above which should not be visible anymore if the recycler view has taken up all the space of the screen, should only show up if the recycler view has reached the top/first item, if the user keeps scrolling back up.
Read this.
Add app:layout_behavior="#string/appbar_scrolling_view_behavior" to your recycler xml.
<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" />
NestedScrollView Smooth Scrolling
recyclerView.isNestedScrollingEnabled = true
Do this programmatically
<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="0dp"
android:fillViewport="true"
...
tl;dr: How to achieve the layout shown in the screenshot below? Placing ListView to a ScrollView is apparently not recommended, but is there actually any other way to achieve it?
The whole question: I want to have multiple CardViews in my app, and one (or more) of them will have either RecyclerView or ListView in it (it doesn't really matter to me which one of those). The whole view is supposed to be scrollable - not only the ListViews in their parent CardViews. I basically need to achieve similar layout as the Play Store app has.
The first option I tried was this (the code is obviously simplified):
<LinearLayout android:orientation="vertical">
<CardView>
<!-- Some content of the first card. -->
</CardView>
<CardView>
<ListView/>
</CardView>
</LinearLayout>
The result was not what I wanted, the ListView was only scrollable in its parent CardView but the whole view wasn't scrollable like it is in the Play Store app. So now I wrapped it all in a ScrollView:
<ScrollView
android:fillViewport="true"
android:isScrollContainer="true">
<LinearLayout orientation="vertical">
<CardView>
<!-- Some content of the first card. -->
</CardView>
<CardView>
<ListView/>
</CardView>
</LinearLayout>
</ScrollView>
And I programmatically set the height of the bottom card to fit the ListView's height (number of elements in the ListView * height of one list item element). Now the whole view is scrollable, and the bottom card's height is the same as the height of the ListView, so the ListView isn't scrollable inside the CardView which is exactly what I wanted.
Now the actual problem: I got it working as described above, but I know this particular issue (ListView in a ScrollView) has been asked about many times before and the answer has always been the same - don't put neither RecyclerView nor ListView in a ScrollView because it causes performance problems. Well, so what's the correct approach then? How did Google do it in the Play Store app? I tried decompiling the Play Store app with APKTool but there weren't any layout files (maybe I did something wrong). Is my approach correct? My ListView will only display a few items (I guess it will be at most 20 items) - will it cause some performance issues in this case?
I wouldn't ask about this if all the answers wouldn't always mention that we shouldn't put ListView in a ScrollView. Is there any other way how to achieve the layout described by the screenshot above?
The first thing to address is why you're "not supposed to" use wrap_content on a ListView or a RecyclerView and put it in a scrollable container: it defeats the entire view-recycling purpose of these components.
What makes a ListView or RecyclerView better than a LinearLayout inside a ScrollView is that the system only needs to create enough views to display everying that fits inside the visible area. When you "scroll" the visible area, the views that disappear off one end can be re-used for the views that scroll into view from the other end. When you make your list/recycler wrap_content, this recycling is impossible, so you might as well just manually add your views to a LinearLayout instead.
That being said, RecyclerView does support using wrap_content... it just means you won't get view recycling. If this performance hit doesn't cause you problems, there's no objectively evil code here.
The only way to know for sure if the performance penalty is problematic or not is to just try it, test it, measure it, and decide for yourself. With 20 items, I suspect you have nothing to worry about.
The next thing to think about is the fact that Google has tons of resources and manpower and can afford to be extremely clever. Perhaps the Play Store app is as you say, with some sort of scrollable parent container that holds cards, each of which have some sort of adapter view within. But it's equally possible that they're doing something completely different, like using a single RecyclerView and "faking" the appearance of cards by using an ItemDecoration. Or perhaps they are using some sort of custom view subclass that the public doesn't have access to.
As for how you could recreate something similar, I suspect a hierarchy like this will work just fine:
<NestedScrollView>
<LinearLayout>
<CardView>
<RecyclerView/>
</CardView>
<CardView>
<RecyclerView/>
</CardView>
<CardView>
<RecyclerView/>
</CardView>
</LinearLayout>
</NestedScrollView>
I would recommend you to use Sectioned RecyclerView for this purpose. Every single item layout would have a cardView in it instead of creating a cardView as a parent.
Refer to this library: https://github.com/luizgrp/SectionedRecyclerViewAdapter
I have this structure
<LinearLayout
android:id="#+id/1">
<LinearLayout
android:id="#+id/2" />
<LinearLayout
android:id="#+id/3">
<ListView
android:id="#android:id/list" />
</LinearLayout>
</LinearLayout>
And I populate the ListView with some data. Well my problem is that the ListView becomes scrollable (while the LinearLayout number 1 fits the screen without scrolling), but what I want is this View to become full height and that the LinearLayout with id=1 becomes scrollable.
Inside ListView number 2 I have some TextViews, etc.
ListView's are scrollable by default if when the content is more than its display area.
However, LinearLayout would need to have a ScrollView in order to scroll.
Red Alert - You cannot use ScrollView and ListView together. You will end up seeing un-expected.
Alternate Solution: Prioritize what is more important to you, if scrolling the entire screen then add a ScrollView (provided your ListView items are static) else I will to wait to hear a good solution on this one. :)
Add ScrollView for ListView.
ScrollView will work for only one child view, so you have to add like this
LinearLayout
LinearLayout
LinearLayout
ScrollView
ListView...../ListView
/ScrollView
/LinearLayout
im trying to insert 6 gridviews with 6 imageview above each of them ! the problem im facing is that i cant scroll my page to see all my girdviews the first gridview seems fine as it wraps all its contents and set the height to it the second gridview shows only first row and make it scrollable but i can't see my other gridviews i want a layout like
--ImageView--
--GridView1--
--ImageView--
--GridView2--
--ImageView--
--GridView3--
and so on
<LinearLayout>
<ImageView />
<GridView />
--
--
<GridView6 />
</LinearLayout>
i have tried using scrollview and all but couldn't get the results !
Thanks
Hee is how you can do this. Check the answer here. It is an expandable height GridView, which you will want to import / create in your project. What that basically means is that as more items are added to the GridView, it will just expand its height, as opposed to keeping its height set and using scrolling. This is exactly what you want.
Once you have the ExpandableHeightGridView in your project, go to your XML layout where you want the GridView to be. You can then do something like this (paraphrasing):
<ScrollView ...>
<RelativeLayout ...>
<com.example.ExpandableHeightGridView ... />
<other view items />
</RelativeLayout>
</ScrollView>
Then, in your activity where you set the GridView's adapter, you want to make sure you set it to expand. So:
ExpandableHeightGridView gridView = (ExpandableHeightGridView) findViewById(R.id.myId);
gridView.setAdapter(yourAdapter);
gridView.setExpanded(true);
The reason you want this expandable GridView is because, the fact that a standard GridView doesn't expand is what causes it to scroll. It sticks to a certain height, and then as more items fill it past its view bounds, it becomes scrollable. Now, with this, your GridView will always expand its height to fit the content within it, thus never allowing it to enter its scrolling mode. This enables you to use it inside of the ScrollView and use other view elements above or below it within the ScrollView, and have them all scroll.
This should give you the result you're looking for. Let me know if you have any questions.