Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> Android

RecyclerView में GridLayoutManager का उपयोग कैसे करें?

RecyclerView के साथ GridLayoutManager - पूर्ण गाइड

GridLayoutManager आइटम को एक ग्रिड में व्यवस्थित करता है (जैसे फोटो गैलरी, उत्पाद सूचियां)। यह स्पैन काउंट, स्पैन आकार लुकअप, और RecyclerView एनिमेशन का समर्थन करता है।

निर्भरताएं

dependencies {
    implementation "androidx.recyclerview:recyclerview:1.3.2"
    implementation "com.google.android.material:material:1.11.0"
}

बुनियादी सेटअप

RecyclerView rv = findViewById(R.id.recyclerView);
int spanCount = 2; // कॉलम
GridLayoutManager glm = new GridLayoutManager(this, spanCount);
rv.setLayoutManager(glm);
rv.setAdapter(new MyAdapter(dataList));

उन्नत: डायनामिक स्पैन आकार (हेडर, फुल-विड्थ आइटम)

glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
    @Override
    public int getSpanSize(int position) {
        // स्थिति 0 = हेडर (पूर्ण चौड़ाई)
        return (position == 0) ? spanCount : 1;
    }
});

आइटम डेकोरेशन - ग्रिड स्पेसिंग

public class GridSpacingDecoration extends RecyclerView.ItemDecoration {
    private final int spanCount;
    private final int spacing;
    private final boolean includeEdge;

    public GridSpacingDecoration(int spanCount, int spacing, boolean includeEdge) {
        this.spanCount = spanCount;
        this.spacing = spacing;
        this.includeEdge = includeEdge;
    }

    @Override
    public void getItemOffsets(@NonNull Rect outRect, @NonNull View view,
                               @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
        int position = parent.getChildAdapterPosition(view);
        int column = position % spanCount;

        if (includeEdge) {
            outRect.left = spacing - column * spacing / spanCount;
            outRect.right = (column + 1) * spacing / spanCount;
            if (position < spanCount) outRect.top = spacing;
            outRect.bottom = spacing;
        } else {
            outRect.left = column * spacing / spanCount;
            outRect.right = spacing - (column + 1) * spacing / spanCount;
            if (position >= spanCount) outRect.top = spacing;
            outRect.bottom = 0;
        }
    }
}

// उपयोग:
rv.addItemDecoration(new GridSpacingDecoration(2, 16, true));

पूर्ण उदाहरण: अनुकूली कॉलम (उपलब्ध चौड़ाई के आधार पर)

public class AdaptiveGridManager extends GridLayoutManager {
    private final int minItemWidth;

    public AdaptiveGridManager(Context context, int minItemWidth) {
        super(context, 1); // अस्थायी
        this.minItemWidth = minItemWidth;
    }

    @Override
    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
        if (getWidth() > 0 && getSpanCount() != calculateSpanCount()) {
            setSpanCount(calculateSpanCount());
            requestLayout();
        }
        super.onLayoutChildren(recycler, state);
    }

    private int calculateSpanCount() {
        return Math.max(1, getWidth() / minItemWidth);
    }
}

// उपयोग: new AdaptiveGridManager(this, 180) // न्यूनतम 180dp प्रति कॉलम

एडॉप्टर पैटर्न (ListAdapter + DiffUtil)

public class GridAdapter extends ListAdapter {
    public GridAdapter() { super(DIFF); }

    private static final DiffUtil.ItemCallback DIFF = new DiffUtil.ItemCallback() {
        @Override public boolean areItemsTheSame(@NonNull Item o, @NonNull Item n) { return o.id == n.id; }
        @Override public boolean areContentsTheSame(@NonNull Item o, @NonNull Item n) { return o.equals(n); }
    };

    @NonNull @Override
    public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_grid, parent, false);
        return new VH(v);
    }

    @Override
    public void onBindViewHolder(@NonNull VH h, int pos) { h.bind(getItem(pos)); }

    static class VH extends RecyclerView.ViewHolder {
        ImageView img; TextView title;
        VH(View v) { super(v); img = v.findViewById(R.id.iv); title = v.findViewById(R.id.tv); }
        void bind(Item i) { title.setText(i.title); img.setImageResource(i.imageRes); }
    }
}

XML लेआउट (item_grid.xml)

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView
    xmlns:android="https://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp"
    app:cardCornerRadius="12dp"
    app:cardElevation="4dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:padding="8dp">

        <ImageView
            android:id="@+id/iv"
            android:layout_width="match_parent"
            android:layout_height="120dp"
            android:scaleType="centerCrop"
            android:src="@drawable/placeholder" />

        <TextView
            android:id="@+id/tv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:gravity="center"
            android:textSize="16sp" />
    </LinearLayout>
</androidx.cardview.widget.CardView>

सर्वोत्तम अभ्यास

  • ListAdapter का उपयोग करें स्वचालित एनिमेटेड अपडेट के लिए।
  • ItemDecoration के साथ स्पेसिंग सेट करें, आइटम लेआउट मार्जिन नहीं (स्क्रॉल जैंक से बचाता है)।
  • अनुकूली स्पैन के लिए SpanSizeLookup या कस्टम GridLayoutManager का उपयोग करें।
  • बड़ी इमेज के लिए Glide/Coil का उपयोग करें जिसमें override(width, height) हो ताकि OOM से बचा जा सके।
  • नेस्टेड स्क्रॉलिंग अक्षम करें यदि ग्रिड स्क्रॉलिंग कंटेनर के अंदर है: rv.setNestedScrollingEnabled(false)।

मूल उदाहरण की समीक्षा

मूल कोड लिगेसी सपोर्ट लाइब्रेरी, हार्डकोडेड 2-कॉलम ग्रिड, मैन्युअल notifyDataSetChanged, और एक अधूरे एडॉप्टर का उपयोग करता था। ऊपर दिया गया समाधान आधुनिक androidx, अनुकूली कॉलम, उचित स्पेसिंग, और DiffUtil-आधारित एडॉप्टर का उपयोग करता है।

  1. Android में Snackbar का उपयोग कैसे करें? Android में Snackbar का उपयोग कैसे करें?

    परिचय Snackbar Material Design का एक घटक है जो स्क्रीन के निचले भाग में एक संक्षिप्त संदेश दिखाता है। यह उदाहरण Snackbar के बुनियादी उपयोग और अनुकूलन को दर्शाता है। चरण 1: नया प्रोजेक्ट बनाएं Android Studio में नया प्रोजेक्ट बनाएं। चरण 2: लेआउट XML res/layout/activity_main.xml: <?xml version=1.

  1. एंड्रॉइड में NestedScrollView के अंदर RecyclerView का उपयोग कैसे करें एंड्रॉइड में NestedScrollView के अंदर RecyclerView का उपयोग कैसे करें

    NestedScrollView में RecyclerView को सही तरीके से एम्बेड करना NestedScrollView के अंदर RecyclerView रखना एक सामान्य पैटर्न है (जैसे: प्रोफाइल स्क्रीन जिसमें हेडर + सूची हो)। मुख्य चुनौती स्क्रॉल संघर्ष और RecyclerView की ऊंचाई मापन है। आधुनिक एंड्रॉइड में setNestedScrollingEnabled(false) या nestedSc

  1. Android में NavigationView (नेविगेशन ड्रॉअर) कैसे उपयोग करें? Android में NavigationView (नेविगेशन ड्रॉअर) कैसे उपयोग करें?

    परिचय NavigationView मटेरियल डिज़ाइन का साइड नेविगेशन ड्रॉअर (हैमबर्गर मेनू) है। यह DrawerLayout के अंदर होता है और मेनू आइटम्स, हेडर, और नेविगेशन हैंडलिंग प्रदान करता है। यह ट्यूटोरियल Navigation Components के साथ आधुनिक सेटअप दिखाता है। आवश्यक चरण चरण 1: नया प्रोजेक्ट बनाएं Android Studio में Fi