web-dev-qa-db-ja.com

GridLayoutManagerでRecyclerViewを使用する単純なAndroidグリッドの例(古いGridViewのように)

RecyclerViewが古いListViewGridViewの機能を置き換えたことを私は知っています。私はRecyclerViewを使った最小限のグリッド設定を示す非常に基本的な例を探しています。私は長いチュートリアルスタイルの説明を探しているのではなく、ほんの一例です。古いGridViewを模した最も単純なグリッドは、次の機能で構成されていると思います。

  • 行ごとに複数のセル
  • 各セルの単一ビュー
  • クリックイベントに応答する
156
Suragch

短い答え

リストを作るためにRecyclerViewを設定することに精通している人たち にとって、良いことはグリッドを作ることはほとんど同じであるということです。 GridLayoutManagerを設定するときは、LinearLayoutManagerの代わりにRecyclerViewを使うだけです。

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

それ以上の助けが必要な場合は、次の例をチェックしてください。

完全な例

以下は、下の画像のように見える最小限の例です。

enter image description here

空のアクティビティから始めます。 RecyclerViewグリッドを追加するには、次の作業を行います。あなたがする必要があるのは、各セクションにコードをコピーして貼り付けることだけです。後であなたはあなたのニーズに合うようにそれをカスタマイズすることができます。

  • Gradleに依存関係を追加する
  • アクティビティ用とグリッドセル用のxmlレイアウトファイルを追加します。
  • RecyclerViewアダプターを作る
  • アクティビティでRecyclerViewを初期化します

Gradleの依存関係を更新する

アプリのgradle.buildファイルに次の依存関係があることを確認してください。

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

あなたは が最新であるものにバージョン番号を更新することができます

活動レイアウトを作成する

XmlレイアウトにRecyclerViewを追加してください。

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>

グリッドセルレイアウトを作成する

私たちのRecyclerViewグリッドの各セルはただ一つのTextViewを持ちます。新しいレイアウトリソースファイルを作成します。

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>

アダプターを作成する

RecyclerViewには、各セルのビューにデータを入力するためのアダプタが必要です。新しいJavaファイルを作成します。

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

ノート

  • 必ずしも必要というわけではありませんが、私はセルのクリックイベントをリッスンするための機能を含めました。これは古いGridViewで利用可能であり、一般的なニーズです。必要でなければ、このコードを削除することができます。

アクティビティ内でRecyclerViewを初期化する

以下のコードをあなたのメインアクティビティに追加してください。

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

ノート

  • アクティビティは、アダプタで定義したItemClickListenerを実装しています。これにより、セルクリックイベントをonItemClickで処理できます。

終了しました

それでおしまい。今すぐプロジェクトを実行して、上部の画像のようなものを取得できるはずです。

続いて

丸い角

自動調整カラム

さらなる研究

386
Suragch

Suragch の答え は気に入っていますが、リスナーを定義して公開するために Adapter MyRecyclerViewAdapter)をコーディングすることに気付いたので、メモを残します。クラスのカプセル化を正しく使用していないため、method onItemClickはそれを実行するための最良の方法ではありません。だから私の提案は Adapter にListening操作だけを処理させ(それが彼の目的です!)、それらを Adapter MainActivity)を使うActivityから切り離すことです。だからこれは私がアダプタクラスを設定する方法です:

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

onItemClickで定義されているMyRecyclerViewAdapterメソッドが、受け取ったイベント/アクションに対してタスクをコーディングしたい場所であることに注意してください。

この変換を完了するために行うべき小さな変更だけがあります: Activity はもうMyRecyclerViewAdapter.ItemClickListenerを実装する必要はありません。なぜなら今やそれは Adapter によって完全に行われるからです。これが最終的な変更になります。

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

中ガイドラインソース

GitHubレポ

Build.gradle内にRecyclerView依存関係を追加します。

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

        }
    }
}

公式ドキュメント にもアクセスしてください。

0
yoAlex5