Activity, Fragment, RecyclerView について、とりあえずメモ

# Activity, Fragment, RecyclerView

について、とりあえずメモ

---

# 🌒️ 序

Android app 作る tutorial とか見ると、まずは、2つ程度の activity を用意して、その間で画面遷移するサンプルコードが出てくる。でもこれ、割と過去の遺物らしい。今（といってももう6年ほど前から）は single activity とか言って、activity をたくさん作らないようにしようよ、って流れができているみたい。

なんで？っていうと、初心者が最初に躓くのが、 activity 間を結びつけるコードを書くのが難しいから。実際これはかなり綱渡りなコードになる。

1. Android app には main() みたいな唯一の起動ポイントが無く、どの activity から起動しても良い
2. OS は、メモリ逼迫などの必要に応じていつでも、任意の activity を消せる
3. したがって画面を呼び出したとき、既存のものを再利用する場合と新規起動する場合とがある

このあたりの仕様により、activity の instance をどこかで静的に保持することができず、this 渡してコールバックさせればいいじゃん、みたいなコードを書くと IDE に怒られる。

どうやら私が初心者だから難しいと思っていたのではなく、みんなが難しいと思っていたみたいで、流れが single activity とか navigation とかいう方向に行っているようだ。でもそういう新しい流れに沿ったコードが tutorial とか初心者向けサンプルコードには出てこないのが壁になっている。

---

# 🌕️ 破

## 伝統的な multi activity

サンプルコードやテンプレートはだいたいこれ。

簡単に見えるけど、 Activity 間のやりとりが割とハマりどころ。

```mermaid
%%{init:
	{
		"theme": "forest",
		"logLevel": 2,
		"flowchart": { "curve": "linear" }
	}
}%%

flowchart TB

	Application
	MainActivity <--> SecondActivity

subgraph Application
	direction TB
	MainActivity
	SecondActivity
end

linkStyle default color:#936, stroke:#f69, stroke-width:2px;
classDef default fill:#fcc, stroke:#345, stroke-width:3px, font-size:14pt;

```

## navigation に任せる

Application と Activity の間に、Navigation という層を入れて、そこに連携を任せる方法。Interface とか Kotlin Object とかを経由すると連携できるっていう解決策を Framework として提供してきた感じか。

```mermaid
%%{init:
	{
		"theme": "forest",
		"logLevel": 2,
		"flowchart": { "curve": "linear" }
	}
}%%

flowchart TB

	Application
	Navigation
	Controller <--> MainActivity
	Controller <--> SecondActivity

subgraph Application
	subgraph Navigation
		Controller
		MainActivity
		SecondActivity
	end
end

linkStyle default color:#936, stroke:#f69, stroke-width:2px;
classDef default fill:#fcc, stroke:#345, stroke-width:3px, font-size:14pt;

```

## single activity なら連携が発生しない?

複数作るから連携が難しいんだ。。。という、そもそもな発想転換。画面を切り替えるのではなく、Factory パターンで中身を入れ替えていく。

### RecyclerView で list の item 表示の view を動的に作る

```mermaid
%%{init:
	{
		"theme": "forest",
		"logLevel": 2,
		"flowchart": { "curve": "linear" }
	}
}%%

flowchart TB

	Application
	MainActivity
	RecyclerView <--> Adapter
	RecyclerView --> recycler_list_view
	List@{ shape: documents }
	Item@{ shape: document }
	List --> Adapter
	List -- position --> Item
	Item -- bind --> ViewHolder
	activity_main_view
	holder_item_view --> recycler_list_view
	ViewHolder --> holder_item_view

subgraph Application
	direction TB
	MainActivity
	List
end

subgraph MainActivity
	activity_main_view
	RecyclerView
	Adapter
end

subgraph Adapter
  Item
	ViewHolder
	holder_item_view
end

subgraph activity_main_view
	recycler_list_view
end

linkStyle default color:#936, stroke:#f69, stroke-width:2px;
classDef default fill:#fcc, stroke:#345, stroke-width:3px, font-size:14pt;

classDef view fill:#9ba, color:#306, font-size:14pt, stroke-width:4px;
class activity_main_view,recycler_list_view,holder_item_view view

classDef data fill:#ec3, color:#33a, font-size:12pt;
class List,Item data

```

### Fragment で、画面を入れ替える

一覧画面で List のどれかをタップしたときに Item の詳細画面を出す、とかを典型的なサンプルだと2つの Activity を使う。これを1つの Activity で実現するために、一覧画面と詳細画面を動的に入れ替える。これが Fragment だ。

```mermaid
%%{init:
	{
		"theme": "forest",
		"logLevel": 2,
		"flowchart": { "curve": "linear" }
	}
}%%

flowchart TB

	Application
	MainActivity
	RecyclerView <--> Adapter
	RecyclerView --> recycler_list_view
	List@{ shape: documents }
	Item@{ shape: document }
	ItemDetail@{ shape: document, label: "Item, Position" }
	List --> Adapter
	List -- position --> Item
	Item -- bind --> ViewHolder
	Adapter --> ItemDetail
	ItemDetail ---> fragment_item_view
	activity_main_view
	activity_main_view --- fragment_list_view
	activity_main_view --- fragment_item_view
	holder_item_view --> recycler_list_view
	ViewHolder --> holder_item_view
	BaseFragment --> ListFragment
	BaseFragment ---> ItemFragment
	ListFragment --- fragment_list_view
	ItemFragment --- fragment_item_view
	FragmentManager --> ListFragment
	FragmentManager ---> ItemFragment
	FragmentManager --- fragment_list_view
	FragmentManager --- fragment_item_view
	comment_list@{ shape: braces, label: "一覧画面"}
	comment_item@{ shape: braces, label: "詳細画面"}
	fragment_list_view --- comment_list
	fragment_item_view --- comment_item
	comment_list <--> comment_item

subgraph Application
	direction TB
	MainActivity
	List
	BaseFragment
	ListFragment
	ItemFragment
	comment_list
	comment_item
end

subgraph MainActivity
	activity_main_view
	fragment_list_view
	fragment_item_view
	RecyclerView
	Adapter
	ItemDetail
  FragmentManager
end

subgraph Adapter
  Item
	ViewHolder
	holder_item_view
end

subgraph fragment_list_view
	recycler_list_view
end

linkStyle default color:#936, stroke:#f69, stroke-width:2px;
classDef default fill:#fcc, stroke:#345, stroke-width:3px, font-size:14pt;

classDef view fill:#9ba, color:#306, font-size:14pt, stroke-width:4px;
class activity_main_view,recycler_list_view,holder_item_view,fragment_list_view,fragment_item_view view

classDef data fill:#ec3, color:#33a, font-size:12pt;
class List,Item,ItemDetail data

```

かなりすっきりしたように見えるものの、これでも実は、 Item, Position みたいな情報を MainActivity に引き渡すところで下手をすると闇に落ちる。

やってないので想像だが、そこの部分まですっきりさせたければ、さらに Navigation とかを投入するのか。。。

# 🌖️ 急

## 参考資料

### Navigation

[Navigation | App architecture | Android Developers](https://developer.android.com/guide/navigation/)

[[Android] Navigationの基礎の基礎 - Qiita](https://qiita.com/t_nana/items/d3f71faefa4ec69c0ca9)

### RecyclerView

[Create dynamic lists with RecyclerView | Views | Android Developers](https://developer.android.com/develop/ui/views/layout/recyclerview)

[【Android】世界一わかりやすいRecyclerViewの実装](https://zenn.dev/squ4t4r014/articles/a2cde436f4c099)

[android Kotlin RecyclerViewの使い方 - Qiita](https://qiita.com/soutominamimura/items/47a48e4e6e1aff3d3396)

[Simple Android RecyclerView example](https://stackoverflow.com/questions/40584424/simple-android-recyclerview-example)

### Fragment

[Fragments | App architecture | Android Developers](https://developer.android.com/guide/fragments)

[Single activity: Why, when, and how (Android Dev Summit '18)](https://youtu.be/2k8x8V77CrU?si=1XpmSM9zAmflmjf0)

[Fragments: Past, present, and future (Android Dev Summit '19)](https://youtu.be/RS1IACnZLy4?si=pgcJZdnmEe4Qiu1R)