web-dev-qa-db-de.com

Einfaches Android Grid-Beispiel mit RecyclerView und GridLayoutManager (wie das alte GridView)

Ich weiß, dass RecyclerView die Funktionalität der alten ListView und GridView ersetzt hat. Ich suche ein sehr einfaches Beispiel, das einen minimalen Rasteraufbau mit RecyclerView zeigt. Ich suche keine langen Erklärungen zum Tutorial-Stil, nur ein minimales Beispiel. Ich stelle mir das einfachste Gitter vor, das das alte GridView nachahmt, und das folgende Funktionen umfasst:

  • mehrere Zellen pro Zeile
  • einzelne Ansicht in jeder Zelle
  • reagiert auf Klickereignisse
166
Suragch

Kurze Antwort

Für diejenigen, die bereits mit dem Erstellen einer RecyclerView vertraut sind , um eine Liste zu erstellen , ist die gute Nachricht, dass das Erstellen eines Rasters weitgehend dieselbe ist. Sie verwenden nur ein GridLayoutManager anstelle eines LinearLayoutManager, wenn Sie das RecyclerView einrichten.

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

Wenn Sie mehr Hilfe benötigen, sehen Sie sich das folgende Beispiel an.

Vollständiges Beispiel

Das folgende Beispiel ist minimal und sieht aus wie das folgende Bild.

enter image description here

Beginnen Sie mit einer leeren Aktivität. Sie führen die folgenden Aufgaben aus, um das Raster RecyclerView hinzuzufügen. Alles, was Sie tun müssen, ist, den Code in jeden Abschnitt zu kopieren und einzufügen. Später können Sie es an Ihre Bedürfnisse anpassen.

  • Abhängigkeiten zu gradle hinzufügen
  • Fügen Sie die XML-Layoutdateien für die Aktivität und die Rasterzelle hinzu
  • Stellen Sie den RecyclerView-Adapter her
  • Initialisieren Sie den RecyclerView in Ihrer Aktivität

Aktualisieren Sie die Gradle-Abhängigkeiten

Stellen Sie sicher, dass die folgenden Abhängigkeiten in Ihrer app gradle.build -Datei enthalten sind:

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

Sie können die Versionsnummern auf die jeweils aktuellste aktualisieren .

Aktivitätslayout erstellen

Fügen Sie das RecyclerView zu Ihrem XML-Layout hinzu.

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>

Rasterzellenlayout erstellen

Jede Zelle in unserem RecyclerView Gitter wird nur eine TextView haben. Erstellen Sie eine neue Layoutressourcendatei.

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>

Erstellen Sie den Adapter

Das RecyclerView benötigt einen Adapter, um die Ansichten in jeder Zelle mit Ihren Daten zu füllen. Erstellen Sie eine neue Java Datei.

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

Anmerkungen

  • Obwohl dies nicht unbedingt erforderlich ist, habe ich die Funktionalität zum Abhören von Klickereignissen in den Zellen hinzugefügt. Dies war im alten GridView verfügbar und ist ein allgemeiner Bedarf. Sie können diesen Code entfernen, wenn Sie ihn nicht benötigen.

RecyclerView in Aktivität initialisieren

Fügen Sie Ihrer Hauptaktivität den folgenden Code hinzu.

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

Anmerkungen

  • Beachten Sie, dass die Aktivität das ItemClickListener implementiert, das wir in unserem Adapter definiert haben. Auf diese Weise können wir Zellklickereignisse in onItemClick verarbeiten.

Fertig

Das ist es. Sie sollten jetzt in der Lage sein, Ihr Projekt auszuführen und ein ähnliches Bild wie oben zu erhalten.

Weiter geht's

Abgerundete Ecken

Automatisch passende Spalten

Weitere Studie

420
Suragch

Obwohl ich die Antwort von Suragch mag und schätze, möchte ich eine Notiz hinterlassen, weil ich Es wurde festgestellt, dass die Codierung des Adapters (MyRecyclerViewAdapter) zum Definieren und Anzeigen der Listener-Methode onItemClick nicht die beste Methode ist Es liegt daran, dass die Klassenkapselung nicht korrekt verwendet wird. Mein Vorschlag ist also, den Adapter ausschließlich die Listening-Operationen ausführen zu lassen (das ist sein Zweck!) Und diese von der Aktivität zu trennen, die den Adapter (MainActivity). So würde ich die Adapter-Klasse einstellen:

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

Bitte beachten Sie die onItemClick -Methode, die jetzt in MyRecyclerViewAdapter definiert ist. Dies ist der Ort, an dem Sie Ihre Aufgaben für das empfangene Ereignis/die empfangene Aktion codieren möchten.

Es ist nur eine kleine Änderung erforderlich, um diese Transformation abzuschließen: Die Aktivität muss MyRecyclerViewAdapter.ItemClickListener nicht mehr implementieren, da das erledigt jetzt komplett der Adapter . Dies wäre dann die letzte Änderung:

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

Quelle der mittleren Richtlinie

GitHub repo

Fügen Sie die RecyclerView-Abhängigkeit in build.gradle hinzu

compile 'com.Android.support:recyclerview-v7:25.1.1'

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:id="@+id/activity_main"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    >

    <!--TODO(2): RecyclerView inside FrameLayout-->

    <Android.support.v7.widget.RecyclerView
        Android:id="@+id/rvStudents"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:scrollbars="none"
        >
    </Android.support.v7.widget.RecyclerView>

    <!--TODO(3): Create one layout resource with item_student.xml name-->

</FrameLayout>

item_student.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:orientation="vertical" Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:background="#d2d2d2"
    Android:id="@+id/llItemStudents"
    Android:layout_margin="8dp"
    >

    <!--TODO(4): Remember to change the height of LinearLayout to wrap_content and also add its ID-->

    <!--TODO(5): Add two TextView which will display student name and mobile number respectively-->

    <TextView
        Android:id="@+id/tvStudentName"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_margin="8dp"
        Android:padding="8dp"
        Android:textSize="25sp"
        Android:textStyle="bold"
        Android:textColor="@color/colorPrimary"
        />

    <TextView
        Android:id="@+id/tvMobileNumber"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_margin="8dp"
        Android:padding="8dp"
        Android:textSize="22sp"
        Android:textStyle="bold"
        Android:textColor="@color/colorAccent"
        />

</LinearLayout>

MainActivity.Java

import Android.support.v7.app.AppCompatActivity;
import Android.os.Bundle;
import Android.support.v7.widget.GridLayoutManager;
import Android.support.v7.widget.LinearLayoutManager;
import Android.support.v7.widget.RecyclerView;
import Android.support.v7.widget.StaggeredGridLayoutManager;
import Android.text.Layout;

import Java.util.ArrayList;

/*
 * Demo Code of Recycler View
 * Created on: 19th Feb, 2017
 * Author Name: Rajat Talesra
 * Company Name: WiseL
 * This code is for Android Monk Campus Program.
 */

/*
 * Recycler View is mainly used to show dynamic list of data.
 * Many applications including Whatsapp, Facebook, Gmail, etc. used RecyclerView
 *
 * RecyclerView mainly uses two main components LayoutManager and Adapter
 *
 * LayoutManger: Helps to arrange data in LinearLayout or GridLayout
 *
 * Adapter: Helps to connect our recycler view with the custom layout and display data on screen
 *
 * In this demo we will display students list with their names and mobile numbers.
 */

public class MainActivity extends AppCompatActivity {

    //TODO(6): Create arrayList for student names and ids.

    ArrayList<String> namesArrayList = new ArrayList<>();
    ArrayList<String> mobileArrayList = new ArrayList<>();

    //TODO(7): Declare below mentioned components.

    RecyclerView rvStudentsList;
    RecyclerView.LayoutManager rvLayoutManager;

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

        //TODO(10): Add data to arrayList
        namesArrayList.add("Student 1");
        namesArrayList.add("Student 2");
        namesArrayList.add("Student 3");
        namesArrayList.add("Student 4");
        namesArrayList.add("Student 5");
        namesArrayList.add("Student 6");
        namesArrayList.add("Student 7");
        namesArrayList.add("Student 8");
        namesArrayList.add("Student 9");
        namesArrayList.add("Student 10");

        mobileArrayList.add("8766986401");
        mobileArrayList.add("8766986402");
        mobileArrayList.add("8766986403");
        mobileArrayList.add("8766986404");
        mobileArrayList.add("8766986405");
        mobileArrayList.add("8766986406");
        mobileArrayList.add("8766986407");
        mobileArrayList.add("8766986408");
        mobileArrayList.add("8766986409");
        mobileArrayList.add("8766986410");

        //TODO(9): Connect UI elements with Java objects.
        rvStudentsList = (RecyclerView) findViewById(R.id.rvStudents);


        //User this to display items vertically
        //rvLayoutManager = new LinearLayoutManager(this);

        //User this to display items in Grid Layout with 2 columns
        rvLayoutManager = new GridLayoutManager(this,2);

        //TODO(10): Attach layoutManager to recycler view
        rvStudentsList.setLayoutManager(rvLayoutManager);

        /*
         * Now we need to create one adapter, so that we can display data row wise
         * For this we will create our custom adapter, i.e. StudentAdapter.Java
         */

        //TODO(11): Create new Java class StudentAdapter.Java

        //TODO(16): Pass data to our custom adapter
        StudentAdapter studentAdapter = new StudentAdapter(this,namesArrayList,mobileArrayList);

        //TODO(17): Attach studentAdapter to recycler view

        rvStudentsList.setAdapter(studentAdapter);

        //TODO(18): Run your app.

    }
}

StudentAdapter.Java

import Android.content.Context;
import Android.support.v7.widget.RecyclerView;
import Android.view.LayoutInflater;
import Android.view.View;
import Android.view.ViewGroup;
import Android.widget.LinearLayout;
import Android.widget.TextView;
import Android.widget.Toast;

import Java.util.ArrayList;

//TODO(12): StudentAdapter extends RecyclerView Adapter with ViewHolder class


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

    //TODO(13): Create two empty arrayList and one context variable;

    Context mainActivityContext;
    ArrayList<String> namesArrayList = new ArrayList<>();
    ArrayList<String> mobileArrayList = new ArrayList<>();

    //TODO(14): Create one constructor with three parameters which will passed from MainActivity class

    public StudentAdapter(Context mainActivityContext, ArrayList<String> namesArrayList, ArrayList<String> mobileArrayList) {
        this.mainActivityContext = mainActivityContext;
        this.namesArrayList = namesArrayList;
        this.mobileArrayList = mobileArrayList;
    }

    //TODO(15): Complete each method as mentioned below


    @Override
    public StudentAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        //Used to connect our custom UI to our recycler view

        View v = LayoutInflater
                .from(parent.getContext())
                .inflate(R.layout.item_student, parent, false);

        return new ViewHolder(v);
    }

    @Override
    public void onBindViewHolder(StudentAdapter.ViewHolder holder, int position) {
        //Used to set data in each row of recycler view

        String currentName = namesArrayList.get(position);
        String currentMobileNumber = mobileArrayList.get(position);

        holder.tvName.setText(currentName);
        holder.tvMobileNumber.setText(currentMobileNumber);

    }

    @Override
    public int getItemCount() {
        //Returns total number of rows inside recycler view

        return namesArrayList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {
        //Used to work with the elements of our custom UI.

        LinearLayout llItemStudents;

        TextView tvName;
        TextView tvMobileNumber;

        public ViewHolder(View itemView) {
            super(itemView);

            tvName = (TextView) itemView.findViewById(R.id.tvStudentName);
            tvMobileNumber = (TextView) itemView.findViewById(R.id.tvMobileNumber);

            llItemStudents = (LinearLayout) itemView.findViewById(R.id.llItemStudents);

            llItemStudents.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(mainActivityContext,
                            "You clicked item number: "+ getAdapterPosition(),
                            Toast.LENGTH_SHORT).show();
                }
            });

        }
    }
}

Besuchen Sie auch offizielles Dokument

0
yoAlex5