Android custom attr color

Android styling: common theme attributes

In the previous article in this series on Android styling, we looked at the difference between themes and styles and how themes allow you to write more flexible styles and layouts which isolate changes:

Android Styling: Themes vs Styles

The Android styling system offers a powerful way to specify your app’s visual design, but it can be easy to misuse…

Specifically we recommended using theme attributes to provide a point of indirection to resources, so that you can vary them (e.g. in dark theme). That is, if you find yourself writing a direct resource reference (or worse yet, a hardcoded value 😱) in a layout or style, consider if you should use a theme attribute instead.

But what theme attributes are available to use? This post highlights the common ones that you should know about; those that come from Material, AppCompat or the platform. This is not a complete list (for that I’d recommend browsing the attrs files linked below where they are defined) but these are the attributes that I use all the time.

Colors

Many of these colors come from the Material color system, which defines semantic names for colors that you can use throughout your app (implemented as theme attrs).

  • ?attr/colorPrimary The primary branding color for the app.
  • ?attr/colorSecondary The secondary branding color for the app, usually a bright complement to the primary branding color.
  • ?attr/colorOn[Primary, Secondary, Surface etc] A color which contrasts against the named color.
  • ?attr/color[Primary, Secondary]Variant An alternate shade of the given color.
  • ?attr/colorSurface A color for surfaces of components, such as cards, sheets, and menus.
  • ?android:attr/colorBackground The background for the screen.
  • ?attr/colorPrimarySurface switches between colorPrimary in the Light themes, colorSurface in the Dark theme.
  • ?attr/colorError A color for displaying errors.

Other handy colors:

  • ?attr/colorControlNormal The color applied to icons/controls in their normal state.
  • ?attr/colorControlActivated The color applied to icons/controls in their activated state (e.g. checked).
  • ?attr/colorControlHighlight The color applied to control highlights (e.g. ripples, list selectors).
  • ?android:attr/textColorPrimary The most prominent text color.
  • ?android:attr/textColorSecondary Secondary text color.

Dimens

  • ?attr/listPreferredItemHeight Standard (min) height for list items.
  • ?attr/actionBarSize The height of a toolbar.

Drawables

  • ?attr/selectableItemBackground A ripple/highlight for interactive items (also handy for foregrounds!!)
  • ?attr/selectableItemBackgroundBorderless An unbounded ripple.
  • ?attr/dividerVertical A drawable that may be used as a vertical divider between visual elements.
  • ?attr/dividerHorizontal A drawable that may be used as a horizontal divider between visual elements.

TextAppearances

Material defines a type scale — a discrete set of text styles that you should use throughout your app, each of which is provided as a theme attribute which can be set as a textAppearance . Check out the Material type scale generator to help generate a scale for different fonts.

  • ?attr/textAppearanceHeadline1 defaults to light 96sp text.
  • ?attr/textAppearanceHeadline2 defaults to light 60sp text.
  • ?attr/textAppearanceHeadline3 defaults to regular 48sp text.
  • ?attr/textAppearanceHeadline4 defaults to regular 34sp text.
  • ?attr/textAppearanceHeadline5 defaults to regular 24sp text.
  • ?attr/textAppearanceHeadline6 defaults to medium 20sp text.
  • ?attr/textAppearanceSubtitle1 defaults to regular 16sp text.
  • ?attr/textAppearanceSubtitle2 defaults to medium 14sp text.
  • ?attr/textAppearanceBody1 defaults to regular 16sp text.
  • ?attr/textAppearanceBody2 defaults to regular 14sp text.
  • ?attr/textAppearanceCaption defaults to regular 12sp text.
  • ?attr/textAppearanceButton defaults to medium all caps 14sp text.
  • ?attr/textAppearanceOverline defaults to regular all caps 10sp text.
Читайте также:  Соединение ноутбука с андроидом что это

Shape

Material employs a shape system which is implemented as theme attrs for small, medium and large components. Note that if you’re setting a shape appearance on a custom component, you likely want to use a MaterialShapeDrawable as it’s background which understands and implements the shaping.

  • ?attr/shapeAppearanceSmallComponent used for Buttons, Chips, Text Fields etc. Defaults to rounded 4dp corners.
  • ?attr/shapeAppearanceMediumComponent used for Cards, Dialogs, Date Pickers etc. Defaults to rounded 4dp corners.
  • ?attr/shapeAppearanceLargeComponent used for Bottom Sheets etc. Defaults to rounded 0dp corners (i.e. square!)

Button Styles

This might seem super specific, but Material defines three types of buttons: Contained, Text and Outlined. MDC offers theme attrs that you can use to set the style of a MaterialButton :

  • ?attr/materialButtonStyle defaults to contained (or just omit the style).
  • ?attr/borderlessButtonStyle for a text style button.
  • ?attr/materialButtonOutlinedStyle for outlined style.

Floats

  • ?android:attr/disabledAlpha Default disabled alpha for widgets.
  • ?android:attr/primaryContentAlpha The alpha applied to the foreground elements.
  • ?android:attr/secondaryContentAlpha The alpha applied to secondary elements.

App vs Android namespace

You might have noticed that some attributes are referenced by
? android:attr/foo and others just by ?attr/bar . This is because some are defined by the Android platform, and as such you need the android part to reference them by their namespace (just like with view attributes in layouts: android:id ). Those without come from static libraries (i.e. AppCompat or MDC) which are compiled into your application, so don’t need the namespace (similar to how you might use app:baz in a layout). Some elements are defined both in the platform and in a library e.g. colorPrimary . In these cases, prefer the non-platform version, as this can be used on all API levels i.e. they’re duplicated in a library precisely to backport them. In these cases, I’ve listed the non-platform versions above.

prefer non-platform attributes which can be used on all API levels

More Resources

For a complete list of the theme attributes available to use, go to the source of truth:

Material Design Components:

Do It Yourself

Sometimes there isn’t a theme attribute which abstracts something you’d like to vary by theme. No worries… create your own! Here’s an example from the Google I/O app which shows a list of conference sessions in two screens.

They’re largely similar but the left screen must leave space for the sticky time headers while the right screen does not. We implemented this by abstracting where to align items behind a theme attribute so that we can vary them by theme and use the same layout across two different screens:

1. Define the theme attribute in attrs.xml

2. Provide different values in different themes:

3. Use the theme attr in the single layout used on both screens (each using one of the above themes):

Читайте также:  Плеймаркет для андроид регистрация

Question (mark) everything

Knowing what theme attributes are available, equips you to use them when writing your layouts, styles or drawables. Using theme attributes makes it much easier to support theming (like dark theme) and to write more flexible, maintainable code. For a deep dive on this, join us in our next post in this series:

Источник

Custom attr get color returns invalid values

I have a custom view in which i want to set the color of a textview.

I set it in the layout file

And in my code I set it

But color keeps returning -1. I also tried to set color to #000 When i do that i get a value of -16777216

I also tried a.getInteger and a.getInt

Anyone experience with this problem or suggestions?

Solution, thanks to Alex Fu

getColor cannot handle references

It is working now with

3 Answers 3

You are using a reference to a color in your example, however according to your attrs.xml file, that property must be of a color type, not a reference. This is probably the reason why when you used a hex color code it worked, but using a reference returned -1.

If you do change the format to a reference, you should also change the method to retrieve it from a.getColor() to a.getColorStateList() .

The is some sort of bug with attrs .

The following works perfectly.

attrs.xml

YourView.java

Usage

If you want every types of color to work

  • hex: #ff0000
  • color resource: @color/primary
  • color selector: @color/primaryWithStates

You need to define your property as both color and reference

Then you simply access the value using getColorStateList

For advanced needs where you want to digest the ColorStateList yourself

  • In the first 2 cases you can access the color using colors.defaultColor
  • If you used a selector you have to call the method getColorForState

So, the easiest way to extract the color is by doing

It returns the color if there is one for the current state, otherwise the default one

Attention: getColorForState should be placed in the drawableStateChanged() method to be notified every time the state changes

Источник

Defining custom attrs

I need to implement my own attributes like in com.android.R.attr

Found nothing in official documentation so I need information about how to define these attrs and how to use them from my code.

5 Answers 5

Currently the best documentation is the source. You can take a look at it here (attrs.xml).

You can define attributes in the top element or inside of a element. If I’m going to use an attr in more than one place I put it in the root element. Note, all attributes share the same global namespace. That means that even if you create a new attribute inside of a element it can be used outside of it and you cannot create another attribute with the same name of a different type.

  • reference — if it references another resource id (e.g, «@color/my_color», «@layout/my_layout»)
  • color
  • boolean
  • dimension
  • float
  • integer
  • string
  • fraction
  • enum — normally implicitly defined
  • flag — normally implicitly defined

You can set the format to multiple types by using | , e.g., format=»reference|color» .

Читайте также:  Кнопочный андроид с фронтальной камерой

enum attributes can be defined as follows:

flag attributes are similar except the values need to be defined so they can be bit ored together:

An example of a custom view :

When defining your custom attributes in XML on your custom view you need to do a few things. First you must declare a namespace to find your attributes. You do this on the root layout element. Normally there is only xmlns:android=»http://schemas.android.com/apk/res/android» . You must now also add xmlns:whatever=»http://schemas.android.com/apk/res-auto» .

Finally, to access that custom attribute you normally do so in the constructor of your custom view as follows.

Qberticus’s answer is good, but one useful detail is missing. If you are implementing these in a library replace:

Otherwise the application that uses the library will have runtime errors.

The answer above covers everything in great detail, apart from a couple of things.

First, if there are no styles, then the (Context context, AttributeSet attrs) method signature will be used to instantiate the preference. In this case just use context.obtainStyledAttributes(attrs, R.styleable.MyCustomView) to get the TypedArray.

Secondly it does not cover how to deal with plaurals resources (quantity strings). These cannot be dealt with using TypedArray. Here is a code snippet from my SeekBarPreference that sets the summary of the preference formatting its value according to the value of the preference. If the xml for the preference sets android:summary to a text string or a string resouce the value of the preference is formatted into the string (it should have %d in it, to pick up the value). If android:summary is set to a plaurals resource, then that is used to format the result.

  • This is just given as an example, however, if you want are tempted to set the summary on the preference screen, then you need to call notifyChanged() in the preference’s onDialogClosed method.

The traditional approach is full of boilerplate code and clumsy resource handling. That’s why I made the Spyglass framework. To demonstrate how it works, here’s an example showing how to make a custom view that displays a String title.

Step 1: Create a custom view class.

Step 2: Define a string attribute in the values/attrs.xml resource file:

Step 3: Apply the @StringHandler annotation to the setTitle method to tell the Spyglass framework to route the attribute value to this method when the view is inflated.

Now that your class has a Spyglass annotation, the Spyglass framework will detect it at compile-time and automatically generate the CustomView_SpyglassCompanion class.

Step 4: Use the generated class in the custom view’s init method:

That’s it. Now when you instantiate the class from XML, the Spyglass companion interprets the attributes and makes the required method call. For example, if we inflate the following layout then setTitle will be called with «Hello, World!» as the argument.

The framework isn’t limited to string resources has lots of different annotations for handling other resource types. It also has annotations for defining default values and for passing in placeholder values if your methods have multiple parameters.

Have a look at the Github repo for more information and examples.

Источник

Оцените статью