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+ }
0 commit comments