Contoh grid Android sederhana menggunakan RecyclerView dengan GridLayoutManager (seperti GridView lama)

227

Saya tahu itu RecyclerViewtelah menggantikan fungsi yang lama ListViewdanGridView . Saya mencari contoh yang sangat mendasar yang menunjukkan pengaturan grid minimal menggunakan RecyclerView. Saya tidak mencari penjelasan gaya tutorial yang panjang, hanya contoh minimal. Saya membayangkan grid paling sederhana yang meniru GridView lama akan terdiri dari beberapa fitur berikut:

  • beberapa sel per baris
  • tampilan tunggal di setiap sel
  • menanggapi acara klik
Suragch
sumber

Jawaban:

556

Jawaban singkat

Bagi mereka yang sudah terbiasa dengan pengaturan RecyclerViewuntuk membuat daftar , kabar baiknya adalah membuat kotak sebagian besar sama. Anda hanya menggunakan GridLayoutManagerbukan sebagai LinearLayoutManagerketika Anda mengatur RecyclerView.

recyclerView.setLayoutManager(new GridLayoutManager(this, numberOfColumns));

Jika Anda membutuhkan lebih banyak bantuan dari itu, lihat contoh berikut.

Contoh lengkap

Berikut ini adalah contoh minimal yang akan terlihat seperti gambar di bawah ini.

masukkan deskripsi gambar di sini

Mulailah dengan aktivitas kosong. Anda akan melakukan tugas-tugas berikut untuk menambahkan RecyclerViewkisi. Yang perlu Anda lakukan adalah menyalin dan menempelkan kode di setiap bagian. Nanti Anda dapat menyesuaikannya agar sesuai dengan kebutuhan Anda.

  • Tambahkan dependensi ke gradle
  • Tambahkan file tata letak xml untuk aktivitas dan untuk sel kisi
  • Buat adaptor RecyclerView
  • Inisialisasi RecyclerView dalam aktivitas Anda

Perbarui dependensi Gradle

Pastikan dependensi berikut ada di gradle.buildfile aplikasi Anda :

compile 'com.android.support:appcompat-v7:27.1.1'
compile 'com.android.support:recyclerview-v7:27.1.1'

Anda dapat memperbarui nomor versi ke apa pun yang terbaru .

Buat tata letak aktivitas

Tambahkan RecyclerViewtata letak ke xml Anda.

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rvNumbers"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

Buat tata letak sel jaringan

Setiap sel di RecyclerViewgrid kami hanya akan memiliki satu TextView. Buat file sumber daya tata letak baru.

recyclerview_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:padding="5dp"
    android:layout_width="50dp"
    android:layout_height="50dp">

        <TextView
            android:id="@+id/info_text"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center"
            android:background="@color/colorAccent"/>

</LinearLayout>

Buat adaptor

The RecyclerViewperlu adaptor untuk mengisi pandangan dalam setiap sel dengan data Anda. Buat file java baru.

MyRecyclerViewAdapter.java

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {

    private String[] mData;
    private LayoutInflater mInflater;
    private ItemClickListener mClickListener;

    // data is passed into the constructor
    MyRecyclerViewAdapter(Context context, String[] data) {
        this.mInflater = LayoutInflater.from(context);
        this.mData = data;
    }

    // inflates the cell layout from xml when needed
    @Override
    @NonNull 
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.recyclerview_item, parent, false);
        return new ViewHolder(view);
    }

    // binds the data to the TextView in each cell
    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
        holder.myTextView.setText(mData[position]);
    }

    // total number of cells
    @Override
    public int getItemCount() {
        return mData.length;
    }


    // stores and recycles views as they are scrolled off screen
    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        TextView myTextView;

        ViewHolder(View itemView) {
            super(itemView);
            myTextView = itemView.findViewById(R.id.info_text);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            if (mClickListener != null) mClickListener.onItemClick(view, getAdapterPosition());
        }
    }

    // convenience method for getting data at click position
    String getItem(int id) {
        return mData[id];
    }

    // allows clicks events to be caught
    void setClickListener(ItemClickListener itemClickListener) {
        this.mClickListener = itemClickListener;
    }

    // parent activity will implement this method to respond to click events
    public interface ItemClickListener {
        void onItemClick(View view, int position);
    }
}

Catatan

  • Meskipun tidak sepenuhnya diperlukan, saya menyertakan fungsionalitas untuk mendengarkan acara klik pada sel. Ini tersedia di yang lama GridViewdan merupakan kebutuhan bersama. Anda dapat menghapus kode ini jika Anda tidak membutuhkannya.

Inisialisasi RecyclerView dalam Aktivitas

Tambahkan kode berikut ke aktivitas utama Anda.

MainActivity.java

public class MainActivity extends AppCompatActivity implements MyRecyclerViewAdapter.ItemClickListener {

    MyRecyclerViewAdapter adapter;

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

        // data to populate the RecyclerView with
        String[] data = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48"};

        // set up the RecyclerView
        RecyclerView recyclerView = findViewById(R.id.rvNumbers);
        int numberOfColumns = 6;
        recyclerView.setLayoutManager(new GridLayoutManager(this, numberOfColumns));
        adapter = new MyRecyclerViewAdapter(this, data);
        adapter.setClickListener(this);
        recyclerView.setAdapter(adapter);
    }

    @Override
    public void onItemClick(View view, int position) {
        Log.i("TAG", "You clicked number " + adapter.getItem(position) + ", which is at cell position " + position);
    }
}

Catatan

  • Perhatikan bahwa aktivitas mengimplementasikan apa ItemClickListeneryang kami tetapkan dalam adaptor kami. Ini memungkinkan kami untuk menangani acara klik sel di onItemClick.

Jadi

Itu dia. Anda harus dapat menjalankan proyek Anda sekarang dan mendapatkan sesuatu yang mirip dengan gambar di atas.

Sedang terjadi

Sudut membulat

Kolom pas otomatis

Pelajaran lanjutan

Suragch
sumber
2
@ MarianPaździoch, Ya, saya baru saja menjadikan ini sebagai contoh minimal. Pasti bisa menggunakan beberapa pekerjaan kecantikan. Saya akan mencoba memperbarui jawaban ini di masa mendatang.
Suragch
1
Saya masuk hanya untuk menunjukkan bahwa orang-orang seperti Anda telah menjaga portal ini tetap hidup dan menendang. Saya terjebak di sini selama dua hari sebelum melihat solusi ini. terima kasih banyak
VarunJoshi129
1
@androiddeveloper, Item grid diletakkan dari kiri ke kanan, atas ke bawah. Scrolling adalah vertikal ketika ada lebih banyak item daripada yang bisa muat di layar.
Suragch
13
Pembaca masa depan, biarkan saya menghemat waktu Anda, kuncinya adalahrecyclerView.setLayoutManager(new GridLayoutManager(this, numberOfColumns));
daka
1
@ Daka, poin bagus. Saya mengedit jawaban saya untuk memasukkan ini di awal.
Suragch
7

Walaupun saya suka dan menghargai jawaban Suragch , saya ingin meninggalkan catatan karena saya menemukan bahwa pengkodean Adapter ( MyRecyclerViewAdapter) untuk mendefinisikan dan mengekspos metode Pendengar onItemClickbukan cara terbaik untuk melakukannya, karena tidak menggunakan enkapsulasi kelas benar. Jadi saran saya adalah membiarkan Adapter menangani operasi Listening semata-mata (itu tujuannya!) Dan memisahkan yang dari Kegiatan yang menggunakan Adapter (MainActivity ). Jadi ini adalah bagaimana saya akan mengatur kelas Adapter:

MyRecyclerViewAdapter.java

public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> {

    private String[] mData = new String[0];
    private LayoutInflater mInflater;

    // Data is passed into the constructor
    public MyRecyclerViewAdapter(Context context, String[] data) {
        this.mInflater = LayoutInflater.from(context);
        this.mData = data;
    }

    // Inflates the cell layout from xml when needed
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = mInflater.inflate(R.layout.recyclerview_item, parent, false);
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    // Binds the data to the textview in each cell
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        String animal = mData[position];
        holder.myTextView.setText(animal);
    }

    // Total number of cells
    @Override
    public int getItemCount() {
        return mData.length;
    }

    // Stores and recycles views as they are scrolled off screen
    public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
        public TextView myTextView;

        public ViewHolder(View itemView) {
            super(itemView);
            myTextView = (TextView) itemView.findViewById(R.id.info_text);
            itemView.setOnClickListener(this);
        }

        @Override
        public void onClick(View view) {
            onItemClick(view, getAdapterPosition());
        }
    }

    // Convenience method for getting data at click position
    public String getItem(int id) {
        return mData[id];
    }

    // Method that executes your code for the action received
    public void onItemClick(View view, int position) {
        Log.i("TAG", "You clicked number " + getItem(position).toString() + ", which is at cell position " + position);
    }
}

Harap perhatikan onItemClickmetode yang sekarang didefinisikan dalam MyRecyclerViewAdapteritu adalah tempat di mana Anda ingin memberi kode tugas Anda untuk peristiwa / tindakan yang diterima.

Hanya ada sedikit perubahan yang harus dilakukan untuk menyelesaikan transformasi ini: Kegiatan tidak perlu diimplementasikan MyRecyclerViewAdapter.ItemClickListenerlagi, karena sekarang hal itu dilakukan sepenuhnya oleh Adaptor . Ini akan menjadi modifikasi terakhir:

MainActivity.java

public class MainActivity extends AppCompatActivity {

    MyRecyclerViewAdapter adapter;

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

        // data to populate the RecyclerView with
        String[] data = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44", "45", "46", "47", "48"};

        // set up the RecyclerView
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rvNumbers);
        int numberOfColumns = 6;
        recyclerView.setLayoutManager(new GridLayoutManager(this, numberOfColumns));
        adapter = new MyRecyclerViewAdapter(this, data);
        adapter.setClickListener(this);
        recyclerView.setAdapter(adapter);
    }
}
jonypera
sumber
3
Bagaimana jika aktivitas tersebut perlu mendengarkan acara klik? mis. meneruskan data ke presenter, melakukan beberapa logika berdasarkan item yang diklik, pelacakan, dll.
Ahmad Fadli
Saya setuju bahwa Adaptor harus menangani acara klik, karena memiliki item dengan data di dalamnya. @AhmadFadli jika Anda perlu melakukan beberapa pekerjaan di host adaptor (Fragmen atau Aktivitas), Anda harus membuat antarmuka panggilan balik dengan metode yang Anda butuhkan. Tuan rumah Anda mengimplementasikan antarmuka ini. Dan kemudian Anda mengirimkan instance host Anda ke konstruktor Adaptor. Memiliki instance dari host Anda dapat memanggil metode itu ketika Anda membutuhkannya dari Adapter Anda. Dan host Anda, kami mendapat panggilan balik. Ini sering digunakan ketika Anda perlu bekerja dengan ActionMode. Ketika Anda rindu Klik untuk memilih item dan menggunakan tombol ActionBar.
Kirill Karmazin
Saya tidak setuju dan berpikir bahwa acara klik harus diproses di hosting Activity. Karena hanya itu pendengar klik dapat mengetahui tentang Activitypandangan dan lainnya Fragments, Activities, dll Adaptor hanya dapat mengirim klik acara untuk tingkat atas. Seharusnya memiliki antarmuka ItemClickListener dengan begitu banyak acara, karena banyak tampilan peristiwa adaptor dapat menghasilkan. Solusi ini ditulis lebih awal: stackoverflow.com/a/40563598/2914140 .
CoolMind
4

Yo Harus Menetapkan layoutmanager recyclerview Anda ke Mode Gridlayout, Untuk Lakukan Ini Ubah saja kode Anda ketika Anda Ingin Mengatur RecyclerView LayoutManager Anda:

Catatan: ganti Jumlah Kolom Anda yang Anda inginkan dengan ### BANTUAN ###

   recyclerView.setLayoutManager(new GridLayoutManager(getActivity(),###HELP###));
MR Coder
sumber