דוגמה ל-GridLayoutManager ב-Android

מנהל הפריסה של Android GridLayoutManager הוא המימוש של RecyclerView.LayoutManager להנית פריטים ברשת. במדריך זה, ניצור אפליקציה שמציגה CardViews בתוך RecyclerView בצורת GridLayout. כמו כן, נממש ממשק שמאפשר ללחיצה על פריט ב-RecyclerView להיות דומה ל־ListView itemClickListener.

מנהל רשת של Android GridLayoutManager

ביצענו RecyclerView באמצעות LinearLayoutManager כאן. עכשיו נשתמש ב-GridLayoutManager כדי לפרוס את RecyclerView כרשת. הנה הבנאי עבור GridLayoutManager.

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

reverseLayout אם הוגדר true אז פריטים יופרסמו מסוף להתחלה. כדי להגדיר את גודל הרווח של כל פריט, אנו קוראים לשיטה setSpanSizeLookup על GridLayoutManager. בואו נממש RecyclerView באמצעות GridLayoutManager בפרויקט חדש ב-Android Studio.

דוגמה למבנה פרויקט GridLayoutManager של Android


הפרויקט מכיל פעילות אחת בלבד: MainActivity.java, מחלקת מתאם: RecyclerViewAdapter.java, מחלקת DataModel.java, ומחלקת GridLayoutManager מותאמת אישית בשם AutoFitGridLayoutManager.java. פריסת ה-xml של מחלקת MainActivity.java מוגדרת בקובץ activity_main.xml כ

<?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>

הערה: אל תשכח להוסיף את התלות הבאות ל-עיצוב החומר ולווידג'טים של CardView בקובץ ה- build.gradle.

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

מחלקת DataModel.java מוצגת למטה:
"`java
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;
    }
}

"`
מחלקת RecyclerViewAdapter.java מוצגת למטה:

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

בקוד לעיל הגדרנו את ממשק ה-ItemListener שיתואר במחלקת MainActivity.java. פריסת ה-xml לכל פריט ב-RecyclerView מוצגת למטה. 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>

מחלקת AutoFitGridLayoutManager.java מוצגת למטה:

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

ספירת ה-span מחושבת דינמית על פי האוריינטציה, הרוחב והגובה הזמינים. ה-MainActivity.java class ניתן להלן:

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. המחלקה למעלה מיישמת את הממשק RecyclerViewAdapter.ItemListener ומפרטת מחדש את השיטה onItemClick המוגדרת במחלקת האדפטור. על ידי כך, ביצענו מימוש של מאזין ללחיצה על RecyclerView בתוך הפעילות שלנו במקום בתוך מחלקת האדפטור (דומה ל־onItemClickListener התקני שמוגדר עבור ListView)
  2. A DataModel class holds the details for each RecyclerView item
  3. מנהל העימוד של RecyclerView ניתן להגדיר על ידי יצירת מופע של מחלקת AutoFitGridLayoutManager עם רוחב עמודה שמוגדר כ־500 או על ידי קריאה לאובייקט מחלקת GridLayoutManager והגדרת מספר העמודות כ-2

בואו נסתכל על פלט היישום עם קוד GridLayoutManager סטנדרטי. כפי שניתן לראות, כל שורה מכילה שני פריטים שמתאימים לרוחב העמודה בשני האוריינטציות. כעת נא להעריך את הקוד עבור GridLayoutManager פשוט ולהפעיל את הקוד עבור AutoFitGridLayoutManager.

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

הפלט של היישום בפעולה מוצג למטה. כפי שניתן לראות בפלט הנ"ל, כאשר האוריינטציה משתנה לנוף, כל שורה מכילה שלושה פריטים, וכתוצאה מכך גודל הפריטים מתאים דינמית לרוחב העמודה. זה מסיים את המדריך הזה. ניתן להוריד את פרויקט GridLayoutManager של אנדרואיד הסופי מהקישור הבא.

הורד פרויקט GridLayoutManager של אנדרואיד

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