<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>foxy_dev.log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Tue, 10 Jan 2023 13:22:54 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>foxy_dev.log</title>
            <url>https://velog.velcdn.com/images/foxy_dev/profile/b3c59331-f6f3-453d-8ada-46786c1e7fd0/social_profile.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. foxy_dev.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/foxy_dev" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[Compose FloatingActionButton 알아보기]]></title>
            <link>https://velog.io/@foxy_dev/Compose-FloatingActionButton-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@foxy_dev/Compose-FloatingActionButton-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Tue, 10 Jan 2023 13:22:54 GMT</pubDate>
            <description><![CDATA[<p><img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyS9gl%2FbtrgBB4Fjhk%2FVbgx4mJPOaNACdAhCeJ32k%2Fimg.png" alt="Jetpack Compose"></p>
<p>본 게시글은 Material3를 기준으로 작성되었습니다.</p>
<h2 id="floadingactionbutton">FloadingActionButton</h2>
<p>오늘은 다양하게 사용되는 FAB에 대해서 알아보겠습니다.</p>
<h3 id="fab">FAB</h3>
<pre><code class="language-kotlin">FloatingActionButton(
    onClick = {
        /* ... */
    },
    containerColor = Color.Red,
    shape = CircleShape,
) {
    Icon(
        imageVector = Icons.Rounded.Add,
        contentDescription = &quot;This is Add Fab&quot;,
        tint = Color.White,
    )
}</code></pre>
<h3 id="large-fab">Large FAB</h3>
<p>패드같이 큰 화면이나 눈에 잘 띄게 하기 위해 사용합니다.
기본 Fab보다 크기가 큽니다.</p>
<pre><code class="language-kotlin">LargeFloatingActionButton(
    onClick = {
        /* ... */
    },
    containerColor = Color.Red,
    shape = CircleShape,
) {
    Icon(
        imageVector = Icons.Rounded.Add,
        contentDescription = &quot;This is Add Fab&quot;,
        tint = Color.White,
    )
}</code></pre>
<h3 id="small-fab">Small FAB</h3>
<p>보조 Fab으로 사용합니다.</p>
<pre><code class="language-kotlin">LargeFloatingActionButton(
    onClick = {
        /* ... */
    },
    containerColor = Color.Red,
    shape = CircleShape,
) {
    Icon(
        imageVector = Icons.Rounded.Add,
        contentDescription = &quot;This is Add Fab&quot;,
        tint = Color.White,
    )
}</code></pre>
<h3 id="extended-fab">Extended FAB</h3>
<p>확장되는 Fab 입니다.
text 속성은 필수입니다.</p>
<pre><code class="language-kotlin">var isExtended = // 확장되는 조건

ExtendedFloatingActionButton(
    Icon(
        imageVector = Icons.Rounded.Add,
        contentDescription = &quot;This is Add Fab&quot;,
        tint = Color.White,
    ),
    text = {
        Text(text = &quot;Add Fab&quot;, color = Color.White)
    },
    onClick = {
        /* ... */
    },
    expanded = isExtended,
    containerColor = Color.Red,
)</code></pre>
<p>하지만 위의 Fab은 가로로 길어지는 확장형으로 세부적인 동작을 위한 세로로 확장되는 Fab은 다음과 같이 사용할 수 있습니다.</p>
<h3 id="customexpanded-fab">CustomExpanded FAB</h3>
<pre><code class="language-kotlin">var isExpanded by remember { mutableStateOf(false) }

Column(horizontalAlignment = Alignment.End) {
    if (isExpanded) {
        Column(
            modifier = Modifier
                .wrapContentSize()
                .background(color = Color.White, shape = RoundedCornerShape(10.dp))
                .padding(20.dp)
        ) {
            FabItem(
                title = &quot;세부항목2&quot;,
                icon = Icons.Default.MyLocation,
                onClicked = { /* ... */ }
            )
            Spacer(modifier = Modifier.height(20.dp))
            FabItem(
                title = &quot;세부항목1&quot;,
                icon = Icons.Default.AddIcCall,
                onClicked = { /* ... */ }
            )
        }
    }
    Spacer(modifier = Modifier.height(15.dp))
    FloatingActionButton(
        onClick = { isExpanded = !isExpanded },
        shape = CircleShape,
        containerColor = if (isExpanded) Color.Red else Color.White
    ) {
        Icon(
            imageVector = if (isExpanded) Icons.Default.Close else Icons.Defaults.Add,
            colorFilter = ColorFilter.tint(color = if (isExpanded) Color.White else Color.Red),
            contentDescription = &quot;This is Expand Button&quot;
        )
    }
}


@Composable
fun FabItem(title: String, icon: ImageVector, onClicked: () -&gt; Unit) {
    Row(modifier = Modifier.clickable {
        onClicked()
    }, verticalAlignment = Alignment.CenterVertically) {
        Icon(
            imageVector = icon,
            contentDescription = &quot;FabItem Icon&quot;
        )
        Spacer(modifier = Modifier.width(10.dp))
        Text(title)
    }
}</code></pre>
<p>하단 Fab을 누르면 그 위로 Column이 펼쳐지며 Custom한 탭들이 나오고 한번 더 누르면 닫히게 됩니다.</p>
<h2 id="마치며-🦊">마치며 🦊</h2>
<p>오늘은 Scaffold에서 사용할 수 있는 FloatingActionButton의 사용법에 대해 알아보았습니다.
다양하게 커스텀하여 사용할 수 있고 bottomBar와 Scaffold의 속성인 isFloatingActionButtonDocked를 사용한다면 bottomBar와 FAB을 겹치게 만들수도 있습니다.
</br></p>
<p>혹시나 잘못된 부분이나 부족한 부분이 있다면 댓글로 알려주시면 열심히 배우겠습니다.
읽어주셔서 감사합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Compose Scaffold 알아보기]]></title>
            <link>https://velog.io/@foxy_dev/Compose-Scaffold-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0</link>
            <guid>https://velog.io/@foxy_dev/Compose-Scaffold-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0</guid>
            <pubDate>Mon, 09 Jan 2023 14:32:06 GMT</pubDate>
            <description><![CDATA[<p><img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyS9gl%2FbtrgBB4Fjhk%2FVbgx4mJPOaNACdAhCeJ32k%2Fimg.png" alt="Jetpack Compose">
본 게시글은 Material3를 기준으로 작성되었습니다.</p>
<h2 id="scaffold">Scaffold</h2>
<p>Material Design에서 사용되는 Composable function으로 다양한 구성요소와 기타 화면 요소를 제공합니다.
기본적으로 일반 content 후행 람다 슬롯이 있어 컨텐츠 루트에서 PaddingValues 인스턴스를 수신해야합니다.</p>
<pre><code class="language-kotlin">Scaffold { contentPadding -&gt;
    Box(modifier = Modifier.padding(contentPadding)) {
        /* ... */
    }
}</code></pre>
<h3 id="appbar">AppBar</h3>
<p>상단 앱 바나 하단 앱 바(네비게이션 바)를 제공합니다.</p>
<pre><code class="language-kotlin">Scaffold(Padding -&gt;
        Text(
    topBar = {
        TopAppBar { /* ... */ }
    },
    bottomBar = {
        BottomAppBar { /* ... */ }
        // 혹은
        // NavigationBar() { /* ... */ }
    }
) {
    /* ... */
}</code></pre>
<h3 id="floatingactionbutton">FloatingActionButton</h3>
<p>플로팅 작업 버튼을 제공합니다.
floatingActionButtonPosition 을 이용하여 가로 위치를 조정할 수 있습니다.</p>
<pre><code class="language-kotlin">Scaffold(
    floatingActionButtonPosition = FabPosition.End,
    floatingActionButton = {
        FloatingActionButton(onClick = { /* ... */ }) {
            /* ... */
        }
    },

    // bottomBar가 있을 시 isFloatingActionButtonDocked 을 이용하여 겹치게 만들 수 있습니다.
    isFloatingActionButtonDocked = true,
    bottomBar = { /* ... */ }
) {
    /* ... */
}</code></pre>
<h3 id="snackbar">Snackbar</h3>
<pre><code class="language-kotlin">val coroutineScope = rememberCoroutineScope()
val snackbarHostState = remember { SnackbarHostState() }

Scaffold(
    snackbarHost = { SnackbarHost(snackbarHostState) },
    floatingActionButtonPosition = FabPosition.End,
    floatingActionButton = {
        FloatingActionButton(onClick = { 
            coroutineScope.launch {
                snackbarHostState.showSnackbar(&quot;Show Snackbar&quot;)
            }
        }) {
            /* ... */
        }
    }
) {
    SnackbarHost(
        hostState = snackBarHostState,
        /* ... */
    )
}
</code></pre>
<h2 id="마치며-🦊">마치며 🦊</h2>
<p>오늘은 Scaffold에 대해 간단히 알아보았습니다.</p>
<p>다음에는 Scaffold에서 사용할 수 있는 컴포넌트들을 하나씩 알아보도록 하겠습니다.
</br></p>
<p>혹시나 잘못된 부분이나 부족한 부분이 있다면 댓글로 알려주시면 열심히 배우겠습니다.
읽어주셔서 감사합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Compose Custom Font 설정하기]]></title>
            <link>https://velog.io/@foxy_dev/Compose-Custom-Font-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@foxy_dev/Compose-Custom-Font-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 06 Jan 2023 01:34:07 GMT</pubDate>
            <description><![CDATA[<p><img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyS9gl%2FbtrgBB4Fjhk%2FVbgx4mJPOaNACdAhCeJ32k%2Fimg.png" alt="Jetpack Compose"></p>
<p>디자이너와 작업하다보면 색상, 폰트, 기본 컴포넌트들을 모아놓고 사용해야하는 경우가 있습니다.
그 중 오늘은 커스텀 폰트를 정의하여 편하게 사용하는 방법을 소개하고자 합니다.</p>
<hr>
<h2 id="폰트-추가하기">폰트 추가하기</h2>
<p>원하는 폰트를 다운받은 후 res/font 폴더에 넣기만 하면 폰트 추가는 간단하게 할 수 있습니다.
<img src="https://velog.velcdn.com/images/foxy_dev/post/a58949f8-fa68-4990-848e-41de012cef8f/image.png" alt="font"></p>
<h2 id="정의하기">정의하기</h2>
<p>저는 FontUtil.kt 라는 파일을 만들어 디자이너의 폰트 DesignStyle을 모아놓았습니다.</p>
<p>먼저 FontFamily와 DesignStyle이 공통으로 사용하는 값들을 먼저 세팅해줍니다.</p>
<pre><code class="language-kotlin">private val myFontFamily = FontFamily(
    Font(R.font.spoqahan_sans_neo_bold, weight = FontWeight.Bold),
    Font(R.font.spoqahan_sans_neo_medium, weight = FontWeight.Medium),
    Font(R.font.spoqahan_sans_neo_regular, weight = FontWeight.Normal)
)

private val baseTextStyle = TextStyle(
    textAlign = TextAlign.Start,
    color = Color.Black,
    fontWeight = FontWeight.Normal,
    fontStyle = FontStyle.Normal,
    // 아래 속성은 기본폰트패딩을 없애주는 속성인데 작동은하지만 올바른 사용방법인지는 잘 모르겠습니다.
    platformStyle = PlatformTextStyle(includeFontPadding = false)
)</code></pre>
<p>다음으로 DesignStyle대로 사용할 이름들을 정의 한 후 Custom하여 스타일들을 정의해줍니다.</p>
<pre><code class="language-kotlin">enum class MyTextStyle {
    H1,
    H2,
    Body1
}

@Composable
fun getTextStyle(style: MyTextStyle): androidx.compose.ui.text.TextStyle {
    return when(style) {
        MyTextStyle.H1 -&gt; {
            baseTextStyle.copy(
                fontFamily = myFontFamily,
                fontSize = dpToSp(26.dp),
                lineHeight = dpToSp(34.dp),
                letterSpacing = dpToSp((-1.0).dp)
            )
        }
        MyTextStyle.H2 -&gt; {
            baseTextStyle.copy(
                fontFamily = myFontFamily,
                fontSize = dpToSp(24.dp),
                lineHeight = dpToSp(32.dp),
                letterSpacing = dpToSp((-1.0).dp)
            )
        }
        MyTextStyle.BODY1 -&gt; {
            baseTextStyle.copy(
                fontFamily = myFontFamily,
                fontSize = dpToSp(16.dp),
                lineHeight = dpToSp(24.dp),
                letterSpacing = dpToSp((-0.4).dp)
            )
        }
    }
}</code></pre>
<h2 id="사용하기">사용하기</h2>
<p>Composable에서 사용할때에는 아래처럼 사용합니다.</p>
<pre><code class="language-kotlin">@Composable
fun MyStyleText(content: String) {
    Text (
        text = content,
        style = getTextStyle(FontUtil.MyTextStyle.H1)
    )
}</code></pre>
<p>개별적으로 바꾸고싶은 속성들이 있다면 아래처럼 사용할 수 있습니다.</p>
<pre><code class="language-kotlin">@Composable
fun MyStyleText(content: String) {
    Text (
        text = content,
        style = getTextStyle(FontUtil.MyTextStyle.H1)
            .copy(color = Color.White)
    )
}</code></pre>
</br>

<h2 id="마치며-🦊">마치며 🦊</h2>
<p>오늘은 폰트 추가 방법과 디자이너와 개발할 때 유용한 폰트를 커스텀하여 모아두고 사용하는 방법을 알아보았습니다.
Text 컴포넌트를 매번 만들어 스타일을 정의하여 쓰는 방법 보다는 위의 방법이 더욱 편리하고 빠른 방법이라고 생각합니다.
</br></p>
<p>혹시나 잘못된 부분이나 부족한 부분이 있다면 댓글로 알려주시면 열심히 배우겠습니다.
읽어주셔서 감사합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Compose Custom Color 설정하기]]></title>
            <link>https://velog.io/@foxy_dev/Compose-Custom-Color-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@foxy_dev/Compose-Custom-Color-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0</guid>
            <pubDate>Thu, 05 Jan 2023 12:32:09 GMT</pubDate>
            <description><![CDATA[<p><img src="https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FyS9gl%2FbtrgBB4Fjhk%2FVbgx4mJPOaNACdAhCeJ32k%2Fimg.png" alt="Jetpack Compose"></p>
<p>디자이너와 작업하다보면 색상, 폰트, 기본 컴포넌트들을 모아놓고 사용해야하는 경우가 있습니다.
그 중 오늘은 색상을 모아놓고 사용하는 방법을 소개하고자 합니다.</p>
<hr>
<h2 id="정의하기">정의하기</h2>
<p>새로 kotlin 파일을 만들어 사용해도 되지만 저는 Compose 프로젝트를 생성하면 기본적으로 생성되는 ui/theme/color.kt에 아래와 같이 정의해두었습니다.</p>
<pre><code class="language-kotlin">// Primary
val Primary_Red_600 = Color(0xFFFC776E)
val Primary_Red_500 = Color(0xFFFF918A)
val Primary_Red_400 = Color(0xFFFFAAA5)
val Primary_Red_300 = Color(0xFFFFC8C5)
val Primary_Red_200 = Color(0xFFFFDFDD)
val Primary_Red_100 = Color(0xFFFFECEB)

// Secondary
val Diary_Green_600 = Color(0xFF31C99D)
val Diary_Green_500 = Color(0xFF59D4B1)
val Diary_Green_400 = Color(0xFF81D9BF)
val Diary_Green_300 = Color(0xFF9BE0CC)
val Diary_Green_200 = Color(0xFFC1EDE0)
val Diary_Green_100 = Color(0xFFDDF5EF)

val Primary_Blue_600 = Color(0xFF4DA9EE)
val Primary_Blue_500 = Color(0xFF6AB8F3)
val Primary_Blue_400 = Color(0xFF80C2F4)
val Primary_Blue_300 = Color(0xFF90C9F4)
val Primary_Blue_200 = Color(0xFFADD9FB)
val Primary_Blue_100 = Color(0xFFDBEFFF)</code></pre>
<h2 id="사용하기">사용하기</h2>
<p>Composable에서 사용할때에는 아래처럼 사용합니다.</p>
<pre><code class="language-kotlin">@Composable
fun ColorText(content: String) {
    Text (
        text = content,
        color = Primary_Red_600
    )
}</code></pre>
</br>

<h2 id="마치며-🦊">마치며 🦊</h2>
<p>오늘은 디자이너와 개발할 때 유용한 색상을 모아두고 사용하는 방법을 알아보았습니다.
별거 없는 것 같지만 같은 색상을 매번 새로 Hex코드를 작성해가며 개발하는것 보다는 위의 방법으로 편하게 사용하는것이 좋은 것 같습니다.</p>
<p>다음에는 폰트를 모아두고 사용하는 방법을 포스팅하도록 하도록 하겠습니다.
</br></p>
<p>혹시나 잘못된 부분이나 부족한 부분이 있다면 댓글로 알려주시면 열심히 배우겠습니다.
읽어주셔서 감사합니다.</p>
]]></description>
        </item>
    </channel>
</rss>