Paris vous permet de définir et d'appliquer des styles par programmation aux vues Android, y compris des attributs personnalisés.
Dans build.gradle
de votre projet :
dependencies {
implementation ' com.airbnb.android:paris:2.0.0 '
// Apply the Paris processor if you're using Paris annotations for code gen.
kapt ' com.airbnb.android:paris-processor:2.0.0 '
// or if you are using Kotlin Symbol Processing
ksp ' com.airbnb.android:paris-processor:2.0.0 '
}
Pour utiliser Paris dans un module de bibliothèque, voir Modules de bibliothèque.
myView.style( R .style. MyStyle )
Paris . style ( myView ). apply ( R . style . MyStyle );
Où myView
est une instance de vue arbitraire, MyStyle
un style défini par XML et style
une fonction d'extension fournie par Paris. De nombreux attributs, mais pas tous, sont pris en charge. Pour en savoir plus, consultez Types de vues et attributs pris en charge.
myView.style {
add( R .style. StyleA )
add( R .style. StyleB )
…
}
Paris . styleBuilder ( myView )
. add ( R . style . StyleA )
. add ( R . style . StyleB )
…
. apply ();
Dans les cas où il y a un certain chevauchement, la valeur d'attribut du dernier style ajouté prévaut. Pour en savoir plus, voir Combinaison de styles.
textView.style {
// Using an actual value.
textColor( Color . GREEN )
// Or a resource.
textSizeRes( R .dimen.my_text_size_small)
}
Paris . styleBuilder ( textView )
// Using an actual value.
. textColor ( Color . GREEN )
// Or a resource.
. textSizeRes ( R . dimen . my_text_size_small )
. apply ();
Peut également être combiné avec des ressources de style :
textView.style {
// Adds all the attributes defined in the MyGreenTextView style.
add( R .style. MyGreenTextView )
textSizeRes( R .dimen.my_text_size_small)
}
Paris . styleBuilder ( textView )
// Adds all the attributes defined in the MyGreenTextView style.
. add ( R . style . MyGreenTextView )
. textSizeRes ( R . dimen . my_text_size_small )
. apply ();
Pour en savoir plus, consultez Définition de styles par programmation.
Les attributs sont déclarés comme suit :
< declare-styleable name = " MyView " >
< attr name = " title " format = " string " />
< attr name = " image " format = " reference " />
< attr name = " imageSize " format = " dimension " />
</ declare-styleable >
La vue personnalisée est annotée avec @Styleable
et @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.
}
}
// 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.
}
}
Les méthodes @Attr
-annotées seront appelées par Paris lorsque la vue est gonflée avec un AttributeSet
ou lorsqu'un style est appliqué.
Pour en savoir plus, consultez Attributs de vue personnalisés.
Les attributs sont déclarés comme suit pour les 2 sous-vues que nous aimerions pouvoir styliser :
< declare-styleable name = " MyHeader " >
< attr name = " titleStyle " format = " reference " />
< attr name = " subtitleStyle " format = " reference " />
...
</ declare-styleable >
Les champs de la sous-vue sont annotés avec @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)
}
}
@ 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.
}
Les styles de titre et de sous-titres peuvent désormais faire partie des styles MyHeader
:
< 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)
}
}
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 ();
Attention : Les fonctions d'extension comme titleStyle
et subtitleStyle
sont générées lors de la compilation par le processeur d'annotations de Paris. Lorsque de nouvelles annotations @StyleableChild
sont ajoutées, le projet doit être (re)compilé une fois pour que les fonctions associées deviennent disponibles.
Pour en savoir plus, consultez Style des sous-vues.
@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)
}
}
}
@ 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 );
}
}
Des méthodes d'assistance sont générées pour chaque style lié :
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)
…
}
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 ();
Attention : les fonctions d'extension comme addRed
et addGreen
sont générées lors de la compilation par le processeur d'annotations Paris. Lorsque de nouvelles annotations @Style
sont ajoutées, le projet doit être (re)compilé une fois pour que les fonctions associées deviennent disponibles.
Pour en savoir plus, consultez Liaison de styles à des vues personnalisées.
Consultez des exemples et parcourez la documentation complète sur le Paris Wiki.
Si vous avez encore des questions, n'hésitez pas à créer un nouveau problème.
Nous aimons les contributions ! Consultez nos directives de contribution et assurez-vous de suivre notre code de conduite.
Copyright 2018 Airbnb, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.