JetPack Compose 시작하기

45802 단어 jepackcompsed
이 튜토리얼에서는 Google에서 관리하는 kotlin을 사용하여 Android UI의 빠른 개발을 위한 곧 출시될 UI 툴킷인 jetpack Compose 라이브러리의 몇 가지 개념에 대해 논의할 것입니다.

우리가 다룰 내용.


1. 사용자 지정 지그재그 그리드 만들기.


2. Composed로 커스텀 컬럼 생성하기.


3. ListView 생성.


4. 로직을 결합하여 전체 UI를 갖습니다.

수입품




import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.Layout
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.example.test2.ui.theme.Test2Theme
import com.google.accompanist.coil.rememberCoilPainter
import kotlinx.coroutines.launch
import kotlin.math.max


  • 맞춤형 엇갈린 그리드 생성

  • @Composable
    fun StaggeredGrid(
        modifier: Modifier = Modifier,
        rows: Int = 3,
        content: @Composable () -> Unit
    ) {
        Layout(
            modifier = modifier,
            content = content
        ) { measurables, constraints ->
    
            // Keep track of the width of each row
            val rowWidths = IntArray(rows) { 0 }
    
            // Keep track of the max height of each row
            val rowHeights = IntArray(rows) { 0 }
    
            // Don't constrain child views further, measure them with given constraints
            // List of measured children
            val placeables = measurables.mapIndexed { index, measurable ->
                // Measure each child
                val placeable = measurable.measure(constraints)
    
                // Track the width and max height of each row
                val row = index % rows
                rowWidths[row] += placeable.width
                rowHeights[row] = max(rowHeights[row], placeable.height)
    
                placeable
            }
    
            // Grid's width is the widest row
            val width = rowWidths.maxOrNull()
                ?.coerceIn(constraints.minWidth.rangeTo(constraints.maxWidth)) ?: constraints.minWidth
    
            // Grid's height is the sum of the tallest element of each row
            // coerced to the height constraints
            val height = rowHeights.sumBy { it }
                .coerceIn(constraints.minHeight.rangeTo(constraints.maxHeight))
    
            // Y of each row, based on the height accumulation of previous rows
            val rowY = IntArray(rows) { 0 }
            for (i in 1 until rows) {
                rowY[i] = rowY[i - 1] + rowHeights[i - 1]
            }
    
            // Set the size of the parent layout
            layout(width, height) {
                // x co-ord we have placed up to, per row
                val rowX = IntArray(rows) { 0 }
    
                placeables.forEachIndexed { index, placeable ->
                    val row = index % rows
                    placeable.placeRelative(
                        x = rowX[row],
                        y = rowY[row]
                    )
                    rowX[row] += placeable.width
                }
            }
        }
    }
    

    방금 만든 구현을 보려면 미리보기를 만들어 보겠습니다.

    엇갈린 그리드에 삽입하려는 열입니다.



    이미지는 drawable 폴더에 있어야 합니다.

    
    /* Testing custom staggered Grid. */
    
    @Composable
    fun GetImageColumn(text: String){
        val typography = MaterialTheme.typography
        MaterialTheme{
            Column (
                modifier = Modifier.padding(16.dp)
            ){
                Card(
                    elevation = 10.dp
    
                ){
                    Image(
                        painter = painterResource(R.drawable.header),
                        contentDescription = null,
                        modifier = Modifier
                            .height(180.dp)
                            .fillMaxWidth()
                            .clip(shape = RoundedCornerShape(4.dp)),
                        contentScale = ContentScale.Crop
                    )
                }
    
                Spacer(Modifier.height(16.dp))
                Card(
                    elevation = 10.dp,
                    modifier = Modifier.fillMaxWidth()
                ) {
                    Column (modifier = Modifier.padding(16.dp)){
                        Text(text = text, style = typography.h4)
                        Text("Nairobi Kenya", style = typography.body2)
                        Text("14 th Feb 2021", style = typography.body2)
                    }
                }
            }
    
        }
    }
    

    미리보기를 만들려면 아래 코드가 있습니다.

    @Preview(showBackground = true)
    @Composable
    fun Preview1(){
        Scaffold{
            Column(modifier = Modifier
                .padding(16.dp)
                .verticalScroll(rememberScrollState()),
                content = {
                    StaggeredGrid (rows = 2){
                        for (topic in topics) {
                            GetImageColumn(text = topic)
                        }
                    }
                }
            )
        }
    
    }
    

    미리보기 이미지: 프레임 포함.


    미리보기 이미지: 프레임 없음.


    작업 1 완료, 이제 작업 2로 이동하겠습니다.

    2. Compose로 사용자 지정 열 만들기.



    @Composable
    fun GetCustomColumn(modifier: Modifier, content: @Composable () -> Unit){
        Layout(modifier = modifier, content = content){
                measurables, constraints ->
    
            val placebles = measurables.map { measurable -> measurable.measure(constraints) }
    
            var yPosition = 0
    
            layout(constraints.maxWidth, constraints.maxHeight){
                placebles.forEach{
                    placeable -> placeable.placeRelative(x = 0, y = yPosition)
                    yPosition += placeable.height
                }
            }
    
        }
    }
    

    열을 테스트하기 위해 미리보기를 만드는 데 사용한 모든 열 컴포저블을 맞춤형 스태거 뷰로 교체할 수 있습니다.

    @Preview(showBackground = true)
    @Composable
    fun Preview1(){
        Scaffold{
            /* New  GetCustomColumn we created*/
            GetCustomColumn(modifier = Modifier
                .padding(16.dp)
                .verticalScroll(rememberScrollState()),
                content = {
                    StaggeredGrid (rows = 2){
                        for (topic in topics) {
                            GetImageColumn(text = topic)
                        }
                    }
                }
            )
        }
    
    }
    

    일부 미리보기.


    이제 다음 작업으로 넘어갑시다.

    3. ListView 생성.



    여기 우리 목록이 있습니다.

    val topics = listOf(
        "Arts & Crafts", "Beauty", "Books", "Business", "Comics", "Culinary",
        "Design", "Fashion", "Film", "History", "Maths", "Music", "People", "Philosophy",
        "Religion", "Social sciences", "Technology", "TV", "Writing"
    )
    

    목록 코드.

    @Composable
    fun SimpleList(){
        val listSize = 100
        // We save the scrolling position with this state
        val scrollState = rememberLazyListState()
        // We save the coroutine scope where our animated scroll will be executed
        val coroutineScope = rememberCoroutineScope()
    
        Row(
            modifier = Modifier.fillMaxWidth(),
            horizontalArrangement = Arrangement.SpaceEvenly
        ) {
            Button(
                onClick = {
                    coroutineScope.launch {
                        scrollState.animateScrollToItem(0)
                    }
                }
            ) {
                Text(text = "Top")
            }
            Button(
                onClick = {
                    coroutineScope.launch {
                        scrollState.animateScrollToItem(listSize - 1)
                    }
                }
            ) {
                Text(text = "Bottom")
            }
    
        }
        LazyColumn(state = scrollState) {
            items(listSize){
                PhotographerCard(numberCount = it)
            }
        }
    
    }
    
    
    @Preview(showBackground = true)
    @Composable
    fun LayoutsCodeLabPreview(){
        Test2Theme{
            SimpleList()
        }
    
    }
    
    
    
    @Composable
    fun PhotographerCard(modifier: Modifier = Modifier , numberCount: Number){
    
        Card(elevation = 10.dp, ) {
            Row(
                modifier
                    .padding(6.dp)
                    .clip(RoundedCornerShape(4.dp))
                    .background(MaterialTheme.colors.surface)
                    .clickable(onClick = { /*TODO Implement click */ })
                    .padding(16.dp)
                    .fillMaxWidth()
    
            ){
                Surface(
                    modifier = Modifier.size(50.dp),
                    shape = CircleShape,
                    color = MaterialTheme.colors.onSurface.copy(alpha = 0.2f)
    
                ) {
                    Image(
                        painter = rememberCoilPainter(
                            request = "https://developer.android.com/images/brand/Android_Robot.png"
                        ),
                        contentDescription = "Android Logo",
                        modifier = Modifier
                            .size(50.dp)
                            .padding(8.dp)
                    )
    //                Icon(Icons.Filled.PersonOutline, modifier = Modifier.padding(8.dp), contentDescription = null)
                }
    
                    Column(
                        modifier
                            .padding(start = 8.dp)
                            .align(Alignment.CenterVertically)
                    ) {
                        Text("List View. ", fontWeight = FontWeight.Bold)
                        CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.medium) {
                            Text(text = "$numberCount sec.", style = MaterialTheme.typography.body2)
                        }
    
                    }
    
    
            }
        }
    
    }
    

    시사


    마지막으로 간단한 UI가 작동하도록 모든 것을 결합해 보겠습니다.

    /* UI  play */
    @Preview(showBackground = true)
    @Composable
    fun LayoutsCodeLab(){
        Scaffold (
            topBar = {
                TopAppBar(
                    title = {
                        Text(text = "Design With Composed", style = MaterialTheme.typography.h5)
                    },
                    actions = {
                        IconButton(onClick = { /*TODO*/ }) {
                            Icon(Icons.Filled.Favorite, contentDescription = null)
                        }
                    }
                )
            }
        ){
    
            innerPadding -> BodyContent(
            Modifier
                .padding(innerPadding)
                .padding(8.dp))
    
        }
    }
    @Composable
    fun BodyContent(modifier: Modifier = Modifier){
        Spacer(Modifier.height(10.dp))
        GetCustomColumn(modifier = modifier) {
            Row(modifier = modifier
                .fillMaxWidth()
                .padding(16.dp)
                .size(200.dp)
                .horizontalScroll(rememberScrollState()),
                content = {
                    StaggeredGrid {
                        for (topic in topics) {
                            Chip(modifier = Modifier.padding(8.dp), text = topic)
                        }
                    }
                }
            )
            PreviewListView1()
        }
    
    }
    @Composable
    fun PreviewListView1(){
        Scaffold{
            /* New  GetCustomColumn we created*/
            // We save the scrolling position with this state
            val scrollState = rememberLazyListState()
    
            LazyColumn(state = scrollState) {
                for (topic in topics) {
                    items(topics.size) {
                        GetImageColumn(text = topic)
                    }
                }
            }
        }
    
    }
    

    시사.



    .ltag__user__id__171680 .follow-action-button {
    배경색: #0030b3 !중요;
    색상: #ffffff !중요;
    테두리 색상: #0030b3 !중요;
    }



    카 디 치엔자



    "Getting Started With JetPack Composed" by dev.to/kchienja/getti…


    오후 14:29 - 2021년 5월 26일












    카디치엔자 / kotlin_test1






    kotlin_test1


    Jetpack Compose는 기본 Android UI를 빌드하기 위한 최신 도구 키트입니다. 선언적 프로그래밍 모델을 기반으로 하므로 UI ​​모양을 간단히 설명하면 Compose가 나머지를 처리합니다. 즉, 앱 상태가 변경되면 UI가 자동으로 업데이트됩니다.


    View on GitHub

    좋은 웹페이지 즐겨찾기