web-dev-qa-db-fra.com

Android GridVIew Changer le nombre de colonnes en fonction de l'orientation

Je veux afficher 6 images sous forme de grille comme suit.

en orientation portrait, 2 colonnes, 3 rangées et en orientation paysage 3 colonnes, 2 rangées

En utilisant Android GridView et en définissant différentes dispositions de grille dans les répertoires layout-port et layout-land, j'ai pu obtenir cet effet.

Plus tard, conformément à mes exigences en matière d’activité, j’ai ajouté un paramètre dans le fichier manifest.xml, à savoir: 

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

arrêter mon activité pour recréer une fois l'orientation de l'écran modifiée.

Après avoir ajouté ce paramètre, ma vue de grille ne se comporte pas comme prévu. Il affiche parfois 1 colonne, parfois 2 colonnes et parfois 3 colonnes.

Je place des méthodes gridView.setNumberOfColumns(2) ou gridView.setNumberOfColumns(3) dans la méthode d'affichage de mon adaptateur de grille, en fonction de l'orientation du périphérique.

Aidez-moi à obtenir cet effet sans supprimer le paramètre Android:configChanges dans Manifest.xml.

14

Utilisez le puissant système de ressources.

Dans la présentation XML, définissez le nombre de colonnes sur une ressource entière, puis dans /values/integers.xml, définissez-le sur 2 pour portrait et sur /values-land/integers.xml, définissez-le sur 3 pour paysage.

// bon, si vous faites configChanges dans le manifeste, vous devrez changer le nombre de colonnes de Java dans onConfogurationChanged

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

vous pouvez définir le nombre de colonnes par programmation en utilisant

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

Ma 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"/>

dans votre 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();
}
4
almisoft
    @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);
        }

    };

Chargez ensuite à nouveau les données dans gridview en fonction de vos besoins.

Mettez Android: configChanges = "orientation" pour ce nœud d'activité dans le manifeste.

2
Amit Hooda

Lorsque vous utilisez Android: configChanges = "orientation" dans Manifest, votre activité ne recrée pas sur l'orientation modifiée (Paysage en Portrait ou inversement). Si vous ne souhaitez pas supprimer cette balise du manifeste, vous devez obligatoirement remplacer onConfigchanged et y insérer de la logique de code.

1
Krishnakant Dalal

je l'ai fait en fonction de la taille de l'écran, pas en dpi

public static int getGridColumnsCount(Context context){
    boolean landscape = context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE;

    DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
    float hi=displayMetrics.heightPixels/displayMetrics.xdpi;
    float wi=displayMetrics.widthPixels/displayMetrics.ydpi;
    float screenWidthInch  = landscape ? Math.max(wi, hi) : Math.min(wi, hi);
    float screenWidthCm = screenWidthInch * 2.54f;
    int columns = (int)(screenWidthCm/2);
    return columns < 3 ? 3 : columns;
}
1
John

Voici le XML:

<GridLayout
    Android:id="@+id/gridLayout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:columnCount="@integer/num_columns"
    Android:rowCount="@integer/num_rows"
    Android:orientation="vertical">
    <!-- TextViews, ImageViews, etc -->
</GridLayout>

Et ensuite dans votre fragment:

@BindView(R.id.gridLayout) GridLayout gridLayout;

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    final ArrayList<View> views = new ArrayList<>();
    for (int i = 0; i < gridLayout.getChildCount(); i++) {
        views.add(gridLayout.getChildAt(i));
    }
    gridLayout.removeAllViews();
    gridLayout.setColumnCount(getContext().getResources().getInteger(R.integer.num_columns));
    gridLayout.setRowCount(getContext().getResources().getInteger(R.integer.num_rows));
    for (int i = 0; i < views.size(); i++) {
        views.get(i).setLayoutParams(new GridLayout.LayoutParams());
        gridLayout.addView(views.get(i));
    }
}
0
Lou Morda