This repository was archived by the owner on Mar 30, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathREADME.md.template
195 lines (141 loc) · 7.18 KB
/
README.md.template
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
[](https://travis-ci.org/hzsweers/barber) [](http://android-arsenal.com/details/1/1612) [](http://search.maven.org/#browse%7C-504042670)
Barber
======
Barber is your personal custom view stylist.
* Simply annotate your fields using the `@StyledAttr` or `@AndroidAttr` annotations
* Call the appropriate `Barber.style(this...)` variant
* Let `Barber` take care of all the boilerplate for you.
* Profit
This library is heavily influenced by Jake Wharton's [Butter Knife](https://github.com/JakeWharton/butterknife) library, and was actually [suggested to me](http://www.reddit.com/r/androiddev/comments/2ue4rm/i_want_to_learn_annotation_processing_but_cant/co7n093?context=3) by the man himself.
Usage
-----
Barber has two main annotations that you use: `@StyledAttr` and `@AndroidAttr`. These can be used on fields or methods (e.g. setters). `StyledAttr` is used for retrieving custom attrs for custom views. `@AndroidAttr` is used for retrieving values for attributes in the android namespace.
The Barber class has 3 overloaded `style()` methods, so you can call the appropriate one from whichever constructor you prefer.
Annotated fields or methods *cannot* be private, and must at least be package accessible. This is because Barber will generate a `**$$Barbershop` class in the same package as the target class.
#### StyledAttr
Declare your styled attributes in your `attrs.xml`, like you normally would. For example:
```xml
<declare-styleable name="BarberView">
<attr name="stripeColor" format="color" />
<attr name="stripeCount" format="integer" />
<attr name="animated" format="boolean" />
<attr name="toggleAnimation" format="reference" />
</declare-styleable>
```
```java
public class BarberView extends FrameLayout {
@StyledAttr(value = R.styleable.BarberView_stripeColor, kind = Kind.COLOR)
public int stripeColor;
@StyledAttr(R.styleable.BarberView_stripeCount)
public int stripeCount;
@StyledAttr(value = R.styleable.BarberView_animated, defaultValue = R.bool.animated_default)
public boolean isAnimated;
public BarberView(Context context) {
super(context);
}
public BarberView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public BarberView(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public BarberView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
Barber.style(this, attrs, R.styleable.BarberView, defStyleAttr, defStyleRes);
}
@StyledAttr(R.styleable.BarberView_toggleAnimation)
public void setToggleAnimationDrawable(Drawable toggleAnimation) {
// Do something with it
}
}
```
By default, Barber will resolve which `TypedArray` method to use based on the type of the target. That is, if you declare it on an `int`, then Barber will generate code that calls `typedArray.getInt(...)`.
```java
@StyledAttr(R.styleable.BarberView_stripeCount)
public int stripeCount;
```
**"But wait, sometimes my int is a color!".**
If you have a special case, such as colors, then you can specify the `kind` member of the annotation with the appropriate `Kind` enum to let Barber know.
```java
@StyledAttr(value = R.styleable.BarberView_stripeColor, kind = Kind.COLOR)
public int stripeColor;
```
The color example above tells Barber it should use `TypedArray`'s `getColor(...)` method. This works for other types as well!
```java
@StyledAttr(value = R.styleable.TestView_testDimension, kind = Kind.DIMEN)
public float testDimension;
@StyledAttr(value = R.styleable.TestView_testDimensionPixelSize, kind = Kind.DIMEN_PIXEL_SIZE)
public int testDimensionPixelSize;
```
And, if you're one of the 10 people that use fraction attributes, you'll be happy to know that those are supported as well.
```java
@StyledAttr(
value = R.styleable.TestView_testFractionBase,
kind = Kind.FRACTION,
base = 2,
pbase = 2
)
public float testFractionBase;
```
See the [Kind enum](https://github.com/hzsweers/barber/blob/master/api/src/main/java/io/sweers/barber/Kind.java) for a full list of supported types.
**Default values**
You can specify resource IDs for default values.
```java
@StyledAttr(value = R.styleable.BarberView_animated, defaultValue = R.bool.animated_default)
public boolean isAnimated;
```
#### AndroidAttr
If you want to retrieve the value of an Android attribute, you can use `@AndroidAttr` to retrieve its value
```java
@AndroidAttr("textAllCaps")
public boolean textAllCaps;
```
Like `StyledAttr`, the normal behavior is to return the type of the field/param. These are also subject to the same approach as `@StyledAttr` regarding special return types. See the [AttrSetKind enum](https://github.com/hzsweers/barber/blob/master/api/src/main/java/io/sweers/barber/AttrSetKind.java) for a full list of supported types.
```java
@AndroidAttr(value = "textColor", kind = AttrSetKind.RESOURCE)
public int textColor;
```
Right now it's just limited to the API of `AttributeSet`, but I may look into adding a more flexible API layer on top of this for coercing the returned data if people express an interest.
Required attributes
-------------------
If you want to require an attribute to be specified, you can use the `@Required` annotation as well.
```java
@Required
@StyledAttr(R.styleable.RequiredTestView_requiredString)
public String requiredString;
```
Now, if a view is inflated without specifying this attribute, its generated `$$Barbershop` class will throw an IllegalStateException looking like this:
`Missing required attribute 'requiredString' while styling 'io.sweers.barber.sample.testing.RequiredTestView'`
**NOTE:** Due to how `AttributeSet`'s interface works, `@Required` is not compatible with `@AndroidAttr` annotations.
Installation
------------
```groovy
buildscript {
repositories {
jcenter() // Also available in maven central
}
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
apply plugin: 'com.neenbedankt.android-apt'
dependencies {
apt 'io.sweers.barber:barber-compiler:%%version%%'
compile 'io.sweers.barber:barber-api:%%version%%'
}
```
Proguard
--------
If you use Proguard, [consumer proguard rules](https://github.com/hzsweers/barber/blob/master/api/consumer-proguard-rules.pro) are packaged in the `api` module AAR.
License
-------
Copyright 2015 Henri Z. Sweers
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.