Android: Scroll whole fragment with ListView inside - android

I have the following structure in my fragment layout file:
- ScrollView
- ConstraintLayout
- CardView
- *some stuff here*
- CardView
- ListView
- *list header*
- *list items generated with a custom adapter*
If I remove the outer ScrollView, I can see the whole content of the ListView, and if it's bigger than the remaining space for the 2nd CardView, I can scroll it. The 1st CardView stays in place, but the content of the 2nd one is scrollable.
However, I would like to scroll the whole fragment. I would like the 2nd CardView to expand and contain the whole ListView, and if I scroll up or down, the 1st one moves as well.
I tried several combinations of height settings. No point of showing you my actual layout XML, because it's a mess. I would like a clean slate. Is it possible to achieve?
EDIT:
I know the ListView is a scroll container itself, but I think it's a pretty common need to scroll the whole thing, so I can't understand why it's so hard to make it work.

Alright, after combining multiple answers, I have the solution that I needed.
First
I needed to use a NestedScrollView instead of a regular ScrollView.
It solves the conflict between the two scroll containers (ScrollView and ListView).
Reference: Android: ScrollView vs NestedScrollView
NOTE: My list content is dynamic, so it can be too short to fill the remaining space. I had to set android:fillViewport="true" on the NestedScrollView. If the list is longer than the remaining space, it will not cause any trouble.
layout.xml
<?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">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.cardview.widget.CardView
android:id="#+id/card1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- NOTE: constraints properties are missing from here for easier reading -->
<!-- card content here -->
</androidx.cardview.widget.CardView>
<androidx.cardview.widget.CardView
android:id="#+id/card2"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- NOTE: constraints properties are missing from here for easier reading -->
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<!-- NOTE: this will change in step 3 -->
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.core.widget.NestedScrollView>
Second
Following the steps above will make the ListView collapse to the height of its first item. To solve this, I needed to create a subclass from ListView and override its onMeasure() method, so it can calculate the proper height at runtime.
Reference: Android - NestedScrollView which contains ExpandableListView doesn't scroll when expanded
NonScrollListView.java
package my.package.name
import ...
public class NonScrollListView extends ListView {
// NOTE: right click -> create constructors matching super
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int heightMeasureSpec_custom = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec_custom);
ViewGroup.LayoutParams params = getLayoutParams();
params.height = getMeasuredHeight();
}
}
Third
I needed to use my custom View instead of the regular ListView in my layout XML.
layout.xml excerpt
<my.package.name.NonScrollListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
This way I managed to make it work. Both cards move together on scroll, even if I tap the ListView area.
I don't know whether it causes performance issues with really long lists, because mine contains a few dozen items at most, but I have no problem on a low end Galaxy A20e.

Related

RecyclerView as child of NestedScrollView - not recycling views

I am trying to create a scroll-able area which will contain various sections of the following types:
Horizontal Recycling Section
Vertical Recycling Section
Text Section
The approach I am taking is to have a NestedRecyclerView as the parent scroll view for all the child sections. This view looks like so:
<?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">
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
android:id="#+id/mynav_appbarLayout"
android:background="?attr/themeToolbarBg"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
android:id="#+id/mynav_toolbar"
layout="#layout/actionbar_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:id="#+id/nestedScrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
<LinearLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"/>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
</layout>
Then, for each section type I am creating a corresponding view binding and adding it as a child to the LinearLayout which is inside the NestedScrollView.
There are 2 types of section layout, one which is a simple TextView (which I will omit here as it is not relevant) the other of which is a view which contains a RecyclerView. The layout manager for this RecyclerView is created dynamically depending on whether the section it is to be used for is a horizontal or vertical section.
The layout with the RecyclerView in looks like so:
<?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">
<LinearLayout
android:id="#+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:focusable="true"
android:focusableInTouchMode="true">
<TextView
android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="8dp"/>
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/fooBarsRecycler"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="16dp"
android:layout_marginTop="8dp"
android:nestedScrollingEnabled="false"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior"/>
</LinearLayout>
</layout>
Now, when I am adding these views to the parent NestedScrollView's LinearLayout and setting up the LayoutManager for the associated RecyclerView to orientation Horizontal it works fine, but, when I use orientation Vertical (which is the same orientation as the NestedScrollView) the RecyclerView is NOT recycling views. Obviously this is leading to unacceptable performance.
After doing about a days worth of research and banging my head against the wall it appears that having a RecyclerView nested within a NestedScrollView with the same orientation as the NestedScrollView causes the RecyclerView to lose it's recycler functionality.
As you can hopefully see from the above layout, I have tried all the suggestions I could find, making sure the RecyclerView's height is not wrap_content, using layout_behaviour, setting the NestedRecyclerView to fill view port and so on.
I have exhausted 6 pages of google search around this issue and have tried every suggestion I have found either on SO or blogs and nothing is working.
Oddly, if I swap out the NestedScrollView for a ScrollView, the vertical RecyclerView regains it's recycler functionality, but now scrolls independently of the parent ScrollView which doesn't meet our requirements.
Is this a solved problem or do I need to rethink my entire solution? I.e. am I just missing an attribute or doing something wrong in the XML or is it fundamentally an issue with using a RecyclerView inside a NestedScrollView with the same orientation?
Here is the list of resources, the suggestions of which I have tried exhaustively to no avail:
How to use RecyclerView inside NestedScrollView?
How to use RecyclerView inside NestedScrollView
Recycler view inside NestedScrollView causes scroll to start in the middle
https://android.jlelse.eu/recyclerview-within-nestedscrollview-scrolling-issue-3180b5ad2542
https://medium.com/#mujtahidah/load-more-recyclerview-inside-nested-scroll-view-and-coordinator-layout-4f179dc01fd
https://github.com/google/flexbox-layout/issues/400
https://www.reddit.com/r/androiddev/comments/8oj8cb/having_recyclerview_inside_a_nestedscrollview_is/
https://github.com/mikepenz/FastAdapter/issues/447
https://www.reddit.com/r/androiddev/comments/bixl6r/nestedscrollview_recyclerview/
View Recycling not happens with Multiple Recyclerview inside NestedScrollView
How to make RecyclerView do recycling inside NestedScrollView?
https://code-examples.net/en/q/1d90611
As per a suggestion in the comments, I could model this with a multi type adapter, which is something I have done before but for this particular problem I am not sure this approach will work.
I think the comment is suggesting I model it like so:
Where the adapter would adapt types:
Horizontal Section
Text Section
Card Section
But, the requirement is this:
So, as you can hopefully see, the RecyclerView will have a LinearLayoutManager with orientation Vertical, but, once we hit the cards, they have to be laid out in a grid fashion, which of course the LinearLayoutManager does not support. So, perhaps I can have the final section be another RecyclerView with a GridLayoutManager? But, I tried this last night and it didn't work, there were scrolling issues as the bottom most RecyclerView is scrolling vertically within the outermost RecyclerView which is also scrolling vertically.

Non-scrolling WRAP_CONTENT RecyclerView inside ScrollView in ConstraintLayout

I want to document the problems I ran into and the solution for the benefit of others, and find help with the key flaw in my solution.
I want a RecyclerView with an arbitrary number of rows in a layout with a number of other Views. The RecyclerView and other Views should be in a ScrollView that scrolls, but the RecyclerView itself should not scroll.
Since the number of rows in the RecyclerView is unknown, and I'm required to have other views immediately underneath the RecyclerView, I can't use a fixed height or match_parent.
I experienced some odd problems: when I would update the RecyclerView data (using an AsyncListDiffer) and the UI was supposed to update, the entire RecyclerView would jump above the view it was constrained underneath, straight to the top of the parent. This is not how a ConstraintLayout is supposed to behave.
Then I was able to stop that from happening, but Views underneath the RecyclerView would disappear--appearing once the RecyclerView data updated.
The solution:
Put the RecyclerView and other Views inside a ConstraintLayout inside a ScrollView (or NestedScrollView)
Set the RecyclerView to have a height of wrap_content (and adding app:layout_constrainedHeight="true" doesn't hurt)
Make sure the rows in the RecyclerView have a fixed height and do not have a height of wrap_content
This was helpful to me after banging my head against the wall and trying some proposed solutions that did not work: make RecyclerView's height to "wrap_content" in Constraint layout
This solution is pretty simple. The layout can be something like:
<ScrollView
android:id="#+id/scrollView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- other Views -->
<androidx.recyclerview.widget.RecyclerView
android:id="#+id/recyclerView"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/otherView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toTopOf="#+id/anotherView"
/>
<!-- other Views -->
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
And then the layout for a row:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/constraintLayout"
android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeight">
<!-- other views -->
</androidx.constraintlayout.widget.ConstraintLayout>
Here's the problem: I'm not a fan of fixed-height rows. What if other content needs to go in there? What if the user changes their text size? I much prefer flexible layouts that can adapt in size. But if I do that, then the RecyclerView takes up a screen's worth of height inside the ScrollView, shoving all lower views off the bottom of the screen, no matter how few rows it contains.
The alternatives I can think of are to make all the other Views outside the RecyclerView become rows of the RecyclerView, or to avoid a RecyclerView altogether and programmatically add Views to a LinearLayout. These are much uglier approaches.
Is there a way to fix it so the rows of the RecyclerView can have a height of wrap_content?

Scrolltoposition/ smoothscrolltoposition for recyclerview under a nestedscrollview layout

I have a recyclerview under a nestedsrcollview. I want to implement the scrolling to a specific position for the recyclerview but I am having difficulty with it. The xml code is:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".HomeFragment"
android:background="#ffffff"
android:fillViewport="true"
android:id="#+id/nestedscrollview"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="1dp"
android:orientation="vertical"
>
<<some other layouts>>
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/home_blog_list"
android:layout_marginBottom="52dp"
/>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
I want to implement the scrolltoposition for the home_blog_list recyclerview to a position (say 26). How to do it? P.S.- I have set nestedscrollingenabled to false for the home_blog_list.Please note that I want to scroll the nestedscrollview to a specific row of the recyclerview. I dont want the case where the recyclerview is scrolled only. Thanks in advance!
I stumbled into the same issue and I found an easy solution that does not require to refactor by using the library suggested by asif-ali.
On my current project, I have a NestedScrollView that holds a ConstraintLayout.
This ConstraintLayout contains a complex header made of multiple view, and then my RecyclerView.
Much like you, I needed the whole thing to be scrollable.
That said, when the user wishes to see an item from the particular RecyclerView, you would normally call:
RecyclerView#smoothScrollToPosition(int position)
But since the RecyclerView's height is set to wrap_content the full list is displayed, with as many ViewHolders as there are items in its adapter.
Granted, we do not benefit from recycling, but then why would we need a ScrollView ? Using #asif-ali solution might surely bring recycling optimizations but that's not the point here.
So, we have a fully laid-out RecyclerView. In order to scroll to a particular item (ViewHolder#itemView) position, you can do as followed:
final void smoothScrollToPosition(final int position) {
final ViewHolder itemViewHolder = this.recyclerView.findViewHolderForAdapterPosition(position);
// at this point, the ViewHolder should NOT be null ! Or else, position is incorrect !
final int scrollYTo = (int) itemViewHolder.itemView.getY();
// FYI: in case of a horizontal scrollview, you may use getX();
this.nestedScrollView.smoothScrollTo(
0, // x - for horizontal
scrollYTo
);
}
That's it !
It might be possible child is not fully visible after doing so (in my test case) so I'd suggest to add half the height of the itemView to the scrollYTo variable to make sure the nestedScrollView will scroll enough. If you do so, you might also want to check out in which direction the nestedScrollView must scroll to (either up, then remove half height, or down, then add half height.
[EDIT 1]
After further testing and research, based on this answer: https://stackoverflow.com/a/6831790/3535408 it is actually better and simpler to target the itemView.getBottom. On my app, it works flawlessly.
So the updated code looks as followed:
final void smoothScrollToPosition(final int position) {
final ViewHolder itemViewHolder = this.recyclerView.findViewHolderForAdapterPosition(position);
// at this point, the ViewHolder should NOT be null ! Or else, position is incorrect !
// FYI: in case of a horizontal scrollview, you may use getX();
this.nestedScrollView.smoothScrollTo(
0, // x - for horizontal
itemViewHolder.itemView.getBottom()
);
}
I think this is what you want, have a look: link

Recyclerview binds all views at the same time

I have a vertical recyclerview (with a GridLayoutManager) inside another recyclerview (with LinearLayoutManager). The problem I am facing right now is that, the inner recyclerview (with GridLayoutManager) binds all of it's items at the same time, even the views that are not on the screen at the moment (onBindViewHolder() gets called for all of its items).
To give you more information, in my layout file, I put height of my recycler view as wrap_content.
I think the problem is, since there are 2 nested vertically recyclerviews, when the parent RV wants to measure its children and the children is another RV, in onMeasure() it computes the size needed for the entire RV, not just the portion that it wants to bind on the screen.
Any idea how to solve this?
Here is the layout file for my outer recyclerview:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="#+id/component_list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
And here is the code for my inner recyclerview:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/container"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="#dimen/gutter"
android:paddingBottom="#dimen/gutter">
<TextView
android:id="#+id/title_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="#dimen/gutter"
android:textSize="30sp"
android:textColor="#android:color/white"
android:fontFamily="sans-serif-thin"/>
<android.support.v7.widget.RecyclerView
android:id="#+id/my_slider"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
P.S.: I'm using this adapter delegate for my outer recyclerview:
https://github.com/sockeqwe/AdapterDelegates
I think nested recyclerviews are a very bad idea. When i try to scroll, which recyclerview has to respond the the scolling, the parrent or child.
That is why I think you are looking for the ExpandableListView? That's limited to only two levels of listings, but that sounds like it would work for your needs). It also solves the soling issue.
It would look something like this:
EDIT: even nested ExpandableListViews are possible:
EDIT: check this lib for horizontal scroling
This is a known bug.
You should not put a RecyclerView inside another RecyclerView because RecyclerView gives its children infinite space. Hence the inner RecyclerView keeps measuring till the dataset is exhausted. Try setting setAutoMeasureEnabled(false) to false on layout manager or you can solve this problem by using a wrapper adapter instead of inner recycler view.
The first thing you need to know is that, when you nest scrolling layouts, the inner ones will get infinity allowed height, effectively making them wrap_content. There is in fact a relatively easy way to fix this problem.
Say I had two nested RecyclerViews such as these, in this case vertically oriented.
<RecyclerView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical>
<View .../>
<!-- other stuff -->
<RecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"/>
</RecyclerView>
The inner recyclerView here will bind all of it's children immediately every time because, from it's position, your screen will have infinite height.
The solution is to set the height of your inner recyclerview to some static value, not wrap_content or match parent, as either of those will simply fill up the outer recyclerview with one view that will all be bound at once due to it's large height. If you make the height of the inner recyclerview the same as the display's height, you should see your problem go away.
Here is an implementation that will not bind all children at once:
<RecyclerView
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical>
<View .../>
<!-- other stuff -->
<RecyclerView
android:layout_width="match_parent"
android:layout_height="#dimen/screen_height"
android:orientation="vertical"/>
</RecyclerView>
Note the layout_height of the inner RecyclerView is now a fixed value pulled from the dimensions file. You yourself will have to come up with a reasonable value to put there.
Side Note: In order to make all of this work and for scrolling to work properly, you may have to play around with the parameter: NestedScrollingEnabled in your RecyclerViews - there are several known bugs relating to this that you may need to work around.
i.e.: innerRecyclerView.setHasFixedSize(true); and innerRecyclerView.setNestedScrollingEnabled(false).
so what happens here when you place a scrollview(no fixed size because of wrap content) inside another scrollview(again no fixed size because of wrap content),both nested scroll view fails to render.
So there is two solutions--
1- Either you will have to think of alternative solution for nested scrollviews
2- You can give outside recyclerview cell fixed height so that inside recycler view can get some fixed layout to render itself.
I could solve my issue by using only one Recyclerview, where it has a grid layout, and based on the component items i'm adding into it, i change the spancount for that. Basically instead of adding the inner recyclerview, i add the items that were supposed to go to the inner recyclerview, to the outer recyclerview.

How do I make a FrameLayout fill the height of its parent so the whole page scrolls together?

I have a FrameLayout that loads Fragments by tapping on tabs in a TabWidget. I can't figure out how to make the height of the FrameLayout as tall as its content, so that the whole containing ScrollView will scroll together as one instead of a separate scrolling view.
Here's a visual example of this Fragment's structure:
As you can see, the Frame Layout Visible Height only reveals one row of the Fragment, when in fact, there are a few. I can scroll within the FrameLayout to see the other rows as it is now, but that's not what I'm going for. The FrameLayout is made up of a LinearLayout containing a GridView with their layout_heights set to wrap_content.
I tried hardcoding the height of the FrameLayout to something like 500dp and it works great except for the fact that it's no longer dynamically sized. Would I need to resize the FrameLayout programmatically each time a new image is loaded into the inner content? Is there a layout attribute I can set so it'll stretch its height to match its inner content?
Here's my layout xml file:
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="200dp">
<!-- CONTAINS USER INFO AND STATS -->
</RelativeLayout>
<android.support.v4.app.FragmentTabHost
android:id="#android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#ffffff">
<TabWidget
android:id="#android:id/tabs"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:weightSum="2">
</TabWidget>
<FrameLayout
android:id="#android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
>
</FrameLayout>
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
</LinearLayout>
</ScrollView>
Thank you!
Since I'm going to set a bounty on this, I thought I'd share what I've figured out so far.
In the thumbnails, onSuccess when each image is loaded, I'm calling a function in the GridLayout that holds the images that counts the images and sets the height of the GridLayout. This works fine, although it seems like it'd be a bit inefficient.
What I'm doing is setting the GridLayout height and then calling requestLayout and invalidate on it and it's parent(s). This works, but not as the images loading. It'll work if I go to a different tab and return to the thumbnails, oddly enough. Which makes me think I'm not updating at the right time or on the right object.
Anyway, that said. Does anyone know how to make the height of a GridLayout expand to hold its contents (instead of scrolling) so I can scroll the entire page (including the top section)?
I should also add the GridView layout:
<GridView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/grid"
android:stretchMode="columnWidth"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:drawSelectorOnTop="false"
android:fastScrollAlwaysVisible="false"
android:fastScrollEnabled="false"
android:numColumns="3"
android:choiceMode="none">
</GridView>
I was in a similar situation but I had a ListView instead of a GridView. You are right in the part when you have to set the height dynamically each time you add an item or if you call notifyDataSetChanged().
THIS CODE IS FOR LISTVIEW WITH DIFFERENT HEIGHT FOR EACH ROW
private void setListViewHeightBasedOnChildren(MyQueueAdapter listAdapter) {
int desiredWidth = MeasureSpec.makeMeasureSpec(
mListView.getWidth(), MeasureSpec.AT_MOST);
int totalHeight = 0;
View view = null;
int i;
for (i = 0; i < listAdapter.getCount(); i++) {
view = listAdapter.getView(i, view, mListView);
view.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = mListView.getLayoutParams();
params.height = heightList
+ (mListView.getDividerHeight() * (listAdapter
.getCount() + 3));
heightListComplete = params.height;
mListView.setLayoutParams(params);
}
You need to modify this code according to your needs, you don't need the loop as the height of each row is static in your case. If you need more help let me know.
ALTERNATIVE
If you know the height of the view in dp you can easily convert the dp in px and set the height of your gridview according to number of rows.
When using dynamic sizes you'll run into problems once you put match_parent inside a wrap_content thing. One tries to get a small as it's content and the content tries to be as big as it's parent. Neither side will know how to scale properly in the end.
ScrollView is such a thing that falls in this category. It's a scalable window to it's content so it can't be wrap_content and the content can't be match_parent because it's parent is a virtual infinite space.
Change <ScrollView android:layout_height="wrap_content" to match_parent (or a fixed size).
To solve the size of the content
set the root layout (LinearLayout in your case) of your ScrollView to be a fixed size so it's content can be match_parent again.
use wrap_content all the way.
combine the two: wrap_content until a child defines an absolute size, then match_parent inside there.
The wrap_content route will only work if all the elements in the layout from inner to outer most expand properly based on their content. Nothing can rely on parent bounds unless you add some.
Your content looks rather dynamic in size. So it is likely that you need to use some code to manually set sizes based on content. E.g. if those images inside your tab frame are a GridView (essentially ScrollView with grid content again) you'll need to set it's size manually. More than 1 degree of freedom in wrapping dynamically sizing containers isn't solvable automatically.
Parent of your frame layout is linear layout whose height is wrap_content. also, your framelayout's height is wrap_content. change both of them to fill_parent. using match_parent is more preferred now a days insted of fill_parent

Categories

Resources