Computer >> 컴퓨터 >  >> 체계 >> Android

Jetpack Compose로 앱 스타일 지정 및 테마 지정 방법

이 기사에서는 Jetpack Compose에서 응용 프로그램의 스타일을 지정하고 테마를 지정하는 방법을 배웁니다.

Compose는 이전 XML 기반 View 시스템을 대체하는 Android용 새로운 UI 프레임워크입니다(데스크톱 및 웹 지원이 개발 중임).

이 기사를 작성하는 시점에서 아직 베타 릴리스에 있지만 라이브러리의 이 특정 부분이 안정적인 릴리스를 위해 크게 변경될 것으로 기대하지는 않습니다.

주제는 다음과 같습니다.

  • XML 접근 방식에 대한 간략한 요약
  • XML 기반 색상, 테마 및 타이포그래피(글꼴) 시스템에서 마이그레이션하는 방법
  • 몇 줄의 코드로 앱의 밝은 테마와 어두운 테마를 설정하는 방법
  • 컴포저블에서 새로운 Kotlin 기반 스타일 정보를 사용하는 방법
  • 텍스트 컴포저블을 구체적으로 스타일 지정하는 방법

계속하기 전에 컴포저블이 무엇인지 이해하는 것이 중요합니다. 이 기사에서 이미 설명한 것처럼 여기에서 그 개념을 설명하기 위해 멈추지 않을 것입니다.

요약을 보려면 이 짧은 동영상을 시청하십시오.

XML 리소스를 사용하여 Android 앱의 스타일을 지정하는 방법

평소와 같이 이러한 주제에 대한 동기와 약간의 역사를 공유하고 싶습니다. 신경쓰지 않는다면 다음 섹션으로 건너뛰어 실용적인 내용을 살펴보세요.

안드로이드 리소스

Android 앱 리소스 시스템은 적어도 제 생각에는 Android 팀이 5위를 차지할 만한 가치가 있는 것입니다. 그러나 모든 설계 결정과 마찬가지로 한 상황의 기능은 다른 상황의 결함이 됩니다.

구체적으로 말하자면, 플랫폼 개발자와 애플리케이션 개발자 모두에게 가장 큰 과제 중 하나는 제가 현지화된 리소스라고 부르는 것을 만드는 것입니다. . 다음과 같은 앱을 구축하는 과제를 언급하고 있습니다.

  • 다양한 언어와 알파벳으로 텍스트와 그래픽 표시
  • 다양한 폼 팩터(크기, 밀도 등)에 비례하는 모양과 느낌

이것들은 단지 두 가지 일반적인 예일 뿐입니다. 더 많은 것이 있습니다. 리소스 시스템은 앱 개발자가 컴파일 타임에 플랫폼이 선택할 수 있는 현지화된 리소스를 제공할 수 있는 장소를 제공합니다. 이렇게 하면 해당 상용구 코드를 직접 작성하지 않아도 됩니다.

기능 또는 결함?

지역화된 문자열 리소스에 필요한 상용구 코드를 직접 관리하고 싶지는 않지만 그렇다고 XML 작성을 즐기는 것은 아닙니다.

사실, XML로 하고 싶은 일은 거의 없습니다 Kotlin이나 Swift와 같은 현대적이고 관용적이며 우아한 언어보다 개인적인 취향을 제외하고 XML 리소스가 항상 이상적이지 않은 데에는 더 기술적인 이유가 있습니다.

이것은 플랫폼 개발자/엔지니어를 비판하기 위한 것이 아닙니다. 설계 결정에 항상 이익과 비용이 따른다는 점을 관찰한 것일 뿐입니다.

XML 기반 리소스를 JVM 기반 애플리케이션 코드에 통합하려면 반드시 번역 레이어가 있어야 합니다. (편집) 및 플랫폼 브리지 (아피스). 이는 플랫폼 및 애플리케이션 개발자 모두에게 어려움을 줄 수 있습니다.

내가 겪었던 두 가지 일반적인 문제는 다음과 같습니다.

  • 리소스를 제공하는 플랫폼 API와의 긴밀한 결합을 원하지 않는 위치에서 리소스에 액세스하고 싶습니다.
  • 보기의 모양을 변경하려면(즉, 리소스 스타일 및 테마 내에 정의된 항목을 재정의하기 위해) 어리석은 상용구 코드를 작성해야 합니다.

근본 문제 관련된 모든 사람에게 긴밀한 결합 View 시스템과 Android 리소스 시스템(자체적으로 밀접하게 결합되어 있음).

플랫폼 개발자의 경우 이는 거대하고 오래된 코드베이스를 기반으로 구축하거나 이를 해결해야 함을 의미합니다. 그들은 또한 이전 Android OS 버전에서 새로운 기능이 작동하도록 시도해야 하며 이는 매우 감사할 일이라고 덧붙입니다.

우리 애플리케이션 개발자의 결과는 대부분 많은 상용구 코드입니다. 몇 가지 해킹된 해결 방법 직관적으로 한 줄로 표시되어야 하는 것처럼 보이는 것들에 대해. 이러한 리소스를 가져오기 위한 주요 API는 말할 것도 없이 Context입니다. , 메모리 누수를 원하지 않는 클래스입니다.

Jetpack Compose를 시작합니다.

Jetpack Compose로 테마, 색상 및 글꼴을 설정하는 방법

이전 시스템에 대한 검토를 마치고 Android 애플리케이션의 스타일을 지정하고 테마를 지정하는 훨씬 더 멋지고 간단한 방법을 살펴보겠습니다. 나는 이것을 실용적으로 유지하겠다고 말했지만 한 점을 허용합니다.

우리는 Kotlin에서 그 작업을 할 것이기 때문에 매우 중요한 한 가지를 의미합니다. 우리와 플랫폼 개발자 모두 번역(컴파일)과 API 브리지(Android의 R 클래스 및 Context ) XML과 JVM 사이.

간단히 말해서 보일러플레이트 코드가 훨씬 적음을 의미합니다. 및 런타임 시 훨씬 더 많은 제어 기능 .

이 기사의 실제적인 부분에서 내가 설명하는 순서대로 이 프로세스를 따르라고 제안합니다. 새 앱에서 이 코드를 작성할 때 따르는 순서대로 구성했습니다.

Colors.xml 리소스를 Kotlin Compose로 바꾸는 방법

응용 프로그램의 색 구성표를 아직 결정하지 않았다면 공식 Material Design 웹 사이트에서 제공되는 다양한 리소스를 사용하는 것이 좋습니다. 사용해 보기:

  • 색상 팔레트
  • 색상 도구

밝고 어두운 앱 테마(간단히 설명)를 지원할 계획이라면 흰색 텍스트를 지원하는 색 구성표와 검은색 텍스트를 지원하는 색 구성표를 선택하십시오.

Jetpack Compose로 앱 스타일 지정 및 테마 지정 방법
밝은 색과 어두운 색 구성표의 예

Color.kt와 같은 파일을 만들고(이름은 중요하지 않음) 변경할 수 없는 val로 채웁니다. 사용자:

import androidx.compose.ui.graphics.Color

val primaryGreen = Color(0XFF00bc00)
val primaryCharcoal = Color(0xFF2b2b2b)
val accentAmber = Color(0xFFffe400)

val textColorLight = Color(0xDCFFFFFF)
val textColorDark = Color(0xFFf3f3f3)
val gridLineColorLight = Color.Black
//...

Color.Black과 같은 미리 정의된 값을 사용할 수도 있습니다. 또는 고유한 ARGB 16진수 값을 제공하십시오.

ARGB Hex는 "0XFF00bc00 "는 다음을 의미합니다.

  • 처음 두 글자 0x 컴파일러에게 이것이 16진수임을 알려줍니다.
  • 두 번째 문자 "FF " 또는 "DC ", 투명도/불투명도/A를 나타냅니다. 16진수로 된 lpha
  • 나머지 6개의 문자 쌍은 R을 나타냅니다. 에드, G 린, 그리고 B

글꼴 추가 및 fontFamily 대체 방법 속성

타이포그래피(글꼴)도 관리하기가 매우 쉽습니다. 이것은 Kotlin의 기본 인수가 매우 유용한 종류입니다.

Type.kt와 같은 파일을 만들고(이름은 여전히 ​​중요하지 않음) Typography를 만듭니다. 클래스...:

val typography = Typography(
    body1 = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Normal,
        fontSize = 16.sp
    ),

    button = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Bold,
        fontSize = 32.sp
    ),

    caption = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Normal,
        fontSize = 12.sp
    )
)
//...

...및 일부 TextStyle 수업:

//...
val mainTitle = TextStyle(
    fontFamily = FontFamily.Default,
    fontWeight = FontWeight.Light,
    fontSize = 48.sp,
    textAlign = TextAlign.Center
)

fun dropdownText(color: Color) = TextStyle(
    fontFamily = FontFamily.Default,
    fontWeight = FontWeight.Normal,
    fontSize = 32.sp,
    textAlign = TextAlign.Center,
    color = color
)
//...

공개 함수 또는 값을 제공하는지 여부(var를 사용하지 않는 것이 좋습니다. 여기)는 개인의 선호도와 현재 요구 사항에 달려 있습니다.

Jetpack Compose에서 앱 테마를 만드는 방법

컴포저블에서 테마를 사용하기 전에 마지막으로 구성해야 하는 것은 MaterialTheme @Composable입니다. . 나는 GraphSudokuTheme라는 파일에 내 밝은 색상 팔레트와 어두운 색상 팔레트가 있습니다.

import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material.MaterialTheme
import androidx.compose.material.darkColors
import androidx.compose.material.lightColors
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color

private val LightColorPalette = lightColors(
    primary = primaryGreen,
    secondary = textColorLight,
    surface = lightGrey,
    primaryVariant = gridLineColorLight,
    onPrimary = accentAmber,
    onSurface = accentAmber
)

private val DarkColorPalette = darkColors(
    //main background color
    primary = primaryCharcoal,
    //used for text color
    secondary = textColorDark,
    //background of sudoku board
    surface = lightGreyAlpha,
    //grid lines of sudoku board
    primaryVariant = gridLineColorLight,
    onPrimary = accentAmber,

    onSurface = accentAmber

)

@Composable
fun GraphSudokuTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable () -> Unit
) {

    MaterialTheme(
        colors = if (darkTheme) DarkColorPalette else LightColorPalette,
        typography = typography,
        shapes = shapes,
        content = content
    )
}

컴포저블이 무엇인지 이미 알고 있을 것이므로(공평한 경고를 드렸습니다) 여기에서 새로 추가된 것은 darkTheme: Boolean = isSystemInDarkTheme()뿐입니다. .

간단히 설명하자면 isSystemInDarkTheme() 사용자가 선호하는 밝은 테마 또는 어두운 테마에 대해 호환되는 모든 Android 기기에 요청하는 호출입니다.

부울 값을 반환합니다. colors = if (darkTheme) DarkColorPalette else LightColorPalette과 같은 삼항(조건부) 할당 표현식에서 사용할 수 있는 .

그게 사실입니다. 몇 분 안에 정의되는 색상, 글꼴 및 두 가지 테마.

Compose에서 테마를 사용하는 방법

이제 앱에서 이 테마를 사용할 시간입니다. 기본 화면이 두 개뿐인 이 앱에서는 Activity를 컨테이너로 사용합니다. 내 컴포저블:

class NewGameActivity : AppCompatActivity(), NewGameContainer {
	//...
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
		//...

        setContent {
            GraphSudokuTheme {
                NewGameScreen(
                    onEventHandler = logic::onEvent,
                    viewModel
                )
            }
        }
		//...
    }

setContent {}로 전화를 거는 곳마다 , 초보자를 위한 제 제안은 즉시 테마 구성 가능을 그 안에 배치하는 것입니다. 그렇게 하면 스타일 정보가 중첩된 각 컴포저블에 계단식/상속됩니다. .

당신은 끝났습니다! 거의.

스타일 및 테마를 재정의하는 방법

도움이 된다면 밝고 어두운 팔레트에 원하는 색상을 포함시키십시오. 이렇게 하면 MaterialTheme.colors.<Color>을 호출할 때 , 시스템은 적절한 팔레트를 선택하는 데 필요한 조건부 논리를 처리합니다.

@Composable
fun NewGameContent(
    onEventHandler: (NewGameEvent) -> Unit,
    viewModel: NewGameViewModel
) {
    Surface(
        Modifier
            .wrapContentHeight()
            .fillMaxWidth()
    ) {
        ConstraintLayout(Modifier.background(MaterialTheme.colors.primary)) { 
        	//...
        }
        //...
      }
}      
        

그러나 때로는 자신의 조건부 논리를 작성하는 것이 더 적합합니다. 아니면 제가 게을렀습니다. 다행히 Compose는 다음과 같은 많은 구성을 속성으로 사용할 수 있습니다.

@Composable
fun DoneIcon(onEventHandler: (NewGameEvent) -> Unit) {
    Icon(
        imageVector = Icons.Filled.Done,
        tint = if (MaterialTheme.colors.isLight) textColorLight 
        else textColorDark,
        contentDescription = null,
        modifier = Modifier
            .clickable(
            //...
            )
    )
}

MaterialTheme.Colors.isLight 어떤 모드에 있는지 나타내는 부울 값을 반환하면 거기에서 다른 삼항 할당을 사용할 수 있습니다.

텍스트 컴포저블 스타일 지정 방법

style을 설정하면 됩니다. 텍스트 스타일 중 하나와 동일한 인수(MaterialTheme에서 가져온 것인지 여부) 또는 Type.kt 내의 스타일 중 하나 ):

Text(
    text = stat.toTime(),
    style = statsLabel.copy(
        color = if (isZero) Color.White
        else MaterialTheme.colors.onPrimary,
    fontWeight = FontWeight.Normal
    ),
    modifier = Modifier
        .wrapContentSize()
        .padding(end = 2.dp, bottom = 4.dp),
        textAlign = TextAlign.End
)

TextStyle 자체 copy이 있습니다. 덮어쓰기가 필요한 경우 기능을 사용할 수 있습니다.

그리고 그게 다야! 이제 Jetpack Compose를 사용하여 응용 프로그램의 스타일을 지정하고 테마를 지정하는 방법을 알게 되었습니다. 읽어주셔서 감사합니다 :)

소셜

여기 인스타그램과 여기 트위터에서 저를 찾을 수 있습니다.

여기에 내 튜토리얼 및 과정이 있습니다.

https://youtube.com/wiseass https://www.freecodecamp.org/news/author/ryan-michael-kay/ https://skl.sh/35IdKsj (Android Studio와 Android 소개)