Skip to content

Commit 1b33c32

Browse files
committed
Implementation of RobotoTextAppearanceSpan.
Close #43
1 parent 69c86b0 commit 1b33c32

18 files changed

Lines changed: 239 additions & 69 deletions
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
package com.devspark.robototextview.style;
2+
3+
import android.content.Context;
4+
import android.content.pm.PackageInfo;
5+
import android.content.pm.PackageManager;
6+
import android.content.res.ColorStateList;
7+
import android.content.res.TypedArray;
8+
import android.graphics.Typeface;
9+
import android.support.annotation.NonNull;
10+
import android.support.annotation.Nullable;
11+
import android.text.TextPaint;
12+
import android.text.style.MetricAffectingSpan;
13+
import android.util.Log;
14+
import android.util.SparseIntArray;
15+
16+
import com.devspark.robototextview.R;
17+
import com.devspark.robototextview.util.RobotoTypefaceManager;
18+
import com.devspark.robototextview.util.RobotoTypefaceUtils;
19+
20+
/**
21+
* Sets the text color, size and typeface to match a TextAppearance resource.
22+
*/
23+
public class RobotoTextAppearanceSpan extends MetricAffectingSpan {
24+
private static final int[] TEXT_ATTRS = new int[]{
25+
android.R.attr.textSize, android.R.attr.textColor, android.R.attr.textColorLink};
26+
27+
private final Typeface mTypeface;
28+
private final int mTextSize;
29+
private final ColorStateList mTextColor;
30+
private final ColorStateList mTextColorLink;
31+
32+
/**
33+
* Uses the specified TextAppearance resource to determine the
34+
* text appearance. The <code>appearance</code> should be, for example,
35+
* <code>android.R.style.TextAppearance_Small</code>.
36+
*/
37+
public RobotoTextAppearanceSpan(Context context, int appearance) {
38+
this(context, appearance, -1);
39+
}
40+
41+
/**
42+
* Uses the specified TextAppearance resource to determine the
43+
* text appearance, and the specified text color resource
44+
* to determine the color. The <code>appearance</code> should be,
45+
* for example, <code>android.R.style.TextAppearance_Small</code>,
46+
* and the <code>colorList</code> should be, for example,
47+
* <code>android.R.styleable.Theme_textColorPrimary</code>.
48+
*/
49+
public RobotoTextAppearanceSpan(Context context, int appearance, int colorList) {
50+
TypedArray a = context.obtainStyledAttributes(appearance, R.styleable.RobotoTextView);
51+
mTypeface = RobotoTypefaceUtils.typefaceFromAttrs(context, a);
52+
a.recycle();
53+
54+
ColorStateList textColor;
55+
56+
a = context.obtainStyledAttributes(appearance, TEXT_ATTRS);
57+
SparseIntArray attrsIndexes = textAttrsIndexes();
58+
59+
textColor = a.getColorStateList(attrsIndexes.get(android.R.attr.textColor));
60+
mTextColorLink = a.getColorStateList(attrsIndexes.get(android.R.attr.textColorLink));
61+
mTextSize = a.getDimensionPixelSize(attrsIndexes.get(android.R.attr.textSize), -1);
62+
63+
a.recycle();
64+
65+
if (colorList >= 0) {
66+
a = context.obtainStyledAttributes(themeResId(context), TEXT_ATTRS);
67+
textColor = a.getColorStateList(colorList);
68+
a.recycle();
69+
}
70+
71+
mTextColor = textColor;
72+
}
73+
74+
/**
75+
* Makes text be drawn with the specified typeface, size and colors.
76+
*/
77+
public RobotoTextAppearanceSpan(Context context, int typefaceId, int size,
78+
ColorStateList color, ColorStateList linkColor) {
79+
mTypeface = RobotoTypefaceManager.obtainTypeface(context, typefaceId);
80+
mTextSize = size;
81+
mTextColor = color;
82+
mTextColorLink = linkColor;
83+
}
84+
85+
private int themeResId(Context context) {
86+
try {
87+
String packageName = context.getPackageName();
88+
PackageInfo packageInfo = context.getPackageManager()
89+
.getPackageInfo(packageName, PackageManager.GET_META_DATA);
90+
return packageInfo.applicationInfo.theme;
91+
} catch (PackageManager.NameNotFoundException e) {
92+
Log.w(getClass().getSimpleName(), e);
93+
}
94+
return -1;
95+
}
96+
97+
private SparseIntArray textAttrsIndexes() {
98+
SparseIntArray indexes = new SparseIntArray(TEXT_ATTRS.length);
99+
for (int i = 0; i < TEXT_ATTRS.length; i++) {
100+
indexes.put(TEXT_ATTRS[i], i);
101+
}
102+
return indexes;
103+
}
104+
105+
/**
106+
* Returns the typeface specified by this span.
107+
*/
108+
@NonNull
109+
public Typeface getTypeface() {
110+
return mTypeface;
111+
}
112+
113+
/**
114+
* Returns the text size specified by this span, or <code>-1</code>
115+
* if it does not specify one.
116+
*/
117+
public int getTextSize() {
118+
return mTextSize;
119+
}
120+
121+
/**
122+
* Returns the text color specified by this span, or <code>null</code>
123+
* if it does not specify one.
124+
*/
125+
@Nullable
126+
public ColorStateList getTextColor() {
127+
return mTextColor;
128+
}
129+
130+
/**
131+
* Returns the link color specified by this span, or <code>null</code>
132+
* if it does not specify one.
133+
*/
134+
@Nullable
135+
public ColorStateList getLinkTextColor() {
136+
return mTextColorLink;
137+
}
138+
139+
@Override
140+
public void updateDrawState(TextPaint tp) {
141+
updateMeasureState(tp);
142+
if (mTextColor != null) {
143+
tp.setColor(mTextColor.getColorForState(tp.drawableState, 0));
144+
}
145+
if (mTextColorLink != null) {
146+
tp.linkColor = mTextColorLink.getColorForState(tp.drawableState, 0);
147+
}
148+
}
149+
150+
@Override
151+
public void updateMeasureState(TextPaint tp) {
152+
RobotoTypefaceUtils.setup(tp, mTypeface);
153+
if (mTextSize > 0) {
154+
tp.setTextSize(mTextSize);
155+
}
156+
}
157+
}

robototextview/src/main/java/com/devspark/robototextview/style/RobotoTypefaceSpan.java

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
import android.content.Context;
44
import android.graphics.Typeface;
5+
import android.support.annotation.NonNull;
56
import android.text.TextPaint;
67
import android.text.style.MetricAffectingSpan;
78

8-
import com.devspark.robototextview.util.RobotoTextViewUtils;
9+
import com.devspark.robototextview.util.RobotoTypefaceUtils;
910
import com.devspark.robototextview.util.RobotoTypefaceManager;
1011

1112
/**
@@ -52,14 +53,21 @@ public RobotoTypefaceSpan(Context context, int fontFamily, int textWeight, int t
5253
mTypeface = RobotoTypefaceManager.obtainTypeface(context, fontFamily, textWeight, textStyle);
5354
}
5455

55-
@Override
56-
public void updateDrawState(TextPaint ds) {
57-
RobotoTextViewUtils.setTypeface(ds, mTypeface);
56+
/**
57+
* Returns the typeface specified by this span.
58+
*/
59+
@NonNull
60+
public Typeface getTypeface() {
61+
return mTypeface;
5862
}
5963

6064
@Override
61-
public void updateMeasureState(TextPaint paint) {
62-
RobotoTextViewUtils.setTypeface(paint, mTypeface);
65+
public void updateDrawState(TextPaint tp) {
66+
updateMeasureState(tp);
6367
}
6468

69+
@Override
70+
public void updateMeasureState(TextPaint tp) {
71+
RobotoTypefaceUtils.setup(tp, mTypeface);
72+
}
6573
}

robototextview/src/main/java/com/devspark/robototextview/util/RobotoTextViewUtils.java renamed to robototextview/src/main/java/com/devspark/robototextview/util/RobotoTypefaceUtils.java

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
import android.content.res.TypedArray;
2121
import android.graphics.Paint;
2222
import android.graphics.Typeface;
23+
import android.support.annotation.NonNull;
24+
import android.support.annotation.Nullable;
2325
import android.util.AttributeSet;
2426
import android.widget.TextView;
2527

@@ -30,9 +32,9 @@
3032
*
3133
* @author Evgeny Shishkin
3234
*/
33-
public class RobotoTextViewUtils {
35+
public final class RobotoTypefaceUtils {
3436

35-
private RobotoTextViewUtils() {
37+
private RobotoTypefaceUtils() {
3638
}
3739

3840
/**
@@ -43,29 +45,33 @@ private RobotoTextViewUtils() {
4345
* access the current theme, resources, etc.
4446
* @param attrs The attributes of the XML tag that is inflating the widget.
4547
*/
46-
public static void initTypeface(TextView textView, Context context, AttributeSet attrs) {
48+
public static void initView(@NonNull TextView textView, @NonNull Context context, @Nullable AttributeSet attrs) {
4749
Typeface typeface;
4850

4951
if (attrs != null) {
5052
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RobotoTextView);
51-
52-
if (a.hasValue(R.styleable.RobotoTextView_typeface)) {
53-
int typefaceValue = a.getInt(R.styleable.RobotoTextView_typeface, RobotoTypefaceManager.Typeface.ROBOTO_REGULAR);
54-
typeface = RobotoTypefaceManager.obtainTypeface(context, typefaceValue);
55-
} else {
56-
int fontFamily = a.getInt(R.styleable.RobotoTextView_fontFamily, RobotoTypefaceManager.FontFamily.ROBOTO);
57-
int textWeight = a.getInt(R.styleable.RobotoTextView_textWeight, RobotoTypefaceManager.TextWeight.NORMAL);
58-
int textStyle = a.getInt(R.styleable.RobotoTextView_textStyle, RobotoTypefaceManager.TextStyle.NORMAL);
59-
60-
typeface = RobotoTypefaceManager.obtainTypeface(context, fontFamily, textWeight, textStyle);
61-
}
62-
53+
typeface = typefaceFromAttrs(context, a);
6354
a.recycle();
6455
} else {
6556
typeface = RobotoTypefaceManager.obtainTypeface(context, RobotoTypefaceManager.Typeface.ROBOTO_REGULAR);
6657
}
6758

68-
setTypeface(textView, typeface);
59+
setup(textView, typeface);
60+
}
61+
62+
@NonNull
63+
public static Typeface typefaceFromAttrs(@NonNull Context context, @NonNull TypedArray a) {
64+
Typeface typeface;
65+
if (a.hasValue(R.styleable.RobotoTextView_typeface)) {
66+
int typefaceValue = a.getInt(R.styleable.RobotoTextView_typeface, RobotoTypefaceManager.Typeface.ROBOTO_REGULAR);
67+
typeface = RobotoTypefaceManager.obtainTypeface(context, typefaceValue);
68+
} else {
69+
int fontFamily = a.getInt(R.styleable.RobotoTextView_fontFamily, RobotoTypefaceManager.FontFamily.ROBOTO);
70+
int textWeight = a.getInt(R.styleable.RobotoTextView_textWeight, RobotoTypefaceManager.TextWeight.NORMAL);
71+
int textStyle = a.getInt(R.styleable.RobotoTextView_textStyle, RobotoTypefaceManager.TextStyle.NORMAL);
72+
typeface = RobotoTypefaceManager.obtainTypeface(context, fontFamily, textWeight, textStyle);
73+
}
74+
return typeface;
6975
}
7076

7177
/**
@@ -75,7 +81,7 @@ public static void initTypeface(TextView textView, Context context, AttributeSet
7581
* @param textView The text view
7682
* @param typeface The specify typeface
7783
*/
78-
public static void setTypeface(TextView textView, Typeface typeface) {
84+
public static void setup(@NonNull TextView textView, @NonNull Typeface typeface) {
7985
textView.setPaintFlags(textView.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
8086
textView.setTypeface(typeface);
8187
}
@@ -86,9 +92,8 @@ public static void setTypeface(TextView textView, Typeface typeface) {
8692
* @param paint The paint
8793
* @param typeface The specify typeface
8894
*/
89-
public static void setTypeface(Paint paint, Typeface typeface) {
95+
public static void setup(@NonNull Paint paint, @NonNull Typeface typeface) {
9096
paint.setFlags(paint.getFlags() | Paint.SUBPIXEL_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG);
9197
paint.setTypeface(typeface);
9298
}
93-
9499
}

robototextview/src/main/java/com/devspark/robototextview/widget/RobotoAutoCompleteTextView.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import android.util.AttributeSet;
2222
import android.widget.AutoCompleteTextView;
2323

24-
import com.devspark.robototextview.util.RobotoTextViewUtils;
24+
import com.devspark.robototextview.util.RobotoTypefaceUtils;
2525

2626
/**
2727
* Implementation of a {@link AutoCompleteTextView} with native support for all the Roboto fonts.
@@ -60,7 +60,7 @@ public RobotoAutoCompleteTextView(Context context, AttributeSet attrs) {
6060
super(context, attrs);
6161

6262
if (!isInEditMode()) {
63-
RobotoTextViewUtils.initTypeface(this, context, attrs);
63+
RobotoTypefaceUtils.initView(this, context, attrs);
6464
}
6565
}
6666

@@ -82,7 +82,7 @@ public RobotoAutoCompleteTextView(Context context, AttributeSet attrs, int defSt
8282
super(context, attrs, defStyle);
8383

8484
if (!isInEditMode()) {
85-
RobotoTextViewUtils.initTypeface(this, context, attrs);
85+
RobotoTypefaceUtils.initView(this, context, attrs);
8686
}
8787
}
8888

robototextview/src/main/java/com/devspark/robototextview/widget/RobotoButton.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import android.util.AttributeSet;
2222
import android.widget.Button;
2323

24-
import com.devspark.robototextview.util.RobotoTextViewUtils;
24+
import com.devspark.robototextview.util.RobotoTypefaceUtils;
2525

2626
/**
2727
* Implementation of a {@link Button} with native support for all the Roboto fonts.
@@ -60,7 +60,7 @@ public RobotoButton(Context context, AttributeSet attrs) {
6060
super(context, attrs);
6161

6262
if (!isInEditMode()) {
63-
RobotoTextViewUtils.initTypeface(this, context, attrs);
63+
RobotoTypefaceUtils.initView(this, context, attrs);
6464
}
6565
}
6666

@@ -82,7 +82,7 @@ public RobotoButton(Context context, AttributeSet attrs, int defStyle) {
8282
super(context, attrs, defStyle);
8383

8484
if (!isInEditMode()) {
85-
RobotoTextViewUtils.initTypeface(this, context, attrs);
85+
RobotoTypefaceUtils.initView(this, context, attrs);
8686
}
8787
}
8888

robototextview/src/main/java/com/devspark/robototextview/widget/RobotoCheckBox.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import android.util.AttributeSet;
2222
import android.widget.CheckBox;
2323

24-
import com.devspark.robototextview.util.RobotoTextViewUtils;
24+
import com.devspark.robototextview.util.RobotoTypefaceUtils;
2525

2626
/**
2727
* Implementation of a {@link CheckBox} with native support for all the Roboto fonts.
@@ -60,7 +60,7 @@ public RobotoCheckBox(Context context, AttributeSet attrs) {
6060
super(context, attrs);
6161

6262
if (!isInEditMode()) {
63-
RobotoTextViewUtils.initTypeface(this, context, attrs);
63+
RobotoTypefaceUtils.initView(this, context, attrs);
6464
}
6565
}
6666

@@ -82,7 +82,7 @@ public RobotoCheckBox(Context context, AttributeSet attrs, int defStyle) {
8282
super(context, attrs, defStyle);
8383

8484
if (!isInEditMode()) {
85-
RobotoTextViewUtils.initTypeface(this, context, attrs);
85+
RobotoTypefaceUtils.initView(this, context, attrs);
8686
}
8787
}
8888

robototextview/src/main/java/com/devspark/robototextview/widget/RobotoCheckedTextView.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
import android.util.AttributeSet;
2222
import android.widget.CheckedTextView;
2323

24-
import com.devspark.robototextview.util.RobotoTextViewUtils;
24+
import com.devspark.robototextview.util.RobotoTypefaceUtils;
2525

2626
/**
2727
* Implementation of a {@link CheckedTextView} with native support for all the Roboto fonts.
@@ -60,7 +60,7 @@ public RobotoCheckedTextView(Context context, AttributeSet attrs) {
6060
super(context, attrs);
6161

6262
if (!isInEditMode()) {
63-
RobotoTextViewUtils.initTypeface(this, context, attrs);
63+
RobotoTypefaceUtils.initView(this, context, attrs);
6464
}
6565
}
6666

@@ -82,7 +82,7 @@ public RobotoCheckedTextView(Context context, AttributeSet attrs, int defStyle)
8282
super(context, attrs, defStyle);
8383

8484
if (!isInEditMode()) {
85-
RobotoTextViewUtils.initTypeface(this, context, attrs);
85+
RobotoTypefaceUtils.initView(this, context, attrs);
8686
}
8787
}
8888

0 commit comments

Comments
 (0)