基本的なRecyclerViewを作る
Poplation Ranking
- 人口ランキングをRecyclerViewで表示、チェックボックスで地域絞り込み
- こんなものを作る
構成
- MainActivity
- RankAdapter : adpter
- Data : データ配列を保持
- activity_main
- ranking_list : RecyclerView内部のView
実装方法
app > build.gradle
- ライブラリを追加
- dependencies {}
implementation 'com.android.support:recyclerview-v7:28.0.0'
activity_main.xml
- RecyclerViewを1つ用意
<android.support.v7.widget.RecyclerView android:id="@+id/rankList" android:layout_width="match_parent" android:layout_height="wrap_content"> </android.support.v7.widget.RecyclerView>
ranking_list.xml
- RecyclerViewで使用する1列分のviewを作成
- {順位、国名、人口数、地域}の4つを横並びで表示したいので以下のようにする。
- 国ごとのテキストの長さにかかわらず4つの幅を固定させたいので
layout_weight
を使う- 順位1,国名4,人口2,地域2 でとりあえず割り振る
- このとき
layout_width="0dp"
にしないとlayout_weightが効かない
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="4dp"> <TextView android:id="@+id/rank" android:layout_weight="1" android:layout_width="0sp" android:layout_height="wrap_content" android:textColor="#000000"/> <TextView android:id="@+id/country" android:layout_weight="4" android:layout_gravity="start" android:layout_width="0dp" android:layout_height="wrap_content" android:textColor="#000000"/> <TextView android:id="@+id/poplation" android:layout_weight="2" android:layout_gravity="start" android:layout_width="0dp" android:layout_height="wrap_content" android:textColor="#000000"/> <TextView android:id="@+id/area" android:layout_gravity="start" android:layout_weight="2" android:layout_width="0dp" android:layout_height="wrap_content" android:textColor="#000000"/> </LinearLayout>
Data.java
- 人口を載せてくれているサイトがあったのでそれを見て手打ちして文字列の二次元配列
String[][]
にする - 2/3が数値データなのにこのやり方ってどーなのと思いつつも最善策がわからずとりあえずこれで...
- エリアの名前を毎回入力するのが手間なのでエリア配列
areaArray
を作って番号を割り振る、data配列にはエリア名ではなくエリア番号を入力 エリア番号を確認しながら記入する作業面倒くさくて時間短縮できた気がしなかった
public class Data { public static String[][] data = { {"Chinese","1390","0" }, {"India","1316","0" }, ~~~省略~~ }; }
public static String[] areaArray ={ "アジア","北米","中南米","ヨーロッパ","オセアニア","中東","アフリカ" };
RankAdapter.java
- RecyclerViewにセットするためのAdapterを用意
- ざっとこんな感じ
public class RankAdapter extends RecyclerView.Adapter<RankAdapter.ViewHolder> { String[][] array; class ViewHolder extends RecyclerView.ViewHolder{ TextView rank; TextView country; TextView poplation; TextView area; ViewHolder(View view){ super(view); rank = view.findViewById(R.id.rank); country = view.findViewById(R.id.country); poplation = view.findViewById(R.id.poplation); area = view.findViewById(R.id.area); } } RankAdapter(String[][] _array){ array = _array; } @NonNull @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { LayoutInflater layoutInflater = LayoutInflater.from(viewGroup.getContext()); View view = layoutInflater.inflate(R.layout.ranking_list, viewGroup, false); return new ViewHolder(view); } @Override public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) { viewHolder.rank.setText("No."+ String.valueOf(i+1)); viewHolder.country.setText(array[i][0]); viewHolder.poplation.setText(array[i][1]); viewHolder.area.setText(Data.areaArray[Integer.parseInt(array[i][2])]); } @Override public int getItemCount() { return array.length; } }
- ViewHolder
- リスト一行ごとにfindViewByIdしてたら重くなるけどviewHolderで指定しておけば1回で済んで高速化できる、という代物らしい
- データを渡すview(今回はすべてTextView)の指定を行っておく
参考
ViewHolderを使わないでListViewを高速化する - Qiita Android ListViewとAdapterとViewHolder - うちなー えんじにあ ぶろぐ
- onCreateViewHolder
- Layoutの設定
onBindViewHolder
- 各viewにデータをセット
getItemCount
- ここの戻り値分
onCreateViewHolder
とonBindViewHolder
が処理される - 最初、処理ちゃんと描いたのに何も表示されない!なんで!とおもったらここが
return 0;
になってた... - とりあえずデータを全部突っ込んどいても、条件でデータ数変えられるのは地味に便利そう
- ここの戻り値分