Android GridVIew Change number of columns depending on Orientation

37,385

Solution 1

Use the powerful resource system.

In the xml layout, set the number of columns to a integer resource and then in /values/integers.xml set it to 2 for portrait and in /values-land/integers.xml set it to 3 for landscape

// well, if you do configChanges in manifest, you will have to change column count from java in onConfogurationChanged

Solution 2

@Override
public void onConfigurationChanged(Configuration newConfig) {
    grid.setNumColumns(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE ? 3 : 2);
    super.onConfigurationChanged(newConfig);
}

Solution 3

you can set number of columns programatically using

float scalefactor = getResources().getDisplayMetrics().density * 100;
int number = getWindowManager().getDefaultDisplay().getWidth();
int columns = (int) ((float) number / (float) scalefactor);
gridView.setNumColumns(columns);

Solution 4

My solution:

values/dimens.xml:

<resources>
    <dimen name="grip_view_entry_size">160dp</dimen>
    <dimen name="grip_view_spacing">10dp</dimen>
</resources>

layout/gridview.xml

<GridView android:id="@+id/android:list"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:numColumns="auto_fit"
    android:verticalSpacing="@dimen/grip_view_spacing"
    android:horizontalSpacing="@dimen/grip_view_spacing"
    android:stretchMode="columnWidth"
    android:gravity="center"
    android:scrollingCache="false"
    android:fastScrollEnabled="true"
    android:animationCache="false"/>

in your fragment:

private void refreshGridView() {

    int gridViewEntrySize = getResources().getDimensionPixelSize(R.dimen.grip_view_entry_size);
    int gridViewSpacing = getResources().getDimensionPixelSize(R.dimen.grip_view_spacing);

    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
    Display display = wm.getDefaultDisplay();

    int numColumns = (display.getWidth() - gridViewSpacing) / (gridViewEntrySize + gridViewSpacing);

    gridView.setNumColumns(numColumns);
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    refreshGridView();
}

@Override
public void onResume() {
    super.onResume();
    refreshGridView();
}

Solution 5

    @Override
    public void onConfigurationChanged(Configuration newConfig) {

        super.onConfigurationChanged(newConfig);
        if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
            setContentView(R.layout.lay_vertical);
        } else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            setContentView(R.layout.lay_horizontal);
        }

    };

Then load the data in gridview again according to your need.

Put android:configChanges="orientation" for that activity node in the manifest.

Share:
37,385
srikanth sanagapalli
Author by

srikanth sanagapalli

Updated on November 30, 2020

Comments

  • srikanth sanagapalli
    srikanth sanagapalli over 3 years

    I want to display 6 images in the form of grid as follows.

    in portrait orientation,2 coumns, 3 rows and in landscare orientation 3 columns, 2 rows

    By using Android GridView and by defining different grid layouts in layout-port and layout-land directories I was able to achieve this effect.

    Later as per my activity requirement, I added one parameter in manifest.xml that is

    android:configChanges = "mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|fontScale|screenSize"`
    

    to stop my activity to recreate once screen orientation changes.

    After adding this parameter, my grid view is not behaving in expected way. It sometimes shows 1 column, sometimes 2 columns, and sometimes 3 columns.

    I am placing gridView.setNumberOfColumns(2) or gridView.setNumberOfColumns(3) methods in the get view method of my grid adapter depending on orientation of the device.

    Please help me to achieve this effect without removing the android:configChanges parameter in Manifest.xml

  • Jin35
    Jin35 over 11 years
    You will get exception, because setContentView can be called only once.
  • Amit Hooda
    Amit Hooda over 11 years
    I dont think so that setcontentview can be called only once,instead all the things in that particular layout will have to be reinitialized with the things inside it by findViewById and it will go smooth
  • Niklas
    Niklas over 10 years
    Thanks man. Now it is values-land and only values for the portrait mode, anyway +1.
  • defhlt
    defhlt over 9 years
    I think it should be values-land and values-port (instead of sheer values) for better compatibility with various devices.
  • Jaky71
    Jaky71 over 8 years
    this worked and should be accepted as correct answer
  • Ody
    Ody over 8 years
    getDefaultDisplay().getWidth() is now deprecated. Is there another way of getting it?