Changement du nombre de colonnes avec GridLayoutManager et RecyclerView

a L'intérieur de mon fragment je mets mon GridLayout de la manière suivante: mRecycler.setLayoutManager(new GridLayoutManager(rootView.getContext(), 2));

Donc, je veux juste changer 24 lorsque l'utilisateur fait pivoter le téléphone/tablette. J'ai lu sur onConfigurationChanged et j'ai essayé de faire en sorte que ça marche pour mon affaire, mais ça ne va pas dans le bon sens. Quand je tourne mon téléphone, l'application se bloque...

Pourriez-vous me dire comment résoudre ce problème?

Voici mon approche pour trouver la solution, qui ne fonctionne pas correctement:

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

        int orientation = newConfig.orientation;

        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
            mRecycler.setLayoutManager(new GridLayoutManager(mContext, 2));
        } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
            mRecycler.setLayoutManager(new GridLayoutManager(mContext, 4));
        }
    }

Merci d'avance!

45
demandé sur fapps 2015-04-11 18:49:38

7 réponses

essayez de gérer cela dans votre méthode onCreateView à la place car il sera appelé chaque fois qu'il y a un changement d'orientation:

if(getActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
     mRecycler.setLayoutManager(new GridLayoutManager(mContext, 2));
}
else{
     mRecycler.setLayoutManager(new GridLayoutManager(mContext, 4));
}
58
répondu SobaDeveloper 2015-04-11 20:12:19

si vous avez plus d'une condition ou utilisez la valeur dans plusieurs endroits cela peut devenir hors de contrôle assez rapidement. Je suggère de créer la structure suivante:

res
  - values
    - dimens.xml
  - values-land
    - dimens.xml

res/values/dimens.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="gallery_columns">2</integer>
</resources>

et res/values-land/dimens.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <integer name="gallery_columns">4</integer>
</resources>

Et le code devient alors (et toujours séjours) comme ceci:

final int columns = getResources().getInteger(R.integer.gallery_columns);
mRecycler.setLayoutManager(new GridLayoutManager(mContext, columns));

Vous pouvez facilement voir combien il est facile d'ajouter de nouvelles façons de déterminer le nombre de colonnes, par exemple à l'aide de -w500dp/-w600dp/-w700dp dossiers de ressources au lieu de -land.

il est aussi assez facile de regrouper ces dossiers dans des dossiers de ressources séparés au cas où vous ne voudriez pas encombrer vos autres ressources (plus pertinentes):

android {
    sourceSets.main.res.srcDir 'src/main/res-overrides' // add alongside src/main/res
}
70
répondu TWiStErRob 2015-10-11 21:25:46

La Vue Recycle supporte la vue AutofitRecycleView.

Vous devez ajouter android:numColumns="auto_fit" dans votre fichier xml.

vous pouvez Vous référer à ce AutofitRecycleViewLink

6
répondu kattashri 2016-05-04 09:02:11

une façon plus robuste de déterminer le non. de colonnes serait de le calculer basé sur la largeur de l'écran et à l'exécution. J'utilise normalement la fonction suivante pour cela.

public static int calculateNoOfColumns(Context context) {
    DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
    float dpWidth = displayMetrics.widthPixels / displayMetrics.density;
    int scalingFactor = 200; // You can vary the value held by the scalingFactor
    // variable. The smaller it is the more no. of columns you can display, and the
    // larger the value the less no. of columns will be calculated. It is the scaling
    // factor to tweak to your needs.
    int columnCount = (int) (dpWidth / scalingFactor);
    return (columnCount>=2?columnCount:2); // if column no. is less than 2, we still display 2 columns
}

C'est une méthode dynamique pour calculer avec précision le pas. des colonnes. Ce sera plus souple pour les utilisateurs de différentes tailles d'écran sans être réglementé à seulement deux valeurs possibles.

NB: Vous pouvez varier la valeur détenue par le scalingFactor variable. Plus il est petit, plus il est non. des colonnes que vous pouvez afficher, et plus la valeur est grande moins Non. des colonnes sera calculée. Il est le facteur d'échelle pour l'ajuster à vos besoins.

5
répondu Rowland Mtetezi 2018-01-17 10:44:21
mRecyclerView = (RecyclerView) v.findViewById(R.id.recyclerView);      

mStaggeredGridLayoutManager = new StaggeredGridLayoutManager(
       1, //number of grid columns
       GridLayoutManager.VERTICAL);      

mRecyclerView.setLayoutManager(mStaggeredGridLayoutManager);

puis quand l'utilisateur tourne l'écran capturez l'événement, et changez le nombre de colonnes automatiquement

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    if (getActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {           
            mStaggeredGridLayoutManager.setSpanCount(1);

    } else {           
            //show in two columns
            mStaggeredGridLayoutManager.setSpanCount(2);           
    }
}
2
répondu Vladimir Salguero 2016-09-19 20:27:40

j'ai fini par gérer ça dans la méthode onCreate.

private RecyclerView recyclerView = null;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    recyclerView.setHasFixedSize(true);
    Configuration orientation = new Configuration();
    if(this.recyclerView.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
        recyclerView.setLayoutManager(new GridLayoutManager(this, 2));
    } else if (this.recyclerView.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
        recyclerView.setLayoutManager(new GridLayoutManager(this, 4));
    }
            connectGetApiData();
}

cela a parfaitement fonctionné pour mon application.

1
répondu user6731701 2017-08-12 17:30:06

vous pouvez implémenter la méthode dans votre recyclerView onMeasure. Tout d'abord, créez la classe java AutofitRecyclerView

public class AutofitRecyclerView extends RecyclerView {
//private GridLayoutManager manager;
private StaggeredGridLayoutManager manager;
private int columnWidth = -1;

public AutofitRecyclerView(Context context) {
    super(context);
    init(context, null);
}

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

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

private void init(Context context, AttributeSet attrs) {
    if (attrs != null) {
        int[] attrsArray = {
                android.R.attr.columnWidth
        };
        TypedArray array = context.obtainStyledAttributes(attrs, attrsArray);
        columnWidth = array.getDimensionPixelSize(0, -1);
        array.recycle();
    }

    manager = new StaggeredGridLayoutManager(1, GridLayoutManager.VERTICAL);
    setLayoutManager(manager);

}

@Override
protected void onMeasure(int widthSpec, int heightSpec) {
    super.onMeasure(widthSpec, heightSpec);
    if (columnWidth > 0) {
        int spanCount = Math.max(1, getMeasuredWidth() / columnWidth);
        manager.setSpanCount(spanCount);
    }
}}

dans votre fichier de mise en page XLM activity_main.xml

<yourpackagename.AutofitRecyclerView
            android:id="@+id/recycler_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:columnWidth="@dimen/column_width"
            android:clipToPadding="false"/>

puis définissez la variable à la largeur de chaque élément dans la taille de fichier du dossier valeurs valeurs/dimensions.xml

<resources>
  <dimen name="column_width">250dp</dimen>
</resources>

il peut être pour des résolutions d'écran différentes valeurs-xxhdpi / dimensions.xml

<resources>
 <dimen name="column_width">280dp</dimen>
</resources>

dans votre activité dans le lieu de l'événement code suivant

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    recyclerView.addItemDecoration(new MarginDecoration(this));
    recyclerView.setHasFixedSize(true);
    recyclerView.setAdapter(new NumberedAdapter(50));
}
0
répondu Vladimir Salguero 2016-09-07 19:59:33