이번에는 뷰모델을 이용해서 간단한 데이터를 가진 리사이클러 뷰를 만들어 볼 것임.
우선 파이어베이스와 앱이 연결되있어야함
사용자 리스트를 보여주는 간단한 뷰를 만들기 위해서 우선 데이터 클래스가 필요함
data class User( val uid : String, val region : String, val nickname : String, val birthday : String, val loginTime : String )
위의 데이터들을 파이어베이스에서 들고와서 관리하는 뷰모델을 만들어 주자.
@HiltViewModel class UserViewmodel @Inject constructor() : ViewModel() { private var fireStore: FirebaseFirestore = FirebaseFirestore.getInstance() val fireStorage = FirebaseStorage.getInstance() private val _userDataPack = mutableStateListOf(*mutableStateListOf<Pair<User, Uri>>().toTypedArray()) val userDataPack = _userDataPack fun getRealTimeUser(userGender : Int){ fireStore.collection("users") .get() .addOnSuccessListener { snapshot -> if(snapshot.isEmpty){ }else{ snapshot.documents.forEach { snap -> try{ val userBasicDataSnap = snap.toNaimanUserBasic()!! fireStorage.reference.child("userprofiles/${userBasicDataSnap.uid}/").list(1).addOnSuccessListener { it.items[0].downloadUrl.addOnSuccessListener { uri -> _userDataPack.add(userBasicDataSnap to uri) } } }catch (e:Exception){ } } } } } }
유저의 데이터를 가져오면서 그 유저의 uid를 참조하여 파이어 스토어에 저장된 사진도 하나 uri로 다운받아서 가져와 준다.. 원래같으면 그냥 StorageReference를 가져다가 사용하면 되는데 coil - compse에서는 아직 지원을 안하는 것 같아서 uri를 가지고 와서 사용한다.
그럼 바로 뷰를 만들어 보자
우선 사용할 원형의 이미지 뷰를 만들어 보자
@Composable fun NaimanUserListImage( onClick: () -> Unit, modifier: Modifier = Modifier, storageReference: Uri? ){ Column( modifier = modifier, verticalArrangement = Arrangement.Center, horizontalAlignment = Alignment.CenterHorizontally ) { Surface(shape = CircleShape) { Image( painter = rememberImagePainter( data = storageReference, onExecute = { _, _ -> true }, builder = { crossfade(true) transformations(CircleCropTransformation()) }), contentDescription = null, modifier = modifier.size(50.dp) ) } } }
그리고 정보들이 들어갈 컴포져블을 만든다..
@Composable fun UserTextPart( modifier: Modifier = Modifier, userData : User ){ val useAge = yeartoAge(userData.birthday.toString()) var time : String? = null userData.loginTime?.let{ val date = (it as Timestamp).toDate() time = timeLapseComplete(date) } Column(modifier = modifier.padding(all = 5.dp)) { Text(text = userData.nickname, fontWeight = FontWeight.Bold) Row() { Text(text = "${userData.regionDetail} / ${useAge}" , modifier.weight(2f)) time?.let{ times-> Text(text = times, modifier.weight(1f)) } } Surface(/*shape= onLineButton, color = Color.DarkGray*/) { Text( text = userData.selfIntroduce, modifier = modifier.fillMaxWidth().border(1.dp, Color.Black, RoundedCornerShape(5.dp) ).padding(5.dp), maxLines = 1 ) } } }
이 두개를 활용해서 하나의 리스트 아이탬을 만들자
@Composable fun UserCard( modifier: Modifier = Modifier, onClick : (String)->Unit, userData : A0LoginBasicdata, imgSize : Int = 50, userStorageReference: Uri? ){ val imgModifier = Modifier .size(imgSize.dp) Surface(/*color = Color.White*/) { Column() { Row( modifier = modifier .clickable { onClick(userData.nickname) } .fillMaxWidth() .padding(top = 8.dp) ) { NaimanUserListImage( onClick = { /*TODO*/ }, storageReference = userStorageReference, modifier = imgModifier .align(CenterVertically) .border(1.5.dp , Color.Red, CircleShape) .border(3.dp,Color.White, CircleShape) ) UserTextPart(userData = userData) } Divider() } } }
example item을 하나 설정해서 프리뷰를 확인해 보자
잘나옴
이걸 이용해서 리사이클러 뷰 같은 형태를 만들어 보자
@Composable fun RealTimeUserList( itemsData: List<Pair<A0LoginBasicdata, Uri>>, onClick: (String) -> Unit, ){ Surface(modifier = Modifier .fillMaxHeight() .fillMaxWidth() ) { LazyColumn( modifier = Modifier.padding(5.dp,60.dp,5.dp,0.dp), horizontalAlignment = Alignment.CenterHorizontally, ) { items(itemsData){ RealTimeUserCard( onClick = { onClick(it) }, userData = it.first, userStorageReference = it.second, imgSize = 60 ) } } } }
그리고 전체적 뷰를 만들자
@Composable fun RealTimeUserMainContents( fragmentTitle : String, onClick: (String) -> Unit, ){ val viewModel: RealTimeUserViewModel = viewModel() viewModel.getRealTimeUser(1) Surface(modifier = Modifier) { RealTimeUserList( onClick = { onClick(it) }, itemsData = viewModel.userDataPack ) M6RealTimeTopTap(title = fragmentTitle) } }
프레그먼트를 만들자
@AndroidEntryPoint class RealTimeUserFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View = ComposeView(inflater.context).apply { layoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT) setContent { MaterialTheme { RealTimeUserMainContents(fragmentTitle = "실시간 이성", onClick = { Toast.makeText(requireContext(),it,Toast.LENGTH_SHORT).show() }) } } } }
그러면 원하는 형태의 리스트가 보인다!
'어플 개발일기' 카테고리의 다른 글
Compose (쉬는시간 2) 호이스팅 (0) | 2021.08.02 |
---|---|
Compose (쉬는시간1) State, Remember (0) | 2021.08.02 |
Android Compose (2) 툴바 만들어 보기 + 단순 리스 (0) | 2021.07.31 |
Android Compose (1) 기초 (0) | 2021.07.29 |
data class를 번들(bundle)로 넘기기! (0) | 2021.06.20 |