2525import android .text .SpannableString ;
2626import android .text .TextPaint ;
2727import android .text .TextUtils ;
28+ import android .text .style .MetricAffectingSpan ;
2829import android .text .style .TextAppearanceSpan ;
2930
3031/**
@@ -42,14 +43,17 @@ class TextDrawer {
4243 private final float padding ;
4344 private final float actionBarOffset ;
4445
45- private Layout .Alignment detailTextAlignment = Layout .Alignment .ALIGN_NORMAL ;
46- private Layout .Alignment titleTextAlignment = Layout .Alignment .ALIGN_NORMAL ;
47- private CharSequence mTitle , mDetails ;
46+ private Layout .Alignment textAlignment = Layout .Alignment .ALIGN_NORMAL ;
47+ private SpannableString textString ;
48+ private DynamicLayout textLayout ;
49+ private MetricAffectingSpan textSpan ;
50+
51+ private Layout .Alignment titleAlignment = Layout .Alignment .ALIGN_NORMAL ;
52+ private SpannableString titleString ;
53+ private DynamicLayout titleLayout ;
54+ private MetricAffectingSpan titleSpan ;
55+
4856 private float [] mBestTextPosition = new float [3 ];
49- private DynamicLayout mDynamicTitleLayout ;
50- private DynamicLayout mDynamicDetailLayout ;
51- private TextAppearanceSpan mTitleSpan ;
52- private TextAppearanceSpan mDetailSpan ;
5357 private boolean hasRecalculated ;
5458 @ ShowcaseView .TextPosition
5559 private int forcedTextPosition = ShowcaseView .UNDEFINED ;
@@ -72,29 +76,29 @@ public void draw(Canvas canvas) {
7276 float [] textPosition = getBestTextPosition ();
7377 int width = Math .max (0 , (int ) mBestTextPosition [INDEX_TEXT_WIDTH ]);
7478
75- if (!TextUtils .isEmpty (mTitle )) {
79+ if (!TextUtils .isEmpty (titleString )) {
7680 canvas .save ();
7781 if (hasRecalculated ) {
78- mDynamicTitleLayout = new DynamicLayout (mTitle , titlePaint ,
79- width , titleTextAlignment , 1.0f , 1.0f , true );
82+ titleLayout = new DynamicLayout (titleString , titlePaint ,
83+ width , titleAlignment , 1.0f , 1.0f , true );
8084 }
81- if (mDynamicTitleLayout != null ) {
85+ if (titleLayout != null ) {
8286 canvas .translate (textPosition [INDEX_TEXT_START_X ], textPosition [INDEX_TEXT_START_Y ]);
83- mDynamicTitleLayout .draw (canvas );
87+ titleLayout .draw (canvas );
8488 canvas .restore ();
8589 }
8690 }
8791
88- if (!TextUtils .isEmpty (mDetails )) {
92+ if (!TextUtils .isEmpty (textString )) {
8993 canvas .save ();
9094 if (hasRecalculated ) {
91- mDynamicDetailLayout = new DynamicLayout (mDetails , textPaint ,
92- width , detailTextAlignment , 1.2f , 1.0f , true );
95+ textLayout = new DynamicLayout (textString , textPaint ,
96+ width , textAlignment , 1.2f , 1.0f , true );
9397 }
94- float offsetForTitle = mDynamicTitleLayout != null ? mDynamicTitleLayout .getHeight () : 0 ;
95- if (mDynamicDetailLayout != null ) {
98+ float offsetForTitle = titleLayout != null ? titleLayout .getHeight () : 0 ;
99+ if (textLayout != null ) {
96100 canvas .translate (textPosition [INDEX_TEXT_START_X ], textPosition [INDEX_TEXT_START_Y ] + offsetForTitle );
97- mDynamicDetailLayout .draw (canvas );
101+ textLayout .draw (canvas );
98102 canvas .restore ();
99103 }
100104
@@ -106,16 +110,16 @@ public void draw(Canvas canvas) {
106110 public void setContentText (CharSequence details ) {
107111 if (details != null ) {
108112 SpannableString ssbDetail = new SpannableString (details );
109- ssbDetail .setSpan (mDetailSpan , 0 , ssbDetail .length (), 0 );
110- mDetails = ssbDetail ;
113+ ssbDetail .setSpan (textSpan , 0 , ssbDetail .length (), 0 );
114+ textString = ssbDetail ;
111115 }
112116 }
113117
114118 public void setContentTitle (CharSequence title ) {
115119 if (title != null ) {
116120 SpannableString ssbTitle = new SpannableString (title );
117- ssbTitle .setSpan (mTitleSpan , 0 , ssbTitle .length (), 0 );
118- mTitle = ssbTitle ;
121+ ssbTitle .setSpan (titleSpan , 0 , ssbTitle .length (), 0 );
122+ titleString = ssbTitle ;
119123 }
120124 }
121125
@@ -194,37 +198,47 @@ public void calculateTextPosition(int canvasW, int canvasH, boolean shouldCentre
194198 }
195199
196200 public void setTitleStyling (int styleId ) {
197- mTitleSpan = new TextAppearanceSpan (this .context , styleId );
198- setContentTitle (mTitle );
201+ titleSpan = new TextAppearanceSpan (this .context , styleId );
202+ setContentTitle (titleString );
199203 }
200204
201205 public void setDetailStyling (int styleId ) {
202- mDetailSpan = new TextAppearanceSpan (this .context , styleId );
203- setContentText (mDetails );
206+ textSpan = new TextAppearanceSpan (this .context , styleId );
207+ setContentText (textString );
204208 }
205209
206210 public float [] getBestTextPosition () {
207211 return mBestTextPosition ;
208212 }
209213
210214 public boolean shouldDrawText () {
211- return !TextUtils .isEmpty (mTitle ) || !TextUtils .isEmpty (mDetails );
215+ return !TextUtils .isEmpty (titleString ) || !TextUtils .isEmpty (textString );
212216 }
213217
214218 public void setContentPaint (TextPaint contentPaint ) {
215219 textPaint .set (contentPaint );
220+ if (textString != null ) {
221+ textString .removeSpan (textSpan );
222+ }
223+ textSpan = new NoOpSpan ();
224+ setContentText (textString );
216225 }
217226
218227 public void setTitlePaint (TextPaint textPaint ) {
219228 titlePaint .set (textPaint );
229+ if (titleString != null ) {
230+ titleString .removeSpan (titleSpan );
231+ }
232+ titleSpan = new NoOpSpan ();
233+ setContentTitle (titleString );
220234 }
221235
222236 public void setDetailTextAlignment (Layout .Alignment textAlignment ) {
223- this .detailTextAlignment = textAlignment ;
237+ this .textAlignment = textAlignment ;
224238 }
225239
226240 public void setTitleTextAlignment (Layout .Alignment titleTextAlignment ) {
227- this .titleTextAlignment = titleTextAlignment ;
241+ this .titleAlignment = titleTextAlignment ;
228242 }
229243
230244 public void forceTextPosition (@ ShowcaseView .TextPosition int textPosition ) {
@@ -233,4 +247,16 @@ public void forceTextPosition(@ShowcaseView.TextPosition int textPosition) {
233247 }
234248 forcedTextPosition = textPosition ;
235249 }
250+
251+ private static class NoOpSpan extends MetricAffectingSpan {
252+ @ Override
253+ public void updateDrawState (TextPaint tp ) {
254+ // No-op
255+ }
256+
257+ @ Override
258+ public void updateMeasureState (TextPaint p ) {
259+ // No-op
260+ }
261+ }
236262}
0 commit comments