Android GridLayoutManager Beispiel

Android GridLayoutManager ist die Implementierung von RecyclerView.LayoutManager zum Anordnen von Elementen in einem Raster. In diesem Tutorial erstellen wir eine Anwendung, die CardViews innerhalb eines RecyclerViews in Form eines GridLayouts anzeigt. Außerdem implementieren wir eine Schnittstelle, die einem RecyclerView-Elementklick ähnelt, wie bei einem ListView itemClickListener.

Android GridLayoutManager

Wir haben bereits einen RecyclerView unter Verwendung eines LinearLayoutManager hier implementiert. Jetzt verwenden wir einen GridLayoutManager, um den RecyclerView als Raster anzuordnen. Nachfolgend finden Sie der Konstruktor für einen GridLayoutManager.

GridLayoutManager (Context context, 
                int spanCount, 
                int orientation, 
                boolean reverseLayout)

reverseLayout, wenn auf true gesetzt, ordnet Elemente vom Ende zum Anfang an. Um die Spannweite für jedes Element festzulegen, rufen wir die Methode setSpanSizeLookup auf dem GridLayoutManager auf. Lassen Sie uns den RecyclerView mit einem GridLayoutManager in einem neuen Android Studio-Projekt implementieren.

Android GridLayoutManager Beispiel Projektaufbau

Das Projekt besteht aus einer einzigen Aktivität: MainActivity.java, einer Adapterklasse: RecyclerViewAdapter.java, einer DataModel.java-Klasse und einer benutzerdefinierten GridLayoutManager-Klasse AutoFitGridLayoutManager.java. Das XML-Layout der MainActivity.java-Klasse ist in der Datei activity_main.xml definiert als

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    android:fitsSystemWindows="true"
    tools:context=".MainActivity">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:scrollbars="vertical"
            app:layout_behavior="@string/appbar_scrolling_view_behavior" />

    </RelativeLayout>

</android.support.design.widget.CoordinatorLayout>

Hinweis: Vergessen Sie nicht, die folgenden Abhängigkeiten für Material Design-Widgets und CardView in der build.gradle-Datei hinzuzufügen.

compile 'com.android.support:cardview-v7:25.1.1'
compile 'com.android.support:design:25.1.1'

Die DataModel.java-Klasse ist unten angegeben: package com.journaldev.recyclerviewgridlayoutmanager;

public class DataModel {

    public String text;
    public int drawable;
    public String color;

    public DataModel(String t, int d, String c )
    {
        text=t;
        drawable=d;
        color=c;
    }
}

Die DataModel-Klasse wird den Text, das zeichnungsfähige Symbol und die Hintergrundfarbe jeder Zellenposition speichern. Die RecyclerViewAdapter.java-Klasse ist unten angegeben:

package com.journaldev.recyclerviewgridlayoutmanager;

import android.content.Context;
import android.graphics.Color;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import java.util.ArrayList;


public class RecyclerViewAdapter extends RecyclerView.Adapter {

    ArrayList mValues;
    Context mContext;
    protected ItemListener mListener;

    public RecyclerViewAdapter(Context context, ArrayList values, ItemListener itemListener) {

        mValues = values;
        mContext = context;
        mListener=itemListener;
    }

    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

        public TextView textView;
        public ImageView imageView;
        public RelativeLayout relativeLayout;
        DataModel item;

        public ViewHolder(View v) {

            super(v);

            v.setOnClickListener(this);
            textView = (TextView) v.findViewById(R.id.textView);
            imageView = (ImageView) v.findViewById(R.id.imageView);
            relativeLayout = (RelativeLayout) v.findViewById(R.id.relativeLayout);

        }

        public void setData(DataModel item) {
            this.item = item;

            textView.setText(item.text);
            imageView.setImageResource(item.drawable);
            relativeLayout.setBackgroundColor(Color.parseColor(item.color));

        }


        @Override
        public void onClick(View view) {
            if (mListener != null) {
                mListener.onItemClick(item);
            }
        }
    }

    @Override
    public RecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(mContext).inflate(R.layout.recycler_view_item, parent, false);

        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder Vholder, int position) {
        Vholder.setData(mValues.get(position));

    }

    @Override
    public int getItemCount() {

        return mValues.size();
    }

    public interface ItemListener {
        void onItemClick(DataModel item);
    }
}

Im obigen Code haben wir eine ItemListener-Schnittstelle definiert, die in der MainActivity.java-Klasse implementiert wird. Das XML-Layout für jedes RecyclerView-Element ist unten angegeben. recycler_view_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:card_view="https://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <android.support.v7.widget.CardView
        android:id="@+id/cardView"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        card_view:cardCornerRadius="0dp"
        card_view:cardElevation="@dimen/margin10"
        card_view:cardMaxElevation="@dimen/margin10"
        card_view:contentPadding="@dimen/margin10">


        <RelativeLayout
            android:id="@+id/relativeLayout"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:layout_gravity="center">

            <ImageView
                android:id="@+id/imageView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:tint="@android:color/white"
                android:padding="5dp" />


            <TextView
                android:id="@+id/textView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:textColor="@android:color/white"
                android:layout_below="@+id/imageView" />


        </RelativeLayout>

    </android.support.v7.widget.CardView>

</LinearLayout>

Die AutoFitGridLayoutManager.java-Klasse ist unten angegeben:

package com.journaldev.recyclerviewgridlayoutmanager;

import android.content.Context;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;

public class AutoFitGridLayoutManager extends GridLayoutManager {

    private int columnWidth;
    private boolean columnWidthChanged = true;

    public AutoFitGridLayoutManager(Context context, int columnWidth) {
        super(context, 1);

        setColumnWidth(columnWidth);
    }

    public void setColumnWidth(int newColumnWidth) {
        if (newColumnWidth > 0 && newColumnWidth != columnWidth) {
            columnWidth = newColumnWidth;
            columnWidthChanged = true;
        }
    }

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        if (columnWidthChanged && columnWidth > 0) {
            int totalSpace;
            if (getOrientation() == VERTICAL) {
                totalSpace = getWidth() - getPaddingRight() - getPaddingLeft();
            } else {
                totalSpace = getHeight() - getPaddingTop() - getPaddingBottom();
            }
            int spanCount = Math.max(1, totalSpace / columnWidth);
            setSpanCount(spanCount);
            columnWidthChanged = false;
        }
        super.onLayoutChildren(recycler, state);
    }
}

Die Spannenzahl wird dynamisch berechnet, basierend auf der Ausrichtung, der verfügbaren Breite und Höhe. Die `MainActivity.java` Klasse sieht wie folgt aus:

package com.journaldev.recyclerviewgridlayoutmanager;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.Toast;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity implements RecyclerViewAdapter.ItemListener {

    RecyclerView recyclerView;
    ArrayList arrayList;

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


        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        arrayList = new ArrayList();
        arrayList.add(new DataModel("Item 1", R.drawable.battle, "#09A9FF"));
        arrayList.add(new DataModel("Item 2", R.drawable.beer, "#3E51B1"));
        arrayList.add(new DataModel("Item 3", R.drawable.ferrari, "#673BB7"));
        arrayList.add(new DataModel("Item 4", R.drawable.jetpack_joyride, "#4BAA50"));
        arrayList.add(new DataModel("Item 5", R.drawable.three_d, "#F94336"));
        arrayList.add(new DataModel("Item 6", R.drawable.terraria, "#0A9B88"));

        RecyclerViewAdapter adapter = new RecyclerViewAdapter(this, arrayList, this);
        recyclerView.setAdapter(adapter);


        /**
         AutoFitGridLayoutManager that auto fits the cells by the column width defined.
         **/

        /*AutoFitGridLayoutManager layoutManager = new AutoFitGridLayoutManager(this, 500);
        recyclerView.setLayoutManager(layoutManager);*/


        /**
         Simple GridLayoutManager that spans two columns
         **/
        GridLayoutManager manager = new GridLayoutManager(this, 2, GridLayoutManager.VERTICAL, false);
        recyclerView.setLayoutManager(manager);
    }

    @Override
    public void onItemClick(DataModel item) {

        Toast.makeText(getApplicationContext(), item.text + " is clicked", Toast.LENGTH_SHORT).show();

    }
}

  1. Die obige Klasse implementiert das Interface `RecyclerViewAdapter.ItemListener` und überschreibt die Methode `onItemClick`, die in der Adapterklasse definiert ist. Dadurch haben wir den RecyclerView-Click-Listener innerhalb unserer Aktivität implementiert, anstatt in der Adapterklasse (ähnlich wie der standardmäßige onItemClickListener, der für eine ListView definiert ist)
  2. A DataModel class holds the details for each RecyclerView item
  3. Der LayoutManager des RecyclerView kann entweder durch Instanziierung der Klasse `AutoFitGridLayoutManager` mit der Spaltenbreite von 500 oder durch Aufruf des Objekts der Klasse `GridLayoutManager` und Festlegen der Anzahl von Spalten als 2 definiert werden

Lassen Sie uns die Ausgabe der Anwendung mit dem standardmäßigen GridLayoutManager-Code sehen. Wie Sie sehen können, hat jede Zeile zwei Elemente, die die Spaltenbreite in beiden Ausrichtungen einnehmen. Kommentieren Sie nun den Code für den einfachen GridLayoutManager aus und führen Sie den Code für AutoFitGridLayoutManager aus.

AutoFitGridLayoutManager layoutManager = new AutoFitGridLayoutManager(this, 500);
recyclerView.setLayoutManager(layoutManager);

Die Ausgabe der Anwendung in Aktion ist unten angegeben. Wie Sie in der obigen Ausgabe sehen können, hat jede Zeile beim Wechsel in den Querformatmodus drei Elemente, wodurch die Elemente dynamisch an die Spaltenbreite angepasst werden. Damit endet dieses Tutorial. Sie können das endgültige Android GridLayoutManager-Projekt über den unten angegebenen Link herunterladen.

Android GridLayoutManager-Projekt herunterladen

Source:
https://www.digitalocean.com/community/tutorials/android-gridlayoutmanager-example