Colors Palette API | Selecting Colors with the Palette API in Android with Example
Good visual design is essential for a successful app, and color schemes are a primary component of design.
The palette library is a support library that extracts prominent colors from images to help you create visually engaging apps.
Goals
- By the end of this tutorial, the reader should:
- Have an understanding of what Palette API is.
- Know how to set up the Palette API library.
- Know how to extract colors from an image using the Palette API.
What is Palette?
- Palette is a support library in Android. It extracts prominent colors from Bitmap images. We can use it in styling view components in the app.
- The views matche the prominent color from the image. For instance, the toolbar, background, or even text color.
Advantages of Using Palette API
- It provides a helper class to extract prominent colors from an image.
- We can use colors obtained to make elegant application UI designs.
- We can customize the color Palette using in-build methods. For instance, adding filters and much more.
Set up the library
implementation 'androidx.palette:palette:1.0.0'
..
Color profiles may be extracted from images on Android using AndroidX’s Palette API; typically, color profiles would be used to generate color-coordinated widgets based on a picture.
A card, for example, may include an image and title text that are colored in accordance with the picture’s color profiles. Palette API allows you to obtain the following color profiles:
- Light Vibrant
- Vibrant Dark
- Vibrant Light
- Muted Muted
- Dark Muted
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:paddingTop="16dp"
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:clipToPadding="false">
<ImageView
android:id="@+id/color_extraction_target_image_view"
android:layout_width="match_parent"
android:layout_height="200dp"
android:src="@drawable/sample2"
android:scaleType="centerCrop"
android:fitsSystemWindows="true"
app:layout_collapseMode="parallax"
android:contentDescription="@string/app_name" />
<TextView
android:gravity="center"
android:id="@+id/header_subtitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="Extract representative color palettes from images."
android:textAppearance="?attr/textAppearanceBody2"
android:textColor="@color/material_on_surface_emphasis_medium"/>
<GridLayout
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:columnCount="2"
android:useDefaultMargins="true">
<LinearLayout
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/vibrant_image_view"
android:layout_marginTop="10dp"
tools:ignore="InefficientWeight"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:scaleType="fitXY"
app:elevation="5dp"
app:shapeAppearance="@style/ShapeAppearanceColorPallate"
app:strokeColor="@color/colorPaletteBorder"
app:strokeWidth="1dp" />
<TextView
android:layout_marginTop="5dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:text="@string/vibrant_color_label"
/>
<!--<TextView
android:id="@+id/color_vibrant"
android:layout_marginTop="5dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/darker_gray"
android:text="#000000"
/>
-->
</LinearLayout>
<LinearLayout
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/light_vibrant_image_view"
android:layout_marginTop="10dp"
tools:ignore="InefficientWeight"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:scaleType="fitXY"
app:elevation="5dp"
app:shapeAppearance="@style/ShapeAppearanceColorPallate"
app:strokeColor="@color/colorPaletteBorder"
app:strokeWidth="1dp" />
<TextView
android:layout_marginTop="5dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:text="@string/light_vibrant_color_label"
/>
</LinearLayout>
<LinearLayout
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/dark_vibrant_image_view"
android:layout_marginTop="10dp"
tools:ignore="InefficientWeight"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:scaleType="fitXY"
app:elevation="5dp"
app:shapeAppearance="@style/ShapeAppearanceColorPallate"
app:strokeColor="@color/colorPaletteBorder"
app:strokeWidth="1dp" />
<TextView
android:layout_marginTop="5dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:text="@string/dark_vibrant_color_label"
/>
</LinearLayout>
<LinearLayout
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/muted_image_view"
android:layout_marginTop="10dp"
tools:ignore="InefficientWeight"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:scaleType="fitXY"
app:elevation="5dp"
app:shapeAppearance="@style/ShapeAppearanceColorPallate"
app:strokeColor="@color/colorPaletteBorder"
app:strokeWidth="1dp" />
<TextView
android:layout_marginTop="5dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:text="@string/muted_color_label"
/>
</LinearLayout>
<LinearLayout
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/light_muted_image_view"
android:layout_marginTop="10dp"
tools:ignore="InefficientWeight"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:scaleType="fitXY"
app:elevation="5dp"
app:shapeAppearance="@style/ShapeAppearanceColorPallate"
app:strokeColor="@color/colorPaletteBorder"
app:strokeWidth="1dp" />
<TextView
android:layout_marginTop="5dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:text="@string/light_muted_color_label"
/>
</LinearLayout>
<LinearLayout
android:layout_margin="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<com.google.android.material.imageview.ShapeableImageView
android:id="@+id/dark_muted_image_view"
android:layout_marginTop="10dp"
tools:ignore="InefficientWeight"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_weight="1"
android:adjustViewBounds="true"
android:scaleType="fitXY"
app:elevation="5dp"
app:shapeAppearance="@style/ShapeAppearanceColorPallate"
app:strokeColor="@color/colorPaletteBorder"
app:strokeWidth="1dp" />
<TextView
android:layout_marginTop="5dp"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="@android:color/black"
android:text="@string/dark_muted_color_label"
/>
</LinearLayout>
</GridLayout>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
package com.boltuix.colorpalette
import android.graphics.BitmapFactory
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.annotation.DrawableRes
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.palette.graphics.Palette
import com.boltuix.colorpalette.databinding.FragmentColorPaletteBinding
import com.google.android.material.imageview.ShapeableImageView
class ColorPaletteFragment : Fragment() {
private var _binding: FragmentColorPaletteBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
private val defaultColor: Int get() = ContextCompat.getColor(
requireContext(),
R.color.colorPrimary
)
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentColorPaletteBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val bitmap = BitmapFactory.decodeResource(resources, R.drawable.sample2)
val palette = PaletteUtils.createPaletteSync(bitmap)
binding.colorExtractionTargetImageView.apply {
setImageBitmap(bitmap)
}
setVibrantPalette(view, palette)
setMutedPalette(view, palette)
}
private fun setMutedPalette(view: View, palette: Palette) {
binding.mutedImageView.apply {
val color = palette.getMutedColor(defaultColor)
setBackgroundColor(color)
val psVibrant: Palette.Swatch = palette.vibrantSwatch!!
val color1: Int = psVibrant.rgb
val population: Int = psVibrant.population
val hsl: FloatArray = psVibrant.hsl
val bodyTextColor: Int = psVibrant.bodyTextColor
val titleTextColor: Int = psVibrant.titleTextColor
Log.d("color1","psVibrant:"+psVibrant)
Log.d("color1","color1:"+color1)
Log.d("color1","population:"+population)
Log.d("color1","hsl:"+hsl)
Log.d("color1","bodyTextColor:"+bodyTextColor)
Log.d("color1","titleTextColor:"+titleTextColor)
}
view.findViewById<ShapeableImageView>(R.id.light_muted_image_view).apply {
val color = palette.getLightMutedColor(defaultColor)
setBackgroundColor(color)
}
view.findViewById<ShapeableImageView>(R.id.dark_muted_image_view).apply {
val color = palette.getDarkMutedColor(defaultColor)
setBackgroundColor(color)
}
}
private fun setVibrantPalette(view: View, palette: Palette) {
view.findViewById<ShapeableImageView>(R.id.vibrant_image_view).apply {
val color = palette.getVibrantColor(defaultColor)
setBackgroundColor(color)
}
view.findViewById<ShapeableImageView>(R.id.light_vibrant_image_view).apply {
val color = palette.getLightVibrantColor(defaultColor)
setBackgroundColor(color)
}
view.findViewById<ShapeableImageView>(R.id.dark_vibrant_image_view).apply {
val color = palette.getDarkVibrantColor(defaultColor)
setBackgroundColor(color)
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
PaletteUtils.kt
//https://developer.android.com/develop/ui/views/graphics/palette-colors
object PaletteUtils {
fun createPaletteSync(bitmap: Bitmap): Palette = Palette.from(bitmap).generate()
}
Comments
Post a Comment