Voorbeeld van Android GridLayoutManager

Android GridLayoutManager is de implementatie van RecyclerView.LayoutManager om items in een raster te plaatsen. In deze tutorial zullen we een toepassing maken die CardViews weergeeft in een RecyclerView in de vorm van een GridLayout. Ook zullen we een interface implementeren die ervoor zorgt dat het klikken op een RecyclerView-item vergelijkbaar is met een ListView itemClickListener.

Android GridLayoutManager

We hebben al een RecyclerView geïmplementeerd met een LinearLayoutManager hier. Laten we nu een GridLayoutManager gebruiken om de RecyclerView als een raster in te delen. Hier is de constructor voor een GridLayoutManager.

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

reverseLayout als ingesteld op waar, dan worden items vanaf het einde naar het begin ingedeeld. Om de spanwijdte voor elk item in te stellen, roepen we de methode setSpanSizeLookup aan op de GridLayoutManager. Laten we RecyclerView implementeren met een GridLayoutManager in een nieuw Android Studio-project.

Voorbeeld Projectstructuur van Android GridLayoutManager

Het project bestaat uit een enkele activiteit: MainActivity.java, een adapterklasse: RecyclerViewAdapter.java, een klasse DataModel.java en een aangepaste GridLayoutManager-klasse AutoFitGridLayoutManager.java. De XML-indeling van de klasse MainActivity.java is gedefinieerd in het bestand activity_main.xml 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>

Let op: vergeet niet de volgende afhankelijkheden toe te voegen voor Material Design widgets en de CardView in het build.gradle-bestand.

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

De klasse DataModel.java is hieronder gegeven: 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;
    }
}

De DataModel-klasse bevat de tekst, het pictogram en de achtergrondkleur van elk itemcel. De klasse RecyclerViewAdapter.java is hieronder gegeven:

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

In de bovenstaande code hebben we een ItemListener-interface gedefinieerd die zal worden geïmplementeerd in de klasse MainActivity.java. De XML-indeling voor elk RecyclerView-item is hieronder gegeven. 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>

De klasse AutoFitGridLayoutManager.java is hieronder gegeven:

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

De spanwijdte wordt dynamisch berekend op basis van de oriëntatie, breedte en hoogte die beschikbaar is. De MainActivity.java-klasse wordt hieronder weergegeven:

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. De bovenstaande klasse implementeert de interface RecyclerViewAdapter.ItemListener en overschrijft de methode onItemClick die is gedefinieerd in de adapterklasse. Hierdoor hebben we de RecyclerView Click Listener geïmplementeerd binnen onze Activity in plaats van de Adapterklasse (vergelijkbaar met de standaard onItemClickListener gedefinieerd voor een ListView)
  2. A DataModel class holds the details for each RecyclerView item
  3. De LayoutManager van de RecyclerView kan worden gedefinieerd door ofwel de klasse AutoFitGridLayoutManager te instantiëren met de kolombreedte ingesteld op 500, of door het object van de klasse GridLayoutManager aan te roepen en het aantal kolommen in te stellen op 2

Laten we de uitvoer van de toepassing bekijken met de standaard GridLayoutManager-code. Zoals je kunt zien, heeft elke rij twee items die de kolombreedte beslaan in beide oriëntaties. Nu, commentarieer de code voor eenvoudige GridLayoutManager uit en voer de code uit voor AutoFitGridLayoutManager

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

De uitvoer van de applicatie in actie wordt hieronder gegeven. Zoals je kunt zien in de bovenstaande uitvoer, wanneer de oriëntatie verandert naar landschap, heeft elke rij drie items, waardoor de items dynamisch worden aangepast om automatisch in de kolombreedte te passen. Dit brengt een einde aan deze tutorial. Je kunt het uiteindelijke Android GridLayoutManager-project downloaden vanaf de onderstaande link.

Download Android GridLayoutManager Project

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