All Projects → airbnb → Paris

airbnb / Paris

Licence: apache-2.0
Define and apply styles to Android views programmatically

Programming Languages

kotlin
9241 projects
java
68154 projects - #9 most used programming language
ruby
36898 projects - #4 most used programming language

Projects that are alternatives of or similar to Paris

Xui
💍A simple and elegant Android native UI framework, free your hands! (一个简洁而优雅的Android原生UI框架,解放你的双手!)
Stars: ✭ 3,571 (+108.1%)
Mutual labels:  styles, android-ui
Figma Theme
Generate development-ready theme JSON files from Figma Styles
Stars: ✭ 130 (-92.42%)
Mutual labels:  design-systems, styles
Androidrate
AndroidRate is a library to help you promote your Android app by prompting users to rate the app after using it for a few days.
Stars: ✭ 117 (-93.18%)
Mutual labels:  android-ui
Tachyons
Functional css for humans
Stars: ✭ 11,057 (+544.35%)
Mutual labels:  design-systems
Zoomabletextureview
Adding zoom and scroll gestures to video playback on Android
Stars: ✭ 122 (-92.89%)
Mutual labels:  android-ui
Vue Cion Design System
CION - Design system boilerplate for Vue.js
Stars: ✭ 119 (-93.07%)
Mutual labels:  design-systems
Fancyshowcaseview
An easy-to-use customisable show case view with circular reveal animation.
Stars: ✭ 1,662 (-3.15%)
Mutual labels:  android-ui
Css
The CSS design system that powers GitHub
Stars: ✭ 10,670 (+521.79%)
Mutual labels:  design-systems
React
Modern and minimalist React UI library.
Stars: ✭ 2,546 (+48.37%)
Mutual labels:  design-systems
Styled By
Simple and powerful lib to handle styled props in your components
Stars: ✭ 122 (-92.89%)
Mutual labels:  styles
Ui Ux
📝 Curated list for UI/UX Designers
Stars: ✭ 125 (-92.72%)
Mutual labels:  design-systems
Patternlab Edition Node Webpack
The webpack wrapper around patternlab-node core, providing tasks to interact with the core library and move supporting frontend assets.
Stars: ✭ 122 (-92.89%)
Mutual labels:  design-systems
Anychart Android
AnyChart Android Chart is an amazing data visualization library for easily creating interactive charts in Android apps. It runs on API 19+ (Android 4.4) and features dozens of built-in chart types.
Stars: ✭ 1,762 (+2.68%)
Mutual labels:  android-ui
Style Dictionary
A build system for creating cross-platform styles.
Stars: ✭ 2,097 (+22.2%)
Mutual labels:  design-systems
Vectorifydahome
📱 Minimal app to apply wallpapers from a vast (400+) collection of vector graphics 🙃
Stars: ✭ 119 (-93.07%)
Mutual labels:  android-ui
Evergreen
🌲 Evergreen React UI Framework by Segment
Stars: ✭ 11,340 (+560.84%)
Mutual labels:  design-systems
Truffle Shuffle
An Android data-driven, percentage-based UI Card Gallery Library
Stars: ✭ 117 (-93.18%)
Mutual labels:  android-ui
Easyadapter
Recyclerview adapter library- Create adapter in just 3 lines of code
Stars: ✭ 122 (-92.89%)
Mutual labels:  android-ui
Carouselrecyclerview
Carousel Recyclerview let's you create carousel layout with the power of recyclerview by creating custom layout manager.
Stars: ✭ 107 (-93.76%)
Mutual labels:  android-ui
Skin
Pure CSS framework designed & developed by eBay for a branded, e-commerce marketplace.
Stars: ✭ 126 (-92.66%)
Mutual labels:  styles

Paris

Paris lets you define and apply styles programmatically to Android views, including custom attributes.

  • Apply styles programmatically at any time.
  • Combine multiple styles together.
  • Create styles programmatically (as opposed to using XML).
  • Use annotations to easily support custom attributes (inspired by Barber).
  • Declare explicitly supported styles for your custom views.
  • And much more...

Installation

In your project's build.gradle:

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'
}

To use Paris in a library module see Library Modules.

Quick Start

Applying an XML-Defined Style

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, MyStyle an XML-defined style, and style an extension function provided by Paris. Many but not all attributes are supported, for more see Supported View Types and Attributes.

Combining 2 or More Styles

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.

Defining Styles Programmatically

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.

Custom View Attributes

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.

Styling Subviews

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: TextViewinit {
        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();

Attention: Extension functions like titleStyle and subtitleStyle are generated during compilation by the Paris annotation processor. When new @StyleableChild annotations are added, the project must be (re)compiled once for the related functions to become available.

For more see Styling Subviews.

Linking Styles to Views

@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();

Attention: Extension functions like addRed and addGreen are generated during compilation by the Paris annotation processor. When new @Style annotations are added, the project must be (re)compiled once for the related functions to become available.

For more see Linking Styles to Custom Views.

Documentation

See examples and browse complete documentation at the Paris Wiki.

If you still have questions, feel free to create a new issue.

Contributing

We love contributions! Check out our contributing guidelines and be sure to follow our code of conduct.

License

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.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].