Modification du nombre de colonnes avec GridLayoutManager et RecyclerView

À l'intérieur de mon fragment, je définis mon GridLayout de la manière suivante: mRecycler.setLayoutManager(new GridLayoutManager(rootView.getContext(), 2));

Donc, je veux simplement changer ce 2 pour un 4 lorsque l'utilisateur tourne le téléphone / tablette. J'ai lu onConfigurationChanged et j'ai essayé de le faire fonctionner pour mon cas, mais cela ne va pas dans le bon sens. Lorsque 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!

7 Solutions collect form web for “Modification du nombre de colonnes avec GridLayoutManager et RecyclerView”

Essayez de traiter cela dans votre méthode onCreateView, puisqu'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)); } 

Si vous avez plus d'une condition ou que vous utilisez la valeur dans plusieurs endroits, cela peut être très rapide. Je suggère de créer la structure suivante:

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

Avec res/values/dimens.xml étant:

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

Et res/values-land/dimens.xml étant:

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

Et le code devient (et reste pour toujours) comme ceci:

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

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

Il est également très facile de regrouper ces dossiers dans un dossier de ressources distinct dans le cas où vous ne voulez pas encombrer vos autres ressources (plus pertinentes):

 android { sourceSets.main.res.srcDir 'src/main/res-overrides' // add alongside src/main/res } 

La vue Recycle prend en charge AutofitRecycleView.

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

Vous pouvez vous référer à cet AutofitRecycleViewLink

Une façon plus robuste de déterminer le no. Des colonnes serait de calculer en fonction de la largeur de l'écran et au moment de l'exécution. J'utilise habituellement la fonction suivante pour cela.

 public static int calculateNoOfColumns(Context context) { DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); float dpWidth = displayMetrics.widthPixels / displayMetrics.density; int scalingFactor = 180; int noOfColumns = (int) (dpWidth / scalingFactor); return noOfColumns; } 

C'est une méthode plus dynamique pour calculer avec précision le no. De colonnes. Cela sera plus adapté pour les utilisateurs de différentes tailles d'écran sans être résisté à seulement deux valeurs possibles.

NB: Vous pouvez modifier la valeur retenue par la variable scalingFactor . Plus il est petit, plus il est. Des colonnes que vous pouvez afficher, et plus la valeur est grande, moins. Des colonnes seront calculées. C'est le facteur de mise à l'échelle qui doit être adapté à vos besoins.

Vous pouvez implémenter la méthode dans votre recyclerVoir sur la mesure. 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"/> 

Ensuite, définissez la variable sur la largeur de chaque élément dans la taille du fichier des valeurs valeurs du dossier / dimens.xml

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

Il peut s'agir de différentes valeurs de résolution d'écran-xxhdpi / dimens.xml

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

Dans votre activité dans l'événement onCreate, placez le 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)); } 

Dans l'événement onCreate (), vous pouvez utiliser StaggeredGridLayoutManager

 mRecyclerView = (RecyclerView) v.findViewById(R.id.recyclerView); mStaggeredGridLayoutManager = new StaggeredGridLayoutManager( 1, //number of grid columns GridLayoutManager.VERTICAL); mRecyclerView.setLayoutManager(mStaggeredGridLayoutManager); 

Ensuite, lorsque l'utilisateur tourne la capture d'écran de l'événement et modifie automatiquement le nombre de colonnes

 @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); } } 

J'ai fini par manipuler ceci 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(); } 

Il fonctionnait parfaitement pour mon application.

coAndroid est un fan Android de Google, tout sur les téléphones Android, Android Wear, Android Dev et Android Games Apps.