ParisletsyoudefineandapplystylesprogrammaticallytoAndroidviews,includingcustomattributes.
Applystylesprogrammaticallyatanytime.Combinemultiplestylestogether.Createstylesprogrammatically(asopposedtousingXML).Useannotationstoeasilysupportcustomattributes(inspiredbyBarber).Declareexplicitlysupportedstylesforyourcustomviews.Andmuchmore...InstallationInyourproject'sbuild.gradle:
dependencies{implementation'com.airbnb.android:paris:2.0.0'//ApplytheParisprocessorifyou'reusingParisannotationsforcodegen.kapt'com.airbnb.android:paris-processor:2.0.0'//orifyouareusingKotlinSymbolProcessingksp'com.airbnb.android:paris-processor:2.0.0'}TouseParisinalibrarymoduleseeLibraryModules.
QuickStartApplyinganXML-DefinedStylemyView.style(R.style.MyStyle)ClicktoseetheexampleinJava.Paris.style(myView).apply(R.style.MyStyle);WheremyViewisanarbitraryviewinstance,MyStyleanXML-definedstyle,andstyleanextensionfunctionprovidedbyParis.Manybutnotallattributesaresupported,formoreseeSupportedViewTypesandAttributes.
Combining2orMoreStylesmyView.style{add(R.style.StyleA)add(R.style.StyleB)…}ClicktoseetheexampleinJava.Paris.styleBuilder(myView).add(R.style.StyleA).add(R.style.StyleB)….apply();Incaseswherethere'ssomeoverlaptheattributevaluefromthelaststyleaddedprevails.FormoreseeCombiningStyles.
DefiningStylesProgrammaticallytextView.style{//Usinganactualvalue.textColor(Color.GREEN)//Oraresource.textSizeRes(R.dimen.my_text_size_small)}ClicktoseetheexampleinJava.Paris.styleBuilder(textView)//Usinganactualvalue..textColor(Color.GREEN)//Oraresource..textSizeRes(R.dimen.my_text_size_small).apply();Canbecombinedwithstyleresourcesaswell:
textView.style{//AddsalltheattributesdefinedintheMyGreenTextViewstyle.add(R.style.MyGreenTextView)textSizeRes(R.dimen.my_text_size_small)}ClicktoseetheexampleinJava.Paris.styleBuilder(textView)//AddsalltheattributesdefinedintheMyGreenTextViewstyle..add(R.style.MyGreenTextView).textSizeRes(R.dimen.my_text_size_small).apply();FormoreseeDefiningStylesProgrammatically.
CustomViewAttributesAttributesaredeclaredasfollowed:
<declare-styleablename="MyView"><attrname="title"format="string"/><attrname="image"format="reference"/><attrname="imageSize"format="dimension"/></declare-styleable>Thecustomviewisannotatedwith@Styleableand@Attr:
//Thevalueherecorrespondstothenamechosenindeclare-styleable.@Styleable("MyView")classMyView(…):ViewGroup(…){init{//ThiscallenablesthecustomattributeswhenusedinXMLlayouts.It//extractsstylinginformationfromAttributeSetlikeitwouldaStyleRes.style(attrs)}@Attr(R.styleable.MyView_title)funsetTitle(title:String){//Automaticallycalledwiththetitlevalue(ifany)whenanAttributeSet//orStyleResisappliedtotheMyViewinstance.}@Attr(R.styleable.MyView_image)funsetImage(image:Drawable?){//Automaticallycalledwiththeimagevalue(ifany)whenanAttributeSet//orStyleResisappliedtotheMyViewinstance.}@Attr(R.styleable.MyView_imageSize)funsetImageSize(@PximageSize:Int){//AutomaticallycalledwiththeimageSizevalue(ifany)whenan//AttributeSetorStyleResisappliedtotheMyViewinstance.}}ClicktoseetheexampleinJava.//Thevalueherecorrespondstothenamechosenindeclare-styleable.@Styleable("MyView")publicclassMyViewextendsViewGroup{publicMyView(Contextcontext){super(context);}publicMyView(Contextcontext,AttributeSetattrs){this(context,attrs,0);}publicMyView(Contextcontext,AttributeSetattrs,intdefStyle){this(context,attrs,defStyle);//ThiscallenablesthecustomattributeswhenusedinXMLlayouts.It//extractsstylinginformationfromAttributeSetlikeitwouldaStyleRes.Paris.style(this).apply(attrs);}@Attr(R.styleable.MyView_title)publicvoidsetTitle(Stringtitle){//Automaticallycalledwiththetitlevalue(ifany)whenanAttributeSet//orStyleResisappliedtotheMyViewinstance.}@Attr(R.styleable.MyView_image)publicvoidsetImage(Drawableimage){//Automaticallycalledwiththeimagevalue(ifany)whenanAttributeSet//orStyleResisappliedtotheMyViewinstance.}@Attr(R.styleable.MyView_imageSize)publicvoidsetImageSize(@PxintimageSize){//AutomaticallycalledwiththeimageSizevalue(ifany)whenan//AttributeSetorStyleResisappliedtotheMyViewinstance.}}The@Attr-annotatedmethodswillbecalledbyPariswhentheviewisinflatedwithanAttributeSetorwhenastyleisapplied.
FormoreseeCustomViewAttributes.
StylingSubviewsAttributesaredeclaredasfollowedforthe2subviewswe'dliketobeabletostyle:
<declare-styleablename="MyHeader"><attrname="titleStyle"format="reference"/><attrname="subtitleStyle"format="reference"/>...</declare-styleable>Thesubviewfieldsareannotatedwith@StyleableChild:
@Styleable("MyHeader")classMyHeader(…):ViewGroup(…){@StyleableChild(R.styleable.MyHeader_titleStyle)internalvaltitle:TextView…@StyleableChild(R.styleable.MyHeader_subtitleStyle)internalvalsubtitle:TextView…init{style(attrs)}}ClicktoseetheexampleinJava.@Styleable("MyHeader")publicclassMyHeaderextendsViewGroup{@StyleableChild(R.styleable.MyHeader_titleStyle)TextViewtitle;@StyleableChild(R.styleable.MyHeader_subtitleStyle)TextViewsubtitle;…//MakesuretocallParis.style(this).apply(attrs)duringinitialization.}ThetitleandsubtitlestylescannowbepartofMyHeaderstyles:
<MyHeader...app:titleStyle="@style/Title2"app:subtitleStyle="@style/Regular"/>myHeader.style{//DefinedinXML.titleStyle(R.style.Title2)//Definedprogrammatically.subtitleStyle{textColorRes(R.color.text_color_regular)textSizeRes(R.dimen.text_size_regular)}}ClicktoseetheexampleinJava.Paris.styleBuilder(myHeader)//DefinedinXML..titleStyle(R.style.Title2)//Definedprogrammatically..subtitleStyle((builder)->builder.textColorRes(R.color.text_color_regular).textSizeRes(R.dimen.text_size_regular)).apply();Attention:ExtensionfunctionsliketitleStyleandsubtitleStylearegeneratedduringcompilationbytheParisannotationprocessor.Whennew@StyleableChildannotationsareadded,theprojectmustbe(re)compiledoncefortherelatedfunctionstobecomeavailable.
FormoreseeStylingSubviews.
LinkingStylestoViews@StyleableclassMyView(…):View(…){companionobject{//ForstylesdefinedinXML.@StylevalRED_STYLE=R.style.MyView_Red//Forstylesdefinedprogrammatically.@StylevalGREEN_STYLE=myViewStyle{background(R.color.green)}}}ClicktoseetheexampleinJava.@StyleablepublicclassMyViewextendsView{//ForstylesdefinedinXML.@StylestaticfinalintRED_STYLE=R.style.MyView_Red;//Forstylesdefinedprogrammatically.@StylestaticvoidgreenStyle(MyViewStyleApplier.StyleBuilderbuilder){builder.background(R.color.green);}}Helpermethodsaregeneratedforeachlinkedstyle:
myView.style{addRed()}//Equivalenttostyle(R.style.MyView_Red)myView.style{addGreen()}//Equivalenttoadd(MyView.GREEN_STYLE)myView.style{addRed()//Equivalenttoadd(R.style.MyView_Red)addGreen()//Equivalenttoadd(MyView.GREEN_STYLE)…}ClicktoseetheexampleinJava.Paris.style(myView).applyRed();//Equivalenttoapply(R.style.MyView_Red)Paris.style(myView).applyGreen();//Noequivalent.Paris.styleBuilder(myView).addRed()//Equivalenttoadd(R.style.MyView_Red).addGreen()//Noequivalent.….apply();Attention:ExtensionfunctionslikeaddRedandaddGreenaregeneratedduringcompilationbytheParisannotationprocessor.Whennew@Styleannotationsareadded,theprojectmustbe(re)compiledoncefortherelatedfunctionstobecomeavailable.
FormoreseeLinkingStylestoCustomViews.
DocumentationSeeexamplesandbrowsecompletedocumentationattheParisWiki.
Ifyoustillhavequestions,feelfreetocreateanewissue.
ContributingWelovecontributions!Checkoutourcontributingguidelinesandbesuretofollowourcodeofconduct.
LicenseCopyright2018Airbnb,Inc.LicensedundertheApacheLicense,Version2.0(the"License");youmaynotusethisfileexceptincompliancewiththeLicense.YoumayobtainacopyoftheLicenseathttps://www.apache.org/licenses/LICENSE-2.0Unlessrequiredbyapplicablelaworagreedtoinwriting,softwaredistributedundertheLicenseisdistributedonan"ASIS"BASIS,WITHOUTWARRANTIESORCONDITIONSOFANYKIND,eitherexpressorimplied.SeetheLicenseforthespecificlanguagegoverningpermissionsandlimitationsundertheLicense.
评论