GridLayoutManager Android هو تنفيذ “RecyclerView.LayoutManager” لترتيب العناصر في شبكة. في هذا البرنامج التعليمي ، سنقوم بإنشاء تطبيق يعرض “CardViews” داخل “RecyclerView” على شكل “GridLayout”. بالإضافة إلى ذلك ، سنقوم بتنفيذ واجهة تجعل عنصر انقر فوقه في “RecyclerView” مشابهًا لـ “ListView” “itemClickListener”.
GridLayoutManager Android
لقد نفذنا “RecyclerView” باستخدام “LinearLayoutManager” هنا. الآن دعنا نستخدم “GridLayoutManager” لترتيب “RecyclerView” كشبكة. يلي بناء الجملة لـ “GridLayoutManager”.
GridLayoutManager (Context context,
int spanCount,
int orientation,
boolean reverseLayout)
إذا تم تعيين “reverseLayout” على القيمة الصحيحة ، فسيتم تخطيط العناصر من النهاية إلى البداية. لتحديد حجم العنصر لكل عنصر ، نقوم باستدعاء الطريقة “setSpanSizeLookup” على “GridLayoutManager”. دعنا ننفذ “RecyclerView” باستخدام “GridLayoutManager” في مشروع جديد في “Android Studio”.
مثال على هيكل مشروع Android GridLayoutManager
يتكون المشروع من نشاط واحد:
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
أدناه: 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;
}
}
تحمل فئة DataModel النص وأيقونة قابلة للرسم ولون خلفية كل خلية عنصر. تظهر فئة 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);
}
}
عدد العناصر يتم حسابه ديناميكياً استناداً إلى الاتجاه والعرض والارتفاع المتاح. الفئة MainActivity.java معطاة أدناه:
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();
}
}
- تنفيذ الفئة المذكورة أعلاه الواجهة RecyclerViewAdapter.ItemListener وتجاوز الطريقة onItemClick المعرفة في فئة المحول. من خلال ذلك، قمنا بتنفيذ مستمع انقر المختار في RecyclerView داخل نشاطنا بدلاً من فئة المحول (مماثل للاستماع القياسي المعرف ل ListView)
- A DataModel class holds the details for each RecyclerView item
- يمكن تحديد مدير التخطيط لـ RecyclerView بإما بإنشاء فئة AutoFitGridLayoutManager مع عرض العمود المضبوط على 500 أو عن طريق استدعاء كائن فئة GridLayoutManager وتحديد عدد الأعمدة على 2
دعنا نرى إخراج التطبيق مع رمز GridLayoutManager القياسي. كما ترى، كل صف يحتوي على عنصرين يمتدان عرض العمود في كلا الاتجاهين. الآن قم بتعليق الكود لمدير التخطيط البسيط GridLayoutManager وتشغيل الكود لـ AutoFitGridLayoutManager
AutoFitGridLayoutManager layoutManager = new AutoFitGridLayoutManager(this, 500);
recyclerView.setLayoutManager(layoutManager);
تم تقديم نتائج التطبيق في الأسفل. كما يمكنك رؤية في النتيجة أعلاه، عندما يتغير الاتجاه إلى الأفقي، يحتوي كل صف على ثلاثة عناصر، مما يعني تحجيم العناصر بشكل ديناميكي لتناسب عرض العمود تلقائيًا. بهذا نكون قد وصلنا إلى نهاية هذا البرنامج التعليمي. يمكنك تنزيل مشروع GridLayoutManager النهائي لنظام التشغيل Android من الرابط الموجود أدناه.
Source:
https://www.digitalocean.com/community/tutorials/android-gridlayoutmanager-example