Main Activityの基本(Recycler view編)

#Main Activityの基本(Recycler view編)

Recycler viewを利用して複数リストが表示される際、どのように生成され、画面に出力されるのかをまとめてみた

##今回作成したview

- リストごとにに写真とtextが表示されている
- 偶奇数のアイテムごとにviewが違う(見ずらいですがtextの色が変わっています)
- スクロールできるようになっている

<img width="400px" alt="" src="https://qiita-image-store.s3.amazonaws.com/0/117537/e3a07639-eade-e3cc-cdc2-df3406c31134.png">

##onCreate()
アクティビティが生成された時に行われるので、activityにつき1度しか読み込まれない。

- setContentViewメソッドでxmlファイルからメインとなる画面のレイアウトを呼び出し、設置する。

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

##onResume()
画面に映し出された時にonResumeが読み込まれる。
onCreate()とは違い、activityが生成された後、別の画面から再び一番上の画面になった時に再度読み込まれるので、画面が変わるごとに再度読み込まれて欲しいものはonResumeに書き、activityが生成された時点で一度のみ読み込まれる必要のあるものはonCreate()に書く

- Recycle viewを呼び出し、layoutManagerをセットする
- Adapterを生成し、addItems()メソッドによってデータを挿入する

```
    @Override
    protected void onResume() {
        super.onResume();
        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
        recyclerView.setHasFixedSize(true);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        RecyclerViewAdapter adapter = new RecyclerViewAdapter(this);
        recyclerView.setAdapter(adapter);
        adapter.addItems(createData());
    }
```

##createData()
- ArrayListのインスタンスを生成し、実際のデータを取得してきて``userInfo``に格納する

```
    @NonNull
    private List<UserInfo> createData() {
        List<UserInfo> userInfos = new ArrayList<>();

        UserInfo userInfo1 = new UserInfo(getString(R.string.sweets1), R.drawable.one);
        UserInfo userInfo2 = new UserInfo(getString(R.string.sweets2), R.drawable.two);
        UserInfo userInfo3 = new UserInfo(getString(R.string.sweets3), R.drawable.three);
        UserInfo userInfo4 = new UserInfo(getString(R.string.sweets4), R.drawable.four);
        UserInfo userInfo5 = new UserInfo(getString(R.string.sweets5), R.drawable.five);
        UserInfo userInfo6 = new UserInfo(getString(R.string.sweets6), R.drawable.six);
        UserInfo userInfo7 = new UserInfo(getString(R.string.sweets1), R.drawable.one);
        UserInfo userInfo8 = new UserInfo(getString(R.string.sweets1), R.drawable.one);
        UserInfo userInfo9 = new UserInfo(getString(R.string.sweets1), R.drawable.one);
        UserInfo userInfo10 = new UserInfo(getString(R.string.sweets1), R.drawable.one);
        UserInfo userInfo11 = new UserInfo(getString(R.string.sweets1), R.drawable.one);
        UserInfo userInfo12 = new UserInfo(getString(R.string.sweets1), R.drawable.one);
        userInfos.add(userInfo1);
        userInfos.add(userInfo2);
        userInfos.add(userInfo3);
        userInfos.add(userInfo4);
        userInfos.add(userInfo5);
        userInfos.add(userInfo6);
        userInfos.add(userInfo7);
        userInfos.add(userInfo8);
        userInfos.add(userInfo9);
        userInfos.add(userInfo10);
        userInfos.add(userInfo11);
        userInfos.add(userInfo12);
        return userInfos;
    }

    static class UserInfo {
        final String name;
        //final String timeStamp;
        @IdRes
        final Integer icon;

        UserInfo(String name, Integer icon) {
            this.name = name;
            //this.timeStamp = timeStamp;
            this.icon = icon;
        }
    }
```

##RecyclerViewAdapter
- Adapterによって データ(リスト内に表示したい情報)とレイアウト(リストなどの)を出力させる

###RecyclerViewAdapter()

```
        // 0番目
        public RecyclerViewAdapter(@NonNull Context context) {
            this.inflater = LayoutInflater.from(context);
            this.data = new ArrayList<>();
        }
```

###CustomViewHolder
- CustomViewHolder内ではリストの中に入れたいImageViewやTextViewなどを格納している
- 定義された変数内(iconView, nameView)にはそれぞれのレイアウトが格納されている

```
        static class CustomViewHolder extends RecyclerView.ViewHolder {
            ImageView iconView;
            TextView nameView;
//            TextView timeStampView;

            public CustomViewHolder(View itemView) {
                super(itemView);
                iconView = (ImageView) itemView.findViewById(R.id.photo);
                nameView = (TextView) itemView.findViewById(R.id.name);
//                timeStampView = (TextView) itemView.findViewById(R.id.time_stamp);
            }
        }
```

###onCreateViewHolder
リストのpositionをviewTypeで取得し、リストごとにレイアウトを挿入する(この場合では偶奇でレイアウトを分けているので偶奇ごとに条件分岐で別々のレイアウトを挿入している)

```
        // 2番目
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View recyclerViewListItem = null;
            if (viewType == VIEW_TYPE1) {
                recyclerViewListItem = inflater.inflate(R.layout.recycler_view_list_item, parent, false);
            } else {
                recyclerViewListItem = inflater.inflate(R.layout.recycler_view_list_item2, parent, false);
            }
            CustomViewHolder customViewHolder = new CustomViewHolder(recyclerViewListItem);
            return customViewHolder;
        }
```

###onBindViewHolder
- CustomViewholderのインスタンスを作成し、リストごとのそれぞれのアイテムのviewをよびだし、そこにデータを挿入する

```
        // 3番目
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
            CustomViewHolder customViewHolder = (CustomViewHolder) holder;
            customViewHolder.nameView.setText(data.get(position).name);
            customViewHolder.iconView.setImageResource(data.get(position).icon);
        }
```

###getItemViewType
- positionの位置の偶奇によって返す値を分けている

```
        @Override
        public int getItemViewType(int position) {
            if (position % 2 == 0) {
                return VIEW_TYPE1;
            }
            return VIEW_TYPE2;
        }
```

###getItemCount
- Itemの個数を数えるmethod

```
        // 1番目
        @Override
        public int getItemCount() {
            return data.size();
        }
```

###addItems
- ``data``に入っているデータを``name``変数に格納するメソッド 
- ``adapter.addItems(createData())``のmethodで使われている
- ``adapter.addItems(createData());``の際に使う、adapterにデータを挿入するためのmethod

```
        public void addItems(@NonNull List<UserInfo> name) {
            this.data.addAll(name);
            notifyDataSetChanged();
        }
```


##@overrideとは?
- ``override``されているというアノテーション(annotation)
- compile した時に、super classに定義されていない場合はエラーを出力してくれる。
- @NonNull は methodの前につけておくことで、このmethodはnullを返さないということをアノテーションしてくれる。

##getIndentifier()を利用して簡略化
- 先ほどのcreateData()メソッドが異様に長くなってしまったので、getIdentifierを使って簡略化しました。
- 取得したい複数データが数字の連番になっている時に便利(data1,data2,data3...など)

この部分を....

```
        List<UserInfo> userInfos = new ArrayList<>();

        UserInfo userInfo1 = new UserInfo(getString(R.string.sweets1), R.drawable.view1);
        UserInfo userInfo2 = new UserInfo(getString(R.string.sweets2), R.drawable.view2);
        UserInfo userInfo3 = new UserInfo(getString(R.string.sweets3), R.drawable.view3);
        UserInfo userInfo4 = new UserInfo(getString(R.string.sweets4), R.drawable.view4);
        UserInfo userInfo5 = new UserInfo(getString(R.string.sweets5), R.drawable.view5);
        UserInfo userInfo6 = new UserInfo(getString(R.string.sweets6), R.drawable.view6);
        UserInfo userInfo7 = new UserInfo(getString(R.string.sweets1), R.drawable.view1);
        UserInfo userInfo8 = new UserInfo(getString(R.string.sweets2), R.drawable.view2);
        UserInfo userInfo9 = new UserInfo(getString(R.string.sweets3), R.drawable.view3);
        UserInfo userInfo10 = new UserInfo(getString(R.string.sweets4), R.drawable.view4);
        UserInfo userInfo11 = new UserInfo(getString(R.string.sweets5), R.drawable.view5);
        UserInfo userInfo12 = new UserInfo(getString(R.string.sweets6), R.drawable.view6);
        userInfos.add(userInfo1);
        userInfos.add(userInfo2);
        userInfos.add(userInfo3);
        userInfos.add(userInfo4);
        userInfos.add(userInfo5);
        userInfos.add(userInfo6);
        userInfos.add(userInfo7);
        userInfos.add(userInfo8);
        userInfos.add(userInfo9);
        userInfos.add(userInfo10);
        userInfos.add(userInfo11);
        userInfos.add(userInfo12);
        return userInfos;
```

このように書き換える

```

List<UserInfo> userInfos = new ArrayList<>();
int strId, viewId;
String resViewName, resStrName;

Resources res = getResources()
for(int i = 1, i < 13; i++){ 
if(i > 6){
resStrName = "sweets" + i - 6;
resViewName = "view" + i - 6;
} else {
resStrName = "sweets" + i;
resViewName = "view" + i;
}
strId = res.getIdentifier(resStrName, "string", getPackageName());
viewId = res.getIdentifier(resViewName, "id", getPackageName());
UserInfo "userInfo" + i = new UserInfo(getString(strId), viewId)

resStrName = "userInfo" + i
userInfos.add(resStrName);
}
return userInfos;
```

##全ソースコード
https://gist.github.com/MihoSasaki/5cbad9f7844658d2f06f5d1cb984a3b2