Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android GridVIew Change number of columns depending on Orientation

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

like image 608
srikanth sanagapalli Avatar asked Oct 17 '12 04:10

srikanth sanagapalli


4 Answers

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

like image 178
urSus Avatar answered Oct 19 '22 21:10

urSus


@Override
public void onConfigurationChanged(Configuration newConfig) {
    grid.setNumColumns(newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE ? 3 : 2);
    super.onConfigurationChanged(newConfig);
}
like image 26
Jin35 Avatar answered Oct 19 '22 21:10

Jin35


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);
like image 38
Pratik Butani Avatar answered Oct 19 '22 21:10

Pratik Butani


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();
}
like image 24
almisoft Avatar answered Oct 19 '22 21:10

almisoft