directory

  • Hello,Jetpack Compose!
  • Jetpack Compose(2) : Layout
  • Jetpack Compose Compose for the first time
  • First introduction to Jetpack Compose(4) : Theme

A, themes,

With Jetpack Compose, you can easily give your applications a consistent look and feel through application themes. You can customize Compose’s Material Design implementation to fit the brand of your product. If that doesn’t meet your needs, you can use Compose’s public API to build a custom design system.

When we create a Compose application with Android Studio, by default we create a UI. Theme package that contains color. kt, shape. kt, theme. kt, and type. kt, which happens to be the subject of this article. Let’s look at the code below:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?). {
        super.onCreate(savedInstanceState)
        setContent {
            ComposeTheme {
                    MainPage()
            }
        }
    }
}
Copy the code

The structure of an automatically generated MainActivity looks something like this, so what is this ComposeTheme? Let’s click inside and have a look:

// Dark theme color
private val DarkColorPalette = darkColors()
// Light theme colors
private val LightColorPalette = lightColors()

@Composable
fun ComposeTheme(
    darkTheme: Boolean = isSystemInDarkTheme(),
    content: @Composable()() - >Unit
) {
    // Specify the colors value according to the system theme mode
    val colors = if (darkTheme) {
        DarkColorPalette
    } else {
        LightColorPalette
    }
    // Declare the subject
    MaterialTheme(
        colors = colors,
        typography = Typography,
        shapes = Shapes,
        content = content
    )
}
Copy the code

Clearly, in the Theme. Kt mentioned above, Android Studio has generated themes that can switch between regular and dark mode for the system. The MaterialTheme is an officially provided theme implementation consisting of color, typography, and shape properties. The theme mode switch in the code above deals only with colors.

1. Colors

So what are the DarkColorPalette and the LightColorPalette?

// Dark theme color
private val DarkColorPalette = darkColors()
// Light theme colors
private val LightColorPalette = lightColors()
Copy the code

Continue with darkColors() and lightColors(), using the lightColors() source code as an example:

fun lightColors(
    primary: Color = Color(0xFF6200EE),
    primaryVariant: Color = Color(0xFF3700B3),
    secondary: Color = Color(0xFF03DAC6),
    secondaryVariant: Color = Color(0xFF018786),
    background: Color = Color.White,
    surface: Color = Color.White,
    error: Color = Color(0xFFB00020),
    onPrimary: Color = Color.White,
    onSecondary: Color = Color.Black,
    onBackground: Color = Color.Black,
    onSurface: Color = Color.Black,
    onError: Color = Color.White
): Colors = Colors(
    primary,
    primaryVariant,
    secondary,
    secondaryVariant,
    background,
    surface,
    error,
    onPrimary,
    onSecondary,
    onBackground,
    onSurface,
    onError,
    true
)
Copy the code

They both inherit from Colors, and have a default value assigned to the color attribute of whatever Colors Colors are in the entry. The bottom line is that Compose provides us with two Colors configurations by default, light mode and dark mode. Normally, we just need to change the color properties of the different modes to the desired color.

Compose Colors only provides 12 Colors, which is not enough or the description is not clear enough. This is where Kotlin’s syntactic sugar comes in handy. We can define the desired color attributes by adding an extension attribute to Colors, such as:

val White = Color(0xFFFFFFFF)
val Black = Color(0xFF000000)
val Colors.Divider: Color
    @Composable get() = if (isLight) Black else White
    
    
// Then you can use it happily
Text(text = "RoundButton",color = MaterialTheme.colors.Divider)
Copy the code

1.1. It is worth mentioning

Although Material is our recommended design system and Jetpack Compose comes with an implementation of Material, you don’t have to use it. You can create your own design system in the same way; Material is entirely based on public apis that you can use for this purpose.

Although the official implementation of Material is included, it is limited to switching between light and dark modes, and various themes need to be customized through Material.

2. Typography

Let’s look at the official description

Compose uses Typography, TextStyle, and typeage-related classes to implement a type system. The Typography constructor can provide default values for each style

Typography is used for unified management and control of font size, style and other properties. Officially, we have defined several properties and given default values:

@Immutable
class Typography internal constructor(
    val h1: TextStyle,
    val h2: TextStyle,
    val h3: TextStyle,
    val h4: TextStyle,
    val h5: TextStyle,
    val h6: TextStyle,
    val subtitle1: TextStyle,
    val subtitle2: TextStyle,
    val body1: TextStyle,
    val body2: TextStyle,
    val button: TextStyle,
    val caption: TextStyle,
    val overline: TextStyle
) {
...
}
Copy the code

TextStyle allows you to define various attributes such as font size, style, and weight:

@Immutable
class TextStyle(
    val color: Color = Color.Unspecified,
    val fontSize: TextUnit = TextUnit.Unspecified,
    val fontWeight: FontWeight? = null.val fontStyle: FontStyle? = null.val fontSynthesis: FontSynthesis? = null.val fontFamily: FontFamily? = null.val fontFeatureSettings: String? = null.val letterSpacing: TextUnit = TextUnit.Unspecified,
    val baselineShift: BaselineShift? = null.val textGeometricTransform: TextGeometricTransform? = null.val localeList: LocaleList? = null.val background: Color = Color.Unspecified,
    val textDecoration: TextDecoration? = null.val shadow: Shadow? = null.val textAlign: TextAlign? = null.val textDirection: TextDirection? = null.val lineHeight: TextUnit = TextUnit.Unspecified,
    val textIndent: TextIndent? = null
)
Copy the code

Consider the few attributes of TextStyle in XML:

Instead of using a brush to bold text for the various word weights required by the UI,Hi big rush

Also, we can define our own Typography by adding extended properties to Typography

val Typography.Title: TextStyle
    @Composable get() = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Bold,
        fontSize = 18.sp
    )

val Typography.SubText: TextStyle
    @Composable get() = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.W500,
        fontSize = 16.sp
    )
val Typography.Content: TextStyle
    @Composable get() = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Normal,
        fontSize = 16.sp
    )

val Typography.Description: TextStyle
    @Composable get() = TextStyle(
        fontFamily = FontFamily.Default,
        fontWeight = FontWeight.Normal,
        fontSize = 14.sp
    )
   
Copy the code
 // Use custom Typography properties
Column(
    Modifier
        .background(Color.White)
        .padding(20.dp)) {
    Text(text = "Title",style = MaterialTheme.typography.Title)
    Text(text = "SubText",style = MaterialTheme.typography.SubText)
    Text(text = "Content",style = MaterialTheme.typography.Content)
    Text(text = "Description",style = MaterialTheme.typography.Description)
}
Copy the code

The effect is as follows:

3. Shapes

Material defines a shape system that lets you define the shape of large, medium, and small components.

ColorsTypographyAgain, the authorities have provided us withShapesUsed to manage styles used in projects.

So let’s seeShapesSource:

@Immutable
class Shapes(
    /** * Shape used by small components like [Button] or [Snackbar]. Components like * [FloatingActionButton], [ExtendedFloatingActionButton] use this shape, but override * the corner size to be 50%. [TextField] uses this shape with overriding the bottom corners * to zero. */
    val small: CornerBasedShape = RoundedCornerShape(4.dp),
    /** * Shape used by medium components like [Card] or [AlertDialog]. */
    val medium: CornerBasedShape = RoundedCornerShape(4.dp),
    /** * Shape used by large components like [ModalDrawer] or [ModalBottomSheetLayout]. */
    val large: CornerBasedShape = RoundedCornerShape(0.dp)
) {
...
}
Copy the code

As stated in the official documentation, Shapes provide large, medium and small shape configurations to provide different styles for different sizes of components within the same semantics; If large, medium, and small don’t fit your needs, you can still add extended attributes to them. I don’t think Shapes make much sense in everyday development, though. It would be nice to use Shapes directly within components when writing pages, as shown in the code below.

@Composable
fun RoundButton(a) {
    Box(
        modifier = Modifier
            .width(300.dp)
            .height(90.dp)
            .padding(20.dp)
            .background(Color(0xFF3ADF00), shape = RoundedCornerShape(50)),
       
        contentAlignment = Alignment.Center){
        Text(text = "RoundButton",color = Color.White)
    }
}
Copy the code





ComposeIn theshapeThere are four subclasses as follows:

3.1. RoundedCornerShape

And I’m going to look at it and I’m going to have a RoundedCornerShape

3.2. CutCornerShape

CutCornerShape(50)

3.3. AbsoluteRoundedCornerShape

AbsoluteRoundedCornerShape and RoundedCornerShape about, the official described as:

Describes the shape of a rectangle with rounded corners. This shape does not automatically mirror the corner size in layoutdirection. Rtl, RoundedCornerShape is used for the layoutdirectional-aware version of the shape’s layout.

3.4. AbsoluteCutCornerShape

AbsoluteCutCornerShape AbsoluteCutCornerShape AbsoluteCutCornerShape

Describes the shape of a rectangle with a cut Angle. The angular size represents the cutting length – the size of the two legs that cut the right triangle. This shape will not automatically mirror the corner size in Layoutdirection. Rtl, cutCornerCornerShape is used for the layoutdirectional-aware version of this shape.

Second, the last

A good memory is better than a bad pen. Jetpack Compose series is my own study notes for the first time, which can not only deepen the knowledge consolidation, but also exercise my writing skills. The content in this article is for reference only, if you have any questions, please leave a comment.

Reference 1.

  • Android developers