wake-up-neo.com

Ändern der Spaltenanzahl mit GridLayoutManager und RecyclerView

In meinem Fragment stelle ich mein GridLayout folgendermaßen ein: mRecycler.setLayoutManager(new GridLayoutManager(rootView.getContext(), 2));

Also, ich möchte nur das ändern 2 Für ein 4 wenn der Benutzer das Telefon/Tablet dreht. Ich habe von onConfigurationChanged gelesen und versucht, es für meinen Fall zum Laufen zu bringen, aber es läuft nicht richtig. Wenn ich mein Handy drehe, stürzt die App ab ...

Können Sie mir sagen, wie Sie dieses Problem lösen können?

Hier ist mein Ansatz, um die Lösung zu finden, die nicht richtig funktioniert:

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

Danke im Voraus!

54
fapps

Versuchen Sie stattdessen, dies in Ihrer onCreateView-Methode zu behandeln, da sie jedes Mal aufgerufen wird, wenn sich die Ausrichtung ändert:

if(getActivity().getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
     mRecycler.setLayoutManager(new GridLayoutManager(mContext, 2));
}
else{
     mRecycler.setLayoutManager(new GridLayoutManager(mContext, 4));
}
66
SobaDeveloper

Wenn Sie mehr als eine Bedingung haben oder den Wert an mehreren Stellen verwenden, kann dies ziemlich schnell außer Kontrolle geraten. Ich schlage vor, die folgende Struktur zu erstellen:

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

mit res/values/dimens.xml Sein:

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

und res/values-land/dimens.xml Sein:

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

Und der Code wird (und bleibt) dann so:

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

Sie können leicht erkennen, wie einfach es ist, neue Methoden zum Bestimmen der Spaltenanzahl hinzuzufügen, z. B. mit -w500dp/-w600dp/-w700dp Ressourcenordner anstelle von -land.

Es ist auch ganz einfach, diese Ordner in separate Ressourcenordner zu gruppieren, falls Sie Ihre anderen (relevanteren) Ressourcen nicht überladen möchten:

Android {
    sourceSets.main.res.srcDir 'src/main/res-overrides' // add alongside src/main/res
}
77
TWiStErRob

Die Recycling-Ansicht unterstützt AutofitRecycleView.

Sie müssen Android:numColumns="auto_fit" In Ihre XML-Datei einfügen.

Sie können darauf verweisen AutofitRecycleViewLink

7
kattashri

Eine robustere Methode zur Bestimmung der Nr. von Spalten wäre es, basierend auf der Bildschirmbreite und zur Laufzeit zu berechnen. Normalerweise benutze ich dazu die folgende Funktion.

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
}

Es ist eine dynamischere Methode, um die Nr. Genau zu berechnen. von Spalten. Dies ist für Benutzer mit unterschiedlichen Bildschirmgrößen anpassungsfähiger, ohne auf nur zwei mögliche Werte beschränkt zu sein.

NB: Sie können den Wert der Variablen scalingFactor variieren. Je kleiner es ist, desto mehr nein. Anzahl der Spalten, die Sie anzeigen können, und je größer der Wert, desto weniger Nr. Spaltenanzahl wird berechnet. Es ist der Skalierungsfaktor, den Sie an Ihre Bedürfnisse anpassen können.

7
Rowland Mtetezi

Im onCreate () -Ereignis können Sie StaggeredGridLayoutManager verwenden

mRecyclerView = (RecyclerView) v.findViewById(R.id.recyclerView);      

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

mRecyclerView.setLayoutManager(mStaggeredGridLayoutManager);

Wenn der Benutzer dann den Bildschirm dreht, erfassen Sie das Ereignis und ändern Sie die Anzahl der Spalten automatisch

@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

Ich habe dies in der onCreate-Methode erledigt.

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

Für meine App hat es perfekt geklappt.

1
user6731701

Sie können die Methode in Ihrem recyclerView onMeasure implementieren. Erstellen Sie zuerst die Java class 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);
    }
}}

In Ihrer xlm-Layoutdatei 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"/>

Stellen Sie dann die Variable auf die Breite jedes Elements in der Dateigröße des Ordners values ​​/ dimens.xml ein

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

Es kann für verschiedene Bildschirmauflösungen Werte-xxhdpi/dimens.xml sein

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

Fügen Sie in Ihrer Aktivität im onCreate-Ereignis den folgenden Code ein

@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