How to put GridView inside ScrollView

AndroidGridviewScrollview

Android Problem Overview


I have to design layout such that whole layout should scroll and inside layout I have to display related content in Grid form so I decided to use GridView.But problem is that I’m unable to use GridView inside ScrollView I have read documentation(Documentation also saying that we should not use GridView inside ScrollView) also.But I have to do this,so can any please give me some idea about this.Thanks

Android Solutions


Solution 1 - Android

There are definitely benefits to a GridView beside the inherent scrolling. For example, a consistent, dynamic layout of cells that will expand and contract based on the data you pass into it. So, when people say it's not good to desire such a functionality, I think that's wrong because you could want the dynamic grid of images (views) inside of a scrolling view, but want that entire scrolling view to contain other things than just the grid cells.

Now, here 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.

Solution 2 - Android

I know I'm late but I have another solution which I must share and which works flawlessly. Here, the method calculates the GridView height based on the number of items it contains and sets the height to the GridView at run time.

public void setGridViewHeightBasedOnChildren(GridView gridView, int columns) {
        ListAdapter listAdapter = gridView.getAdapter(); 
        if (listAdapter == null) {
            // pre-condition
            return;
        }
        
        int totalHeight = 0;
        int items = listAdapter.getCount();
        int rows = 0;
        
        View listItem = listAdapter.getView(0, null, gridView);
        listItem.measure(0, 0);
        totalHeight = listItem.getMeasuredHeight();
        
        float x = 1;
        if( items > columns ){
        	x = items/columns;
        	rows = (int) (x + 1);
        	totalHeight *= rows;
        }
        
        ViewGroup.LayoutParams params = gridView.getLayoutParams();
        params.height = totalHeight;
        gridView.setLayoutParams(params);
        
}

After you have called setAdapter on your gridview, just call

setGridViewHeightBasedOnChildren( <yourGridView> , <no of grid view columns> )
    

and it'll work.

You can the define the gridview in your xml as you normally do

and let the code take care of it. :)

Solution 3 - Android

I found a way to give the GridView a fixed size inside ScrollView, and enable scrolling it. That allows you to see the entire ScrollView without having to scroll all elements of the GridView, and it makes more sense to me that using an ExpandableHeightGridView.

To do so, you would have to implement a new class extending GridView and override onTouchEvent() to call requestDisallowInterceptTouchEvent(true). Thus, the parent view will leave the Grid intercept touch events.

GridViewScrollable.java:

package com.example;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.GridView;

public class GridViewScrollable extends GridView {

    public GridViewAdjuntos(Context context) {
        super(context);
    }

    public GridViewAdjuntos(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public GridViewAdjuntos(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev){
        // Called when a child does not want this parent and its ancestors to intercept touch events.
        requestDisallowInterceptTouchEvent(true);
        return super.onTouchEvent(ev);
    }
}

Add it in your layout with the characteristics and margins you want, inside a ScrollView:

<ScrollView 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"
android:isScrollContainer="true" >

    <com.example.GridViewScrollable
    android:id="@+id/myGVS"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:numColumns="auto_fit"
    android:stretchMode="columnWidth" />

</ScrollView>

And just get it in your activity:

GridViewScrollable myGridView = (GridViewScrollable) findViewById(R.id.myGVS);

I hope it helps =)

In Kotlin:

class GridViewScrollable @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : GridView(context, attrs, defStyleAttr) {

    override fun onTouchEvent(ev: MotionEvent?): Boolean {
        // Called when a child does not want this parent and its ancestors to intercept touch events.
        requestDisallowInterceptTouchEvent(true)
        return super.onTouchEvent(ev)
    }
}

There is an annoying warning: "Custom view GridViewScrollable overrides onTouchEvent but not performClick". Please, resolve yourself if you want.

Solution 4 - Android

I was also trying to make a GridView scrollable inside a NestedScrollView.

This answer on another question helped me: https://stackoverflow.com/a/38612612

> Enable your GridView Property as > > android:nestedScrollingEnabled="true"

Original poster: Droid_Dev

Solution 5 - Android

To use gridview inside scrollview, set scrollview android:fillViewport="true"

I know its late to answer here but may be useful to some new developers.

Solution 6 - Android

If you have used dennisdrew's answer and you have content above your grid and it gets hidden when you open your view simply add the last line below

ExpandableHeightGridView gridView = (ExpandableHeightGridView) findViewById(R.id.myId);
gridView.setAdapter(yourAdapter);
gridView.setExpanded(true);
gridView.setFocusable(false);

Solution 7 - Android

It's better to use ExpandableHeightlistView or ExpandableHeightGridView inside scrollview.

Logic

Calculate entire height by providing a very large height hint. But do not use the highest 2 bits of this integer; those are reserved for the MeasureSpec mode.

int expandSpec = MeasureSpec.makeMeasureSpec(
 Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
 super.onMeasure(widthMeasureSpec, expandSpec);
 
 ViewGroup.LayoutParams params = getLayoutParams();
 params.height = getMeasuredHeight();

for further information explore the example below with demo

http://www.londatiga.net/it/programming/android/make-android-listview-gridview-expandable-inside-scrollview/

Solution 8 - Android

i would not force the issue. GridView does not work well in a scrollView. instead convert your gridview into a recyclerview and use a gridLayoutManager to resolve the issue.

Solution 9 - Android

Trust this solution worked for me!

android:nestedScrollingEnabled="true"

The code above inside grid view enables to scroll gridview and set width and height android:layout_width="match_parent" android:layout_height="200sp"

This will work even inside scrollview Thanks for the previous answers I figured out this for the previous answers. Thanks to them

Solution 10 - Android

 gridView.setOnTouchListener(new View.OnTouchListener() {
                @Override
                public boolean onTouch(View v, MotionEvent event) {
                    v.getParent().requestDisallowInterceptTouchEvent(true);
                    return false;
                }

            });

// Setting on Touch Listener for handling the touch inside ScrollView

Solution 11 - Android

If you want to have GridView inside ScrollView / RecyclerView, there are 2 cases:

  1. If you want to have GridView with all rows visible, see https://stackoverflow.com/a/63724794/2914140.

  2. If you want to have one row visible in GridView, but be able to scroll it (to reveal other rows), see https://stackoverflow.com/a/26852498/2914140.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDilipView Question on Stackoverflow
Solution 1 - AndroiddennisdrewView Answer on Stackoverflow
Solution 2 - AndroidVikram GuptaView Answer on Stackoverflow
Solution 3 - AndroidLionel T.View Answer on Stackoverflow
Solution 4 - AndroidStephen EmeryView Answer on Stackoverflow
Solution 5 - AndroidDharmendra ChaudharyView Answer on Stackoverflow
Solution 6 - Androidaidan slineyView Answer on Stackoverflow
Solution 7 - AndroidKishore ReddyView Answer on Stackoverflow
Solution 8 - Androidj2emanueView Answer on Stackoverflow
Solution 9 - AndroidVijaykanth ReddyView Answer on Stackoverflow
Solution 10 - AndroidAbdurrhman SeferView Answer on Stackoverflow
Solution 11 - AndroidCoolMindView Answer on Stackoverflow