-
Notifications
You must be signed in to change notification settings - Fork 91
How do I...
This page answers common how-to questions that may come up when using Paris. You should read and understand the Overview and the Core documentation first.
- … extend a @Styleable class?
- … apply a style to a subview's subview?
- … add support for an Android view attribute?
Nothing tricky here, extending views annotated with @Styleable
should just work.
@Styleable("MyView")
open class MyView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {
init {
style(attrs)
}
…
}
@Styleable("MyViewExtension")
class MyViewExtension @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : MyView(context, attrs, defStyleAttr) {
init {
// Every view in the hierarchy needs to call this for itself.
style(attrs)
}
…
}
Click to see the example in Java.
@Styleable("MyView")
public class MyView extends View {
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);
Paris.style(this).apply(attrs);
}
...
}
@Styleable("MyViewExtension")
public class MyViewExtension extends MyView {
public MyViewExtension(Context context) {
super(context);
}
public MyViewExtension(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MyViewExtension(Context context, AttributeSet attrs, int defStyle) {
this(context, attrs, defStyle);
// Every view in the hierarchy needs to call this for himself
Paris.style(this).apply(attrs);
}
...
}
Each view in the hierarchy needs to call style(attrs)
during initialization.
However when using myViewExtension.style(R.style…)
with a style resource all attributes throughout the view hierarchy will be applied (from MyViewExtension
, MyView
, and View
). Similarly when using a style builder all attribute methods throughout the view hierarchy will be available.
As we've seen, Paris generates helper methods to style annotated subviews:
@Styleable("MyView")
class MyView(…) : View(…) {
@StyleableChild(R.styleable.MyView_labelStyle)
internal val label: TextView by lazy { findViewById(R.id…) }
}
// Applying a style to a MyView instance.
myView.style(R.style…)
// Applying a style to the label.
myView.style {
labelStyle(R.style…)
}
Click to see the example in Java.
@Styleable("MyView")
public class MyView extends View {
@StyleableChild(R.styleable.MyView_labelStyle)
TextView label;
}
// Applying a style to a MyView instance.
Paris.style(myView).apply(R.style…);
// Applying a style to the label.
Paris.styleBuilder(myView)
.labelStyle(R.style…)
.apply();
But what if the subview has styleable subviews of its own? Paris lets you chain calls so you can style any annotated subview in the hierarchy:
@Styleable("MyHeader")
class MyHeader(…) : ViewGroup(…) {
@StyleableChild(R.styleable.MyHeader_myViewStyle)
internal val myView: MyView …
@StyleableChild(R.styleable.MyHeader_titleStyle)
internal val title: TextView …
}
// Applying a style to a MyHeader instance.
myHeader.style(R.style…)
// Applying a style to the MyView subview.
myHeader.style {
myViewStyle(R.style…)
}
// Applying a style to MyView's label.
myHeader.style {
myViewStyle {
labelStyle(R.style…)
}
}
Click to see the example in Java.
@Styleable("MyHeader")
public class MyHeader extends ViewGroup {
@StyleableChild(R.styleable.MyHeader_myViewStyle)
MyView myView;
@StyleableChild(R.styleable.MyHeader_titleStyle)
TextView title;
}
// Applying a style to a MyHeader instance.
Paris.style(myHeader).apply(R.style…);
// Applying a style to the MyView subview.
Paris.style(myHeader)
.myViewStyle(R.style…)
.apply();
// Applying a style to MyView's label.
Paris.style(myHeader)
.myViewStyle((builder) -> builder
.labelStyle(R.style…)
)
.apply();
Support for Android view attributes can be added using View Proxies.