38

In meinem Fragment ich meine Gridlayout in der folgenden Art und Weise bin Einstellung: mRecycler.setLayoutManager(new GridLayoutManager(rootView.getContext(), 2));ändern Anzahl der Spalten mit GridLayoutManager und RecyclerView

Also, ich möchte nur, dass 2 ein 4 für ändern, wenn der Benutzer das Telefon dreht/Tablette. Ich habe über onConfigurationChanged gelesen und ich habe versucht, es für meinen Fall funktionieren zu lassen, aber es geht nicht richtig. Wenn ich mein Handy rotiere, stürzt die App ab ...

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

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

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

Vielen Dank im Voraus!

+0

fügen Sie bitte ein Absturzprotokoll hinzu –

+0

Ich habe gerade einen Blick auf meine Logcat geworfen und dies verursachte nicht den Absturz. Aber es funktioniert immer noch nicht. – fapps

+0

Ich würde keinen neuen Manager erstellen, sondern stattdessen einen vorhandenen verwenden. Verwenden Sie getLayoutManager() in Ihrer Recycleransicht, um sie in GridLayoutManager zu konvertieren. Auf diesem Manager-Aufruf setSpanCount (orientation == Porträt? 2: 4) Und um die Ansicht neu zu zeichnen Aufruf adaper.notifyDatasetChanged() Dies sollte gut funktionieren, wenn Ihre Ansicht nicht jedes Mal neu gezeichnet wird. –

Antwort

51

Versuchen Sie dies in Ihrer onCreateView Methode Handhabung statt, da es jedes Mal aufgerufen wird, gibt es eine Orientierungsänderung:

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

Ich werde es ausprobieren und Ihnen davon erzählen. Vielen Dank! – fapps

+0

Danke! Das hat super funktioniert! – fapps

+2

Ist das das richtige Verhalten, um diese Aufgabe zu erledigen? Danke – ciccioska

55

Wenn Sie mehr als eine Bedingung oder den Wert an mehreren Stellen verwenden dieser heraus gehen kann Hand ziemlich schnell. Ich schlage vor, die folgende Struktur zu erstellen:

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

mit res/values/dimens.xml Wesen:

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

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

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

und der Code wird dann (und für immer bleibt) wie folgt aus:

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 Ermitteln der Spaltenanzahl hinzuzufügen, z. B. unter Verwendung von -w500dp/-w600dp/-w700dp Ressourcenordnern anstelle von -land.

Es ist auch ganz einfach diese Ordner in separate Ressourcenordner, falls Gruppe, die Sie wollen nicht Ihre andere (mehr relevant) Ressourcen Krempel:

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

Das Papier Ansicht AutofitRecycleView unterstützt.

Sie müssen android:numColumns="auto_fit" in Ihrer XML-Datei hinzufügen.

können Sie auf diese verweisen AutofitRecycleViewLink

+0

Ausgezeichnete Umsetzung! Drehen Sie den Bildschirm, um die Anzahl der Spalten dynamisch zu ändern, und behalten Sie die Position von scroll –

+0

Dies ist wahrscheinlich die perfekte Lösung, aber nicht, wenn Ihr Designer etwas anderes entscheidet. Manchmal macht uns das Design auf die harte Tour einfach zur Umsetzung – Sniper

0

Sie können die Methode in Ihrem recyclerView onMeasure implementieren. Erstellen Sie zunächst die Java-Klasse 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 Layout-Datei 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"/> 

dann wird die Variable auf die Breite der einzelnen Elemente in der Dateigröße der Werte Ordner Werte/Dimensionen.xml

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

Es kann in der onCreate Veranstaltung für verschiedene Bildschirmauflösungen Werte-xxhdpi/dimens.xml

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

In Ihrer Tätigkeit sein der folgende Code

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

Im onCreate() Ereignis können Sie StaggeredGridLayoutManager

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

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

mRecyclerView.setLayoutManager(mStaggeredGridLayoutManager); 
verwenden Dann werden 10

, wenn der Benutzer dreht die Bildschirmaufzeichnung der Veranstaltung, 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);   
    } 
} 
4

eine robustere Art und Weise des nicht zu bestimmen. von Spalten wäre es, basierend auf der Bildschirmbreite und zur Laufzeit zu berechnen. Ich verwende normalerweise die folgende Funktion dafür.

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 zur genauen Berechnung der Nr. von Spalten. Dies wird für Benutzer mit unterschiedlichen Bildschirmgrößen adaptiver sein, ohne auf nur zwei mögliche Werte beschränkt zu sein.

NB: Sie den Wert durch die Variable scalingFactor gehalten variieren kann. Je kleiner es ist, desto mehr nein. der Spalten, die Sie anzeigen können, und je größer der Wert, desto weniger. von Spalten werden berechnet. Es ist der Skalierungsfaktor, der an Ihre Bedürfnisse angepasst werden kann.

0

Ich endete damit in der onCreate-Methode.

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

Es funktionierte perfekt für meine App.

Verwandte Themen