画面とコードのみで理解していくJetpack Compose その1

### Hello World

```MainActivity.kt

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            Text(text = "Hello World",Modifier.padding(8.dp))
        }
    }

```
Text ≒　TextView
Modifilerで各種属性が設定できる。

### Row Column

```RowLayout.kt 
@Composable
    fun RowLayout() {
        Row(
            modifier = Modifier
                .fillMaxSize(0.5f)
                .background(Color.Gray) ,
            horizontalArrangement = Arrangement.SpaceAround,
            verticalAlignment = Alignment.CenterVertically
        ) {
            Text(text = "Hello")
            Text(text = "World")
            Text(text = "Android")
        }
    }

``` 
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700755/d49ce902-54c2-6cfa-530f-a00088010d26.png" width=30%>


```ColumLayout.kt 
    @Composable
    fun ColumnLayout(){
        Column(
            modifier = Modifier
                .width(240.dp)
                .fillMaxHeight()
                .background(Color.Gray) ,
            horizontalAlignment = Alignment.CenterHorizontally,
            verticalArrangement = Arrangement.SpaceEvenly
        ) {
            Text(text = "Hello")
            Text(text = "World")
            Text(text = "Android")
        }
    }

```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700755/ecd485ed-6466-019e-5f7c-2b26e642f237.png" width=30%>

※Row,Column指定なしだと重なる。 

``` MainActivity.kt
setContent {
            Text(text = "Hello")
            Text(text = "World")
        }
```
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700755/21cc5f80-c967-3fb9-bf66-1d3ab042d934.png" width=30%>



### Clickable 

``` Clickable.kt
setContent {
            Column(Modifier.clickable {
                // do something
            })
            {
                Text(text = "hello",Modifier.clickable {
                    // do something
                })
            }
        }
``` 

いずれもCompossable部品にModifier.clickableでクリックリスナが書ける。

### ImageCard

```setContent.kt

setContent {
            val painter = painterResource(id = R.drawable.sample)
            val description = "sample image"
            val title = "title: 眼精疲労"
            Box(
                modifier = Modifier
                    .fillMaxWidth(0.8f)
                    .padding(12.dp))
            {
                ImageCard(painter = painter,
                    contentDescription = description,
                    title = title)
            }
        }

```

``` ImageCard.kt
@Composable
    fun ImageCard(
        painter: Painter,
        contentDescription: String ,
        title: String,
        modifier: Modifier = Modifier
    ) {
        Card(
            modifier = modifier
                .fillMaxWidth(),
            shape = RoundedCornerShape(15.dp),
            elevation = 5.dp
        ) {
            Box(modifier = Modifier.height(200.dp)) {
                Image(painter = painter,
                contentDescription = contentDescription,
                contentScale = ContentScale.Crop)

                Box(modifier = Modifier
                    .fillMaxSize()
                    .padding(12.dp),
                    contentAlignment = Alignment.BottomStart) {
                    Text(text = title,
                        style = TextStyle(color = Color.White),
                        fontSize = 16.sp)
                }
            }
        }
    }
```
ネストが深くなる。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700755/b5e7fe11-19c4-12bd-378e-7cd6f083b879.png" width=30%>


### 各種UIパーツ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700755/d2fb953c-a799-e1a3-5305-d48c52327695.png" width=30%>

```setContent.kt
setContent {
            Column(Modifier.fillMaxSize()) {
                TopAppBar() {
                    Text(text = "AppBar")
                }
                Snackbar(Modifier.padding(8.dp)) {
                    Text(text = "SnackBar")
                }
                TextField(value = "TextField", onValueChange = { /*TODO*/}, Modifier.padding(8.dp))
                Button(onClick = {/*TODO*/}, Modifier.padding(8.dp)) {
                    Text(text = "button")
                }
                Switch(checked = false, onCheckedChange = {/*TODO*/ }, Modifier.padding(8.dp))


                var state by remember { mutableStateOf(0) }
                val titles = listOf("TAB 1", "TAB 2", "TAB 3 WITH LOTS OF TEXT")
                Column {
                    TabRow(selectedTabIndex = state) {
                        titles.forEachIndexed { index, title ->
                            Tab(
                                text = { Text(title) },
                                selected = state == index,
                                onClick = { state = index }
                            )
                        }
                    }
                }

                var state2 by remember { mutableStateOf(true) }
                Row(Modifier.selectableGroup().padding(12.dp)) {
                    RadioButton(
                        selected = state2,
                        onClick = { state2 = true }
                    )
                    Text(text = "radioButton1")
                    RadioButton(
                        selected = !state2,
                        onClick = { state2 = false }
                    )
                    Text(text = "radioButton2")
                }

                var selectedItem by remember { mutableStateOf(0) }
                val items = listOf("Songs", "Artists", "Playlists")
                BottomNavigation (
                    Modifier.fillMaxSize()
                        ) {
                    items.forEachIndexed { index, item ->
                        BottomNavigationItem(
                            icon = { Icon(Icons.Filled.Favorite, contentDescription = null) },
                            label = { Text(item) },
                            selected = selectedItem == index,
                            onClick = { selectedItem = index }
                        )
                    }
                }
            }

```
viewの状態を残しておくにはrememberが必要。

### List

```MainActivity.kt
setContent {
            LazyColumn{
                itemsIndexed(
                    listOf("This", "is", "Jetpack", "compose", "List??")
                ) {
                        index, string ->
                    Text(
                        text = string,
                        fontSize = 24.sp,
                        fontWeight = FontWeight.Bold,
                        textAlign = TextAlign.Center,
                        modifier = Modifier.fillMaxWidth().padding(vertical = 24.dp)
                    )
                }
            }
        }
```

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/700755/4e02384b-fb9d-937b-07fc-67e1fb1b75a2.png" width=30%>


### 以上
JetPackComposeの利点は宣言型の記述方法による（rememberの使用方法にもよるが）副作用の発生を防げることが挙げられます。が、その辺の詳細は以下に書いてあるので参照ください。
[Compose の思想](https://developer.android.com/jetpack/compose/mental-model?hl=ja)

ConstraintLayoutも使えるので次回はその辺書く予定。swiftUIもいじりたい。


#### 参考
https://material.io/components?platform=android
https://developer.android.com/jetpack/compose/layout?hl=ja
https://developer.android.com/jetpack/compose/mental-model?hl=ja
https://www.youtube.com/watch?v=qvDo0SKR8-k&t=512s
https://www.youtube.com/c/PhilippLackner


#### おまけ
いろいろ情報探していて見つけたJoke動画。

<iframe width="560" height="315" src="https://www.youtube.com/embed/4ZKL0SsU4g8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>