[Android] RecyclerView を使ってみました

| トラックバック(0) |

Android L Developer Preview、Material Design で追加された新ウィジェット(※1)である RecyclerView を使用してみました。

 

RecyclerView を使用すると、アイテムのサイズが固定長の場合に、従来よりも良いパフォーマンスが得られる(※2)ほか、

アイテムの追加、削除時などのアニメーション(※3)についても、デフォルトで利用することができます。

 

ちなみに RecyclerView のコードは、現時点(2014/7/11)では見れなかったのですが、前身のコード?っぽいのは、

sdk / sources / android-20 / android / support / v7 / widget / RecyclerView.java

にありました(約5,700行)。

(ソースコード読んで、notifyItemInserted() や notifyItemRemoved() の存在に気づくなど。。。)

 

以下、

従来の ListView & BaseAdapter で実装した場合のソースコードと、

RecyvlerView & RecyvlerView.Adapter で実装した場合のソースコードを貼っておきました。

文章で書くよりもコードを見た方が分かり易いと思いますので、コード内の番号をヒントに比較してみてください。

 

BaseAdapter(従来)のコード

public class SampleAdapter1 extends BaseAdapter {
    private LayoutInflater mLayoutInflater;
    private ArrayList<String> mDataList;

    // コンストラクタは、RecyclerView.Adapter でも変更なし
    public SampleAdapter1(Context context, ArrayList<String> dataList) {
        super();
        mLayoutInflater = LayoutInflater.from(context);
        mDataList = dataList;
    }

    // 4.RecyclerView.Adapter の場合、getItemCount() に書き換える
    @Override
    public int getCount() {
        return mDataList.size();
    }

    // RecyclerView.Adapter では不要
    @Override
    public Object getItem(int position) {
        return mDataList.get(position);
    }

    // RecyclerView.Adapter では不要
    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView == null) {

            // 1.RecyclerView.Adapter の場合、この部分を onCreateViewHolder() で実装する
            // ViewHolder の引数には、インフレートしたビューを渡すように変更する
            convertView = mLayoutInflater.inflate(R.layout.list_item, parent, false);
            viewHolder = new ViewHolder();

            // 2.RecyclerView.Adapter の場合、この部分を ViewHolder のコンストラクタ内で実装する
            viewHolder.text = (TextView) convertView.findViewById(R.id.text);

            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        // 3.RecyclerView.Adapter の場合、この部分を onBindViewHolder() で実装する
        String data = (String) getItem(position);
        viewHolder.text.setText(data);

        return convertView;
    }

    static class ViewHolder {
        TextView text;
    }
}

 

RecyvlerView.Adapter に書き換えた場合のコード

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

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

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

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

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

    static class ViewHolder extends RecyclerView.ViewHolder {
        TextView text;

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

 

ListView(従来)のコード

ListView listView = (ListView) view.findViewById(R.id.listview);

// アダプターの設定(mDataList は、ここでは ArrayList<String>)
listView.setAdapter(new SampleAdapter1(getActivity(), mDataList));

 

RecyvlerView に書き換えた場合のコード

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

// コンテキスト:Activity内ではthis、Fragment内ではgetActivity()など
recyclerView.setLayoutManager(new LinearLayoutManager(コンテキスト));
recyclerView.setHasFixedSize(true); // アイテムは固定サイズ

// アダプターの設定(mDataList は、ここでは ArrayList<String>)
recyclerView.setAdapter(new SampleAdapter2(getActivity(), mDataList));

 

ListView(従来)のリソース

<ListView
    android:id="@+id/listview"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

 

RecyvlerView に書き換えた場合のリソース

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

 

RecyvlerView.Adapter でデフォルトアニメーションを使用する例

// アイテム追加後、notifyItemInserted(index)を呼び出す(ここでは最後に追加)
recyclerView.getAdapter().notifyItemInserted(mDataList.size() - 1);

// アイテム削除後、notifyItemRemoved(index)を呼び出す(ここでは先頭を削除)
recyclerView.getAdapter().notifyItemRemoved(0);

 

備考

※1:N5だと、従来のListView と動作比較してみたところ、目に見えてわかるような差は体感できませんでした

※2:Material Design の追加ウィジェットは2つだけで、もう一方は以前紹介した CardView

※3:アニメーションは RecyclerView.ItemAnimator で自作したものへ置き換え可能

トラックバック(0)

トラックバックURL: http://mt.adakoda.com/mt-tb.cgi/618

2014年7月

    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