구성 팔레트
18891 단어 jetpackcomposeandroidjetpackkotlin
android.graphics.Bitmap
에서 중요한 색상을 추출할 수 있습니다. Jetpack Compose 앱에서 Palette가 생성한 데이터를 사용합니다. 시작 직후 앱의 모습은 다음과 같습니다.FAB를 클릭한 후 사용자는 이미지를 선택할 수 있습니다. 그러면 앱이 다음과 같이 표시됩니다.
나쁘지 않죠? 소스 코드를 살펴보겠습니다. GitHub에서 찾을 수 있습니다.
비트맵 로드 및 팔레트 가져오기
Jetpack Palette를 사용하려면 구현 종속성에 추가해야 합니다.
implementation 'androidx.palette:palette-ktx:1.0.0'
다음으로 액티비티를 살펴보겠습니다.
class PaletteDemoActivity : ComponentActivity() {
private lateinit var viewModel: PaletteDemoViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(PaletteDemoViewModel::class.java)
setContent {
PaletteDemoTheme {
Surface(color = MaterialTheme.colors.background) {
PaletteDemo(
onClick = { showGallery() }
)
}
}
}
}
…
멋진 아키텍처를 얻기 위해
ViewModel
를 사용합니다. 활동에서 viewModel
가 사용된 위치를 곧 확인할 수 있습니다. 하지만 먼저 PaletteViewModel
를 살펴보겠습니다.class PaletteDemoViewModel : ViewModel() {
private val _bitmap: MutableLiveData<Bitmap> =
MutableLiveData<Bitmap>()
val bitmap: LiveData<Bitmap>
get() = _bitmap
fun setBitmap(bitmap: Bitmap) {
_bitmap.value = bitmap
}
private val _palette: MutableLiveData<Palette> =
MutableLiveData<Palette>()
val palette: LiveData<Palette>
get() = _palette
fun setPalette(palette: Palette) {
_palette.value = palette
}
}
따라서 비트맵과 팔레트라는 두 가지 속성이 있습니다. 둘 다 활동 내부에서 설정되고 구성 가능한 함수 내부에서 사용됩니다.
PaletteDemo()
는 구성 가능한 계층 구조의 루트입니다. showGallery()
를 호출하는 람다 식을 받습니다. 이 함수가 하는 일은 다음과 같습니다.private fun showGallery() {
val intent = Intent(Intent.ACTION_PICK)
intent.type = "image/*"
val mimeTypes =
arrayOf("image/jpeg", "image/png")
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes)
startActivityForResult(intent, REQUEST_GALLERY)
}
startActivityForResult()
는 ComponentActivity
에서 더 이상 사용되지 않기 때문에 교체해야 하지만 향후 문서를 위해 저장해 두겠습니다. 😎 다음은 흥미로운 부분입니다. 사용자가 이미지를 선택하면 어떻게 됩니까?override fun onActivityResult(requestCode: Int,
resultCode: Int,
intent: Intent?) {
super.onActivityResult(requestCode, resultCode, intent)
when (requestCode) {
REQUEST_GALLERY -> {
if (resultCode == RESULT_OK) {
intent?.let {
it.data?.let { uri ->
val source = ImageDecoder.createSource(
contentResolver,
uri
)
val bitmap = ImageDecoder.decodeBitmap(source).asShared()
viewModel.setBitmap(bitmap)
lifecycleScope.launch {
viewModel.setPalette(
Palette.Builder(bitmap).generate()
)
}
}
}
}
}
}
}
비트맵을 얻으려면 먼저
ImageDecoder.createSource()
를 사용하여 소스를 만듭니다. 그런 다음 소스가 ImageDecoder.decodeBitmap()
로 전달됩니다. asShared()
를 발견했습니까? 내부 Jetpack 팔레트getPixels()
가 호출됩니다. 이 메서드는 IllegalStateException: unable to getPixels(), pixel access is not supported on Config#HARDWARE bitmaps
와 함께 실패할 수 있습니다. asShared()
는 이를 방지합니다. 문서say:Return an immutable bitmap backed by shared memory which
can be efficiently passed between processes via Parcelable.If this bitmap already meets these criteria it will return
itself.
이 메서드는 API 레벨 31에서 도입되었으므로 이전 플랫폼을 지원하려면 비슷한 것으로 교체해야 합니다.
코드로 돌아갑니다. 비트맵에서 중요한 색상을 어떻게 얻습니까? 먼저
Palette.Builder
인스턴스를 만들어 비트맵을 전달합니다. 그런 다음 이 개체에서 generate()
를 호출합니다. 이 동기식 버전 외에도 AsyncTask
기반 변형도 있습니다. 보시다시피 저는 대신 코루틴을 사용하기로 했습니다.이제 구성 가능한 기능
PaletteDemo()
을 살펴보겠습니다.팔레트 구성
대부분의 Compose 앱은 루트로
Scaffold()
를 가지며 여기에는 TopAppBar()
및 제 예와 같이 FloatingActionButton()
가 포함될 수 있습니다. 내 콘텐츠 영역은 세로로 스크롤 가능한 영역Column()
으로 구성되어 있으며 이미지를 선택할 때까지 비어 있습니다. 그런 다음 중요한 색상을 나타내는 Image()
및 여러 Box()
요소를 포함합니다.@Composable
fun PaletteDemo(
viewModel: PaletteDemoViewModel = viewModel(),
onClick: () -> Unit
) {
val bitmap = viewModel.bitmap.observeAsState()
val palette = viewModel.palette.observeAsState()
Scaffold(topBar = {
TopAppBar(title = { Text(stringResource(id =
R.string.app_name)) })
},
floatingActionButton = {
FloatingActionButton(onClick = onClick) {
Icon(
Icons.Default.Search,
contentDescription =
stringResource(id = R.string.select)
)
}
}
) {
Column(
modifier = Modifier
.verticalScroll(rememberScrollState())
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
bitmap.value?.run {
Image(
bitmap = asImageBitmap(),
contentDescription = null,
alignment = Alignment.Center
)
}
palette.value?.run {
swatches.forEach {
Box(
modifier = Modifier
.padding(top = 8.dp)
.fillMaxWidth()
.height(32.dp)
.clip(RectangleShape)
.background(Color(it.rgb))
)
}
}
}
}
}
변경 사항에 대한 정보를 얻으려면
observeAsState()
및 bitmap
모두에서 palette
를 호출해야 합니다. asImageBitmap()
? 비트맵을 ImageBitmap
로 변환합니다.예를 들어
Palette
또는 getVibrantColor()
와 같이 getDarkVibrantColor()
인스턴스에서 호출할 수 있는 몇 가지 메서드가 있습니다. 내 코드는 swatches 목록을 반복합니다. 자세한 내용은 설명서를 참조하십시오.결론
Composable 앱 내에서 Jetpack Palette를 사용하는 것은 쉽고 재미있습니다. Material You 이후 라이브러리가 업데이트를 받는지 확인하는 것은 흥미로울 것입니다. 이 게시물이 마음에 드셨기를 바랍니다. 댓글로 여러분의 생각을 공유해주세요.
Reference
이 문제에 관하여(구성 팔레트), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/tkuenneth/composing-palettes-4pec텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)