Skip to content

Commit

Permalink
add instagram search
Browse files Browse the repository at this point in the history
  • Loading branch information
kwmt committed Dec 30, 2023
1 parent cbfbadb commit 1f28433
Show file tree
Hide file tree
Showing 5 changed files with 652 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ import net.kwmt27.jetpackcomposeplayground.icon.UpIconSample
import net.kwmt27.jetpackcomposeplayground.image.CircleImageSample
import net.kwmt27.jetpackcomposeplayground.list.ListWithUpdatableItem
import net.kwmt27.jetpackcomposeplayground.list.SampleHorizontalList
import net.kwmt27.jetpackcomposeplayground.list.SampleInstagramSearchListLayout
import net.kwmt27.jetpackcomposeplayground.list.instagram.SampleInstagramSearchListLayout
import net.kwmt27.jetpackcomposeplayground.list.SampleVerticalList
import net.kwmt27.jetpackcomposeplayground.list.StickyListSample
import net.kwmt27.jetpackcomposeplayground.livedata.SampleMutableLiveDataScreen
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package net.kwmt27.jetpackcomposeplayground.list
package net.kwmt27.jetpackcomposeplayground.list.instagram

import android.util.Log
import androidx.compose.foundation.background
Expand Down Expand Up @@ -31,6 +31,49 @@ import net.kwmt27.jetpackcomposeplayground.ui.theme.JetpackComposePlayGroundThem

private const val TAG = "InstagramSearchList"

enum class MoviePosition {
LEFT, RIGHT
}

data class GridRowData(
val list: List<ItemData>,
)

sealed interface ItemData {
val id: Int

@Stable
data class ItemImage(
override val id: Int,
val list: List<String> = emptyList()
) : ItemData

@Stable
data class ItemMovie(
override val id: Int,
) : ItemData
}

data class GridListData(
val list: List<GridRowData>,
) {
companion object {
fun createData(): GridListData {
return (1..1000).mapIndexed { index, i ->
if (index % 5 == 0 && index != 0) {
ItemData.ItemMovie(i)
} else {
ItemData.ItemImage(i)
}
}.chunked(5).map { items ->
GridRowData(items)
}.run {
GridListData(this)
}
}
}
}

@Composable
fun SampleInstagramSearchListLayout() {
InstagramSearchListLayout(GridListData.createData())
Expand All @@ -51,16 +94,7 @@ private fun InstagramSearchListLayout(
} else {
listState.firstVisibleItemIndex + 1
}
// OK例
// val playMovieIndex by remember {
// derivedStateOf {
// if (listState.firstVisibleItemScrollOffset == 0) {
// listState.firstVisibleItemIndex
// } else {
// listState.firstVisibleItemIndex + 1
// }
// }
// }

BoxWithConstraints {
LazyColumn(
modifier = Modifier
Expand Down Expand Up @@ -90,10 +124,6 @@ private fun InstagramSearchListLayout(
}
}

private enum class MoviePosition {
LEFT, RIGHT
}

@Composable
private fun GridRowItem(
gridRowData: GridRowData,
Expand Down Expand Up @@ -229,44 +259,6 @@ private fun ItemMovie(item: ItemData, width: Dp, listState: LazyListState, index
}
}

data class GridListData(
val list: List<GridRowData>,
) {
companion object {
fun createData(): GridListData {
return (1..1000).mapIndexed { index, i ->
if (index % 5 == 0 && index != 0) {
ItemData.ItemMovie(i)
} else {
ItemData.ItemImage(i)
}
}.chunked(5).map { items ->
GridRowData(items)
}.run {
GridListData(this)
}
}
}
}

data class GridRowData(
val list: List<ItemData>,
)

sealed interface ItemData {
val id: Int

@Stable
data class ItemImage(
override val id: Int,
) : ItemData

@Stable
data class ItemMovie(
override val id: Int,
) : ItemData
}

@Preview(showBackground = true, device = "spec:width=320dp,height=640dp")
@Composable
private fun PreviewInstagramSearchList() {
Expand All @@ -277,7 +269,7 @@ private fun PreviewInstagramSearchList() {

@Preview(showBackground = true, device = "spec:width=320dp,height=640dp")
@Composable
fun PreviewGridItemImages() {
private fun PreviewGridItemImages() {
JetpackComposePlayGroundTheme {
BoxWithConstraints {
GridItemImages(
Expand All @@ -290,7 +282,7 @@ fun PreviewGridItemImages() {

@Preview(showBackground = true, device = "spec:width=320dp,height=640dp")
@Composable
fun PreviewItemMovie() {
private fun PreviewItemMovie() {
JetpackComposePlayGroundTheme {
BoxWithConstraints {
ItemMovie(GridListData.createData().list.get(2).list.last(), 320.dp / 3, isPlay = false)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,223 @@
package net.kwmt27.jetpackcomposeplayground.list.instagram

import android.util.Log
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import net.kwmt27.jetpackcomposeplayground.ui.theme.JetpackComposePlayGroundTheme

private const val TAG = "InstagramSearchList"

@Composable
fun SampleInstagramSearchListLayout2() {
InstagramSearchListLayout(GridListData.createData())
}

@Composable
private fun InstagramSearchListLayout(
gridListData: GridListData,
) {
val listState = rememberLazyListState()
// OK例
val playMovieIndex by remember {
derivedStateOf {
if (listState.firstVisibleItemScrollOffset == 0) {
listState.firstVisibleItemIndex
} else {
listState.firstVisibleItemIndex + 1
}
}
}
BoxWithConstraints {
LazyColumn(
modifier = Modifier
.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(1.dp),
state = listState,
) {
itemsIndexed(gridListData.list) { index, gridRowData ->
val moviePosition = if (index % 2 == 0) {
MoviePosition.RIGHT
} else {
MoviePosition.LEFT
}
GridRowItem(
gridRowData = gridRowData,
width = maxWidth / 3,
moviePosition = moviePosition,
listState = listState,
index = index,
// // [isPlay]はスクロールの状態によって変化するため、
// // Booleanを直接渡すと、recomposeされてしまう。
// // そのため、関数を渡すことによりCompositionを防ぐ
isPlay = index == playMovieIndex
)
}
}
}
}

@Composable
private fun GridRowItem(
gridRowData: GridRowData,
width: Dp,
moviePosition: MoviePosition,
listState: LazyListState,
index: Int,
isPlay: Boolean,
) {
// val playMovieIndex by remember {
// derivedStateOf {
// if (listState.firstVisibleItemScrollOffset == 0) {
// listState.firstVisibleItemIndex
// } else {
// listState.firstVisibleItemIndex + 1
// }
// }
// }
//
// val isPlay = { playMovieIndex ==index }
/**
* [item][item][ItemImage]
* [item][item] ---
*/
val itemImageDataList: List<List<ItemData>> = gridRowData.list.take(4).chunked(2)
val itemMovieData = gridRowData.list.last()

Row(
horizontalArrangement = Arrangement.spacedBy(1.dp),
) {
if (moviePosition == MoviePosition.LEFT) {
ItemMovie(itemMovieData, width, isPlay)
// ItemMovie(itemMovieData, width, listState, index)
}
GridItemImages(itemImageDataList, width)

if (moviePosition == MoviePosition.RIGHT) {
ItemMovie(itemMovieData, width, isPlay)
// ItemMovie(itemMovieData, width, listState, index)
}
}
}

@Composable
private fun GridItemImages(
itemImageDataList: List<List<ItemData>>,
width: Dp,
) {
Column(
verticalArrangement = Arrangement.spacedBy(1.dp)
) {
itemImageDataList.forEach { itemImageData ->
Row(
horizontalArrangement = Arrangement.spacedBy(1.dp)
) {
itemImageData.forEach { itemData ->
ItemImage(itemData, width)
}
}
}
}
}

@Composable
private fun ItemImage(item: ItemData, width: Dp) {
Box(
modifier = Modifier
.size(width = width, height = width)
.background(color = Color.Gray),
contentAlignment = Alignment.Center
) {
Text(
text = "${item.id} 画像",
style = TextStyle(fontSize = 20.sp, color = Color.White)
)
}
}

@Composable
private fun ItemMovie(item: ItemData, width: Dp, isPlay: Boolean) {
Log.d(TAG, "ItemMovie: id=${item.id}, isPlay=${isPlay}")
val color = if (isPlay) Color.Green else Color.Red
Column(
modifier = Modifier
.size(width = width, height = width * 2 + 1.dp)
.background(color = color),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "${item.id} 動画",
style = TextStyle(fontSize = 20.sp, color = Color.White)
)
val text = if (isPlay) "Playing" else "Stop"
Text(
text = text,
style = TextStyle(fontSize = 20.sp, color = Color.White)
)
}
}

@Composable
private fun ItemMovie(item: ItemData, width: Dp, listState: LazyListState, index: Int) {
val isPlay by remember {
derivedStateOf {
val firstVisibleItemIndex = if (listState.firstVisibleItemScrollOffset == 0) {
listState.firstVisibleItemIndex
} else {
listState.firstVisibleItemIndex + 1
}
firstVisibleItemIndex == index
}
}

Log.d(TAG, "ItemMovie: id=${item.id}, isPlay=${isPlay}")
val color = if (isPlay) Color.Green else Color.Red
Column(
modifier = Modifier
.size(width = width, height = width * 2 + 1.dp)
.background(color = color),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
text = "${item.id} 動画",
style = TextStyle(fontSize = 20.sp, color = Color.White)
)
val text = if (isPlay) "Playing" else "Stop"
Text(
text = text,
style = TextStyle(fontSize = 20.sp, color = Color.White)
)
}
}

@Preview(showBackground = true, device = "spec:width=320dp,height=640dp")
@Composable
private fun PreviewInstagramSearchList2() {
JetpackComposePlayGroundTheme {
SampleInstagramSearchListLayout2()
}
}
Loading

0 comments on commit 1f28433

Please sign in to comment.