Exploring

Dirty ways to use GirdView and ListView in a ScrollView Android

noras noras |

Tags: #Android #Android Studio #Java

One of the dirty ways (in my opinion) to use the ListView and GridView in android is inside a ScrollView. The reason I do it sometimes is to have multiple ListViews or GridViews or a combination of both with other elements inside a LinearLayout.
This time I will review how to achieve the following:

  • GirdView inside a ScrollView
  • ListView inside a ScrollView
  • Horizontal GridView

GirdView inside a ScrollView

After adding the your gridview in the xml as usual. With height set to wrap_contnet. You need a way to set the height with respect to the row count. In order to do that you have to call the following function after filling your adapter. If you have a dynamic column count. Just use the mGridView.getNumColumns();.

 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;

        if(items==0)
            return;
        View listItem = listAdapter.getView(0, null, gridView);
        listItem.measure(0, 0);
        totalHeight = listItem.getMeasuredHeight()+20; //(padding)

        float x = 1;
        if( items > columns ){
            x = items/columns;

            if(items%columns==0)
                rows=(int) x;
            else
                rows = (int) (x + 1);

            totalHeight *= rows;
            
        }
        ViewGroup.LayoutParams params = gridView.getLayoutParams();
        params.height = totalHeight;
        gridView.setLayoutParams(params);
        
    }

List views inside a scroll view

The same case here but with a ListView instead…

 public void setListViewHeightBasedOnChildren(ListView listView) {
        ListAdapter listAdapter = listView.getAdapter();
        if (listAdapter == null) {
            // pre-condition
            return;
        }

        int totalHeight = listView.getPaddingTop() + listView.getPaddingBottom();
        for (int i = 0; i < listAdapter.getCount(); i++) {
            View listItem = listAdapter.getView(i, null, listView);
            if (listItem instanceof ViewGroup) {
                listItem.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            }
            listItem.measure(0, 0);
            totalHeight += listItem.getMeasuredHeight();
        }

        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
    }

Horizontal GridView

The trick here is using a HorizontalScrollView inside your LinearLayout.

  <HorizontalScrollView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:background="@color/divider"
                android:padding="2dp">

                <LinearLayout
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">

                    <GridView xmlns:android="http://schemas.android.com/apk/res/android"
                        android:id="@+id/smart_gridview"

                        android:layout_width="fill_parent"
                        android:layout_height="wrap_content"
                        android:layout_gravity="center"
                        android:layout_marginLeft="1dp"
                        android:layout_marginRight="1dp"
                        android:clipToPadding="false"
                        android:columnWidth="150dp"
                        android:drawSelectorOnTop="true"
                        android:gravity="center"
                        android:horizontalSpacing="1dp"
                        android:listSelector="@drawable/grid_item_selector"
                        android:numColumns="auto_fit"
                        android:overScrollMode="never"
                        android:scrollbars="horizontal"
                        android:stretchMode="columnWidth"
                        android:verticalSpacing="2dp" />
                </LinearLayout>
            </HorizontalScrollView>

Then use the java code used to fill the adapter and expand the gridview :

  public void setHorizontalGridView(final List<Product> products) {
        try {
            DisplayMetrics dm = new DisplayMetrics();
            getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
            final float density = dm.density;
            int totalWidth = (int) (150 * products.size() * density);
            final int singleItemWidth = (int) (150 * density);

            final LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
                    totalWidth, LinearLayout.LayoutParams.MATCH_PARENT);


            getActivity().runOnUiThread(new Runnable() {
                public void run() {

                    horizontalGridView.setLayoutParams(params);
                    horizontalGridView.setColumnWidth(singleItemWidth);
                    horizontalGridView.setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
                    horizontalGridView.setHorizontalSpacing((int) (density * 5));
                    horizontalGridView.setNumColumns(products.size());
                    horizontalGridViewAdapter.refill(products);     

                }
            });

        } catch (Exception e) {
        }
    }

About the author

noras

"Senior Software Engineer. MSc in Computer systems and Networks with big interest in security. Loves to play with Android code and does security research for fun and profit. Speaks 4 languages and codes in much more."

Related articles

Tags: #Android #Android Studio #Java




Copyright © 2019 - nindoda.com