読者です 読者をやめる 読者になる 読者になる

うさがにっき

読書感想文とプログラムのこと書いてきます

RecyclerViewを使ってみる

Android AndroidStudo

概要

AndroidStudioに慣れるため、lollipopから実装されたRecyclerViewを使ってみる
RecyclerViewはより効率的、色々なことができるようになったlistview

詳細

実装したソース

package project.test.recyclerviewproject.recyclerviewproject;

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.TextView;

import java.util.ArrayList;


public class SimpleAdapter extends RecyclerView.Adapter<SimpleAdapter.ViewHolder> {
    private LayoutInflater mLayoutInflater;
    private ArrayList<String> mDataList;

    public SimpleAdapter(Context context, ArrayList<String> dataList) {
        super();
        mLayoutInflater = LayoutInflater.from(context);
        mDataList = dataList;
    }

    @Override
    public SimpleAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = mLayoutInflater.inflate(R.layout.list_item, parent, false);
        ViewHolder viewHolder = new ViewHolder(v);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(SimpleAdapter.ViewHolder holder, int position) {
        String data = (String) mDataList.get(position);
        holder.text.setText(data);
    }

    @Override
    public int getItemCount() {
        return mDataList.size();
    }

    static class ViewHolder extends RecyclerView.ViewHolder {
        TextView text;

        public ViewHolder(View v) {
            super(v);
            // 2
            text = (TextView) v.findViewById(R.id.text);
        }
    }
}
package project.test.recyclerviewproject.recyclerviewproject;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.Menu;
import android.view.MenuItem;

import java.util.ArrayList;


public class MainActivity extends ActionBarActivity {

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

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);

        // ここで色々なLayoutManagerを設定することにより表示形式を変更できる
//        recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
//        recyclerView.setLayoutManager(new GridLayoutManager(getApplicationContext(), 3));
        recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));

        // レイアウトが固定の場合下記メソッドによってパフォーマンスが向上
        recyclerView.setHasFixedSize(true);

        ArrayList<String> mDataList = new ArrayList<String>();
        mDataList.add("test1");
        mDataList.add("test2");
        mDataList.add("test3");
        mDataList.add("test4");
        mDataList.add("test5");
        mDataList.add("test6");
        mDataList.add("test7");
        mDataList.add("test8");
        mDataList.add("test9");
        mDataList.add("test10");
        mDataList.add("test11");
        mDataList.add("test12");
        mDataList.add("test13");

        recyclerView.setAdapter(new SimpleAdapter(this, mDataList));
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

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

</RelativeLayout>

気づいたこと

  • viewHolderが必須になった
  • layoutManagerを変更することにより同じadapterでも簡単に表示形式を変更できるようになった

recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
f:id:tiro105:20141217185910p:plain

recyclerView.setLayoutManager(new GridLayoutManager(getApplicationContext(), 3));
f:id:tiro105:20141217185923p:plain

recyclerView.setLayoutManager(new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL));
f:id:tiro105:20141217185931p:plain

以下、Creating Lists and Cards | Android Developersを調べた時のメモ

The RecyclerView widget is a more advanced and flexible version of ListView. This widget is a container for displaying large data sets that can be scrolled very efficiently by maintaining a limited number of views. Use the RecyclerView widget when you have data collections whose elements change at runtime based on user action or network events.

RecyclerViewはListViewより発展していて、柔軟性があります
RecyclerViewはviewを限られた数で維持することにより、非常に効率的にスクロールすることができる大規模なデータセットを表示できます
ユーザのアクションやネットワークイベントに基づいて、実行時に変更されるデータコレクションがある場合RecyclerViewを使用してください

To use the RecyclerView widget, you have to specify an adapter and a layout manager. To create an adapter, extend the RecyclerView.Adapter class. The details of the implementation depend on the specifics of your dataset and the type of views. For more information, see the examples below.

RecyclerViewを使うときには、adapterとlayout managerを指定する必要があります
adapterを作成するにはRecyclerView.Adapterクラスを拡張してください
詳細な実装方法はデータセットの仕様とviewのタイプによって異なります
さらなる情報は、こちらの例をごらんください

A layout manager positions item views inside a RecyclerView and determines when to reuse item views that are no longer visible to the user.
To reuse (or recycle) a view, a layout manager may ask the adapter to replace the contents of the view with a different element from the dataset. Recycling views in this manner improves performance by avoiding the creation of unnecessary views or performing expensive findViewById() lookups.

1行目よくわかんない
viewを再利用する(またはリサイクル)するには、layoutmanagerは、データセットとは異なる要素でviewの内容を交換するadapterが必要になる時があります
これによりviewを再利用することでfindviewbyid()の高負荷な処理を回避できて、パフォーマンスが向上します

RecyclerView provides these built-in layout managers:

LinearLayoutManager shows items in a vertical or horizontal scrolling list.
GridLayoutManager shows items in a grid.
StaggeredGridLayoutManager shows items in a staggered grid.
To create a custom layout manager, extend the RecyclerView.LayoutManager class.


RecyclerViewにはこれらのlayout managerが組み込まれています。
LinearLayoutManager 縦か横のスクロールリスト
GridLayoutManager グリッド形式
StaggeredGridLayoutManager 千鳥格子形式