-
Notifications
You must be signed in to change notification settings - Fork 91
Quick Start
myView.style(R.style.MyStyle)
Click to see the example in Java.
Paris.style(myView).apply(R.style.MyStyle);
Where myView
is an arbitrary view instance and MyStyle
an XML-defined style. Many but not all attributes are supported, for more see Supported View Types and Attributes.
myView.style {
add(R.style.StyleA)
add(R.style.StyleB)
…
}
Click to see the example in Java.
Paris.styleBuilder(myView)
.add(R.style.StyleA)
.add(R.style.StyleB)
…
.apply();
In cases where there's some overlap the attribute value from the last style added prevails. For more see Combining Styles.
textView.style {
// Using an actual value.
textColor(Color.GREEN)
// Or a resource.
textSizeRes(R.dimen.my_text_size_small)
}
Click to see the example in Java.
Paris.styleBuilder(textView)
// Using an actual value.
.textColor(Color.GREEN)
// Or a resource.
.textSizeRes(R.dimen.my_text_size_small)
.apply();
Can be combined with style resources as well:
textView.style {
// Adds all the attributes defined in the MyGreenTextView style.
add(R.style.MyGreenTextView)
textSizeRes(R.dimen.my_text_size_small)
}
Click to see the example in Java.
Paris.styleBuilder(textView)
// Adds all the attributes defined in the MyGreenTextView style.
.add(R.style.MyGreenTextView)
.textSizeRes(R.dimen.my_text_size_small)
.apply();
For more see Defining Styles Programmatically.
Attributes are declared as followed:
<declare-styleable name="MyView">
<attr name="title" format="string" />
<attr name="image" format="reference" />
<attr name="imageSize" format="dimension" />
</declare-styleable>
The custom view is annotated with @Styleable
and @Attr
:
// The value here corresponds to the name chosen in declare-styleable.
@Styleable("MyView")
class MyView(…) : ViewGroup(…) {
init {
// This call enables the custom attributes when used in XML layouts. It
// extracts styling information from AttributeSet like it would a StyleRes.
style(attrs)
}
@Attr(R.styleable.MyView_title)
fun setTitle(title: String) {
// Automatically called with the title value (if any) when an AttributeSet
// or StyleRes is applied to the MyView instance.
}
@Attr(R.styleable.MyView_image)
fun setImage(image: Drawable?) {
// Automatically called with the image value (if any) when an AttributeSet
// or StyleRes is applied to the MyView instance.
}
@Attr(R.styleable.MyView_imageSize)
fun setImageSize(@Px imageSize: Int) {
// Automatically called with the imageSize value (if any) when an
// AttributeSet or StyleRes is applied to the MyView instance.
}
}
Click to see the example in Java.
// The value here corresponds to the name chosen in declare-styleable.
@Styleable("MyView")
public class MyView extends ViewGroup {
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyView(Context context, AttributeSet attrs, int defStyle) {
this(context, attrs, defStyle);
// This call enables the custom attributes when used in XML layouts. It
// extracts styling information from AttributeSet like it would a StyleRes.
Paris.style(this).apply(attrs);
}
@Attr(R.styleable.MyView_title)
public void setTitle(String title) {
// Automatically called with the title value (if any) when an AttributeSet
// or StyleRes is applied to the MyView instance.
}
@Attr(R.styleable.MyView_image)
public void setImage(Drawable image) {
// Automatically called with the image value (if any) when an AttributeSet
// or StyleRes is applied to the MyView instance.
}
@Attr(R.styleable.MyView_imageSize)
public void setImageSize(@Px int imageSize) {
// Automatically called with the imageSize value (if any) when an
// AttributeSet or StyleRes is applied to the MyView instance.
}
}
The @Attr
-annotated methods will be called by Paris when the view is inflated with an AttributeSet
or when a style is applied.
For more see Custom View Attributes.
Attributes are declared as followed for the 2 subviews we'd like to be able to style:
<declare-styleable name="MyHeader">
<attr name="titleStyle" format="reference" />
<attr name="subtitleStyle" format="reference" />
...
</declare-styleable>
The subview fields are annotated with @StyleableChild
:
@Styleable("MyHeader")
class MyHeader(…) : ViewGroup(…) {
@StyleableChild(R.styleable.MyHeader_titleStyle)
internal val title: TextView …
@StyleableChild(R.styleable.MyHeader_subtitleStyle)
internal val subtitle: TextView …
init {
style(attrs)
}
}
Click to see the example in Java.
@Styleable("MyHeader")
public class MyHeader extends ViewGroup {
@StyleableChild(R.styleable.MyHeader_titleStyle)
TextView title;
@StyleableChild(R.styleable.MyHeader_subtitleStyle)
TextView subtitle;
…
// Make sure to call Paris.style(this).apply(attrs) during initialization.
}
The title and subtitle styles can now be part of MyHeader
styles:
<MyHeader
...
app:titleStyle="@style/Title2"
app:subtitleStyle="@style/Regular" />
myHeader.style {
// Defined in XML.
titleStyle(R.style.Title2)
// Defined programmatically.
subtitleStyle {
textColorRes(R.color.text_color_regular)
textSizeRes(R.dimen.text_size_regular)
}
}
Click to see the example in Java.
Paris.styleBuilder(myHeader)
// Defined in XML.
.titleStyle(R.style.Title2)
// Defined programmatically.
.subtitleStyle((builder) -> builder
.textColorRes(R.color.text_color_regular)
.textSizeRes(R.dimen.text_size_regular))
.apply();
For more see Styling Subviews.
@Styleable
class MyView(…) : View(…) {
companion object {
// For styles defined in XML.
@Style
val RED_STYLE = R.style.MyView_Red
// For styles defined programmatically.
@Style
val GREEN_STYLE = myViewStyle {
background(R.color.green)
}
}
}
Click to see the example in Java.
@Styleable
public class MyView extends View {
// For styles defined in XML.
@Style
static final int RED_STYLE = R.style.MyView_Red;
// For styles defined programmatically.
@Style
static void greenStyle(MyViewStyleApplier.StyleBuilder builder) {
builder.background(R.color.green);
}
}
Helper methods are generated for each linked style:
myView.style { addRed() } // Equivalent to style(R.style.MyView_Red)
myView.style { addGreen() } // Equivalent to add(MyView.GREEN_STYLE)
myView.style {
addRed() // Equivalent to add(R.style.MyView_Red)
addGreen() // Equivalent to add(MyView.GREEN_STYLE)
…
}
Click to see the example in Java.
Paris.style(myView).applyRed(); // Equivalent to apply(R.style.MyView_Red)
Paris.style(myView).applyGreen(); // No equivalent.
Paris.styleBuilder(myView)
.addRed() // Equivalent to add(R.style.MyView_Red)
.addGreen() // No equivalent.
…
.apply();
For more see Linking Styles to Custom Views.