1
1
/*
2
2
* Copyright (C) 2015 The Android Open Source Project
3
- * Modified 2015 by Johan v. Forstner
3
+ * Modified 2015 by Johan v. Forstner (modifications are marked with comments)
4
4
*
5
5
* Licensed under the Apache License, Version 2.0 (the "License");
6
6
* you may not use this file except in compliance with the License.
28
28
import android .support .v4 .text .TextDirectionHeuristicsCompat ;
29
29
import android .support .v4 .view .GravityCompat ;
30
30
import android .support .v4 .view .ViewCompat ;
31
+ // BEGIN MODIFICATION: Added imports
31
32
import android .text .Layout ;
32
33
import android .text .StaticLayout ;
34
+ // END MODIFICATION
33
35
import android .text .TextPaint ;
34
36
import android .text .TextUtils ;
35
37
import android .view .Gravity ;
@@ -52,8 +54,10 @@ final class CollapsingTextHelper {
52
54
}
53
55
54
56
private final View mView ;
57
+
55
58
private boolean mDrawTitle ;
56
59
private float mExpandedFraction ;
60
+
57
61
private final Rect mExpandedBounds ;
58
62
private final Rect mCollapsedBounds ;
59
63
private final RectF mCurrentBounds ;
@@ -63,6 +67,7 @@ final class CollapsingTextHelper {
63
67
private float mCollapsedTextSize = 15 ;
64
68
private int mExpandedTextColor ;
65
69
private int mCollapsedTextColor ;
70
+
66
71
private float mExpandedDrawY ;
67
72
private float mCollapsedDrawY ;
68
73
private float mExpandedDrawX ;
@@ -72,42 +77,50 @@ final class CollapsingTextHelper {
72
77
private Typeface mCollapsedTypeface ;
73
78
private Typeface mExpandedTypeface ;
74
79
private Typeface mCurrentTypeface ;
80
+
75
81
private CharSequence mText ;
76
82
private CharSequence mTextToDraw ;
77
- private CharSequence mTextToDrawCollapsed ;
78
83
private boolean mIsRtl ;
84
+
79
85
private boolean mUseTexture ;
80
- private Bitmap mCollapsedTitleTexture ;
81
86
private Bitmap mExpandedTitleTexture ;
82
87
private Paint mTexturePaint ;
88
+ // MODIFICATION: Removed now unused fields mTextureAscent and mTextureDescent
89
+
83
90
private float mScale ;
84
91
private float mCurrentTextSize ;
92
+
85
93
private boolean mBoundsChanged ;
94
+
86
95
private final TextPaint mTextPaint ;
96
+
87
97
private Interpolator mPositionInterpolator ;
88
98
private Interpolator mTextSizeInterpolator ;
89
- private Interpolator mTextBlendInterpolator ;
99
+
90
100
private float mCollapsedShadowRadius , mCollapsedShadowDx , mCollapsedShadowDy ;
91
101
private int mCollapsedShadowColor ;
102
+
92
103
private float mExpandedShadowRadius , mExpandedShadowDx , mExpandedShadowDy ;
93
104
private int mExpandedShadowColor ;
105
+
106
+ // BEGIN MODIFICATION: Added fields
107
+ private CharSequence mTextToDrawCollapsed ;
108
+ private Bitmap mCollapsedTitleTexture ;
94
109
private StaticLayout mTextLayout ;
95
110
private float mTextBlend ;
111
+ // END MODIFICATION
96
112
97
113
public CollapsingTextHelper (View view ) {
98
114
mView = view ;
115
+
99
116
mTextPaint = new TextPaint ();
100
117
mTextPaint .setAntiAlias (true );
118
+
101
119
mCollapsedBounds = new Rect ();
102
120
mExpandedBounds = new Rect ();
103
121
mCurrentBounds = new RectF ();
104
122
}
105
123
106
- void setTextBlendInterpolator (Interpolator interpolator ) {
107
- mTextBlendInterpolator = interpolator ;
108
- recalculate ();
109
- }
110
-
111
124
void setTextSizeInterpolator (Interpolator interpolator ) {
112
125
mTextSizeInterpolator = interpolator ;
113
126
recalculate ();
@@ -204,9 +217,11 @@ void setCollapsedTextAppearance(int resId) {
204
217
mCollapsedShadowDy = a .getFloat (R .styleable .TextAppearance_android_shadowDy , 0 );
205
218
mCollapsedShadowRadius = a .getFloat (R .styleable .TextAppearance_android_shadowRadius , 0 );
206
219
a .recycle ();
220
+
207
221
if (Build .VERSION .SDK_INT >= 16 ) {
208
222
mCollapsedTypeface = readFontFamilyTypeface (resId );
209
223
}
224
+
210
225
recalculate ();
211
226
}
212
227
@@ -225,9 +240,11 @@ void setExpandedTextAppearance(int resId) {
225
240
mExpandedShadowDy = a .getFloat (R .styleable .TextAppearance_android_shadowDy , 0 );
226
241
mExpandedShadowRadius = a .getFloat (R .styleable .TextAppearance_android_shadowRadius , 0 );
227
242
a .recycle ();
243
+
228
244
if (Build .VERSION .SDK_INT >= 16 ) {
229
245
mExpandedTypeface = readFontFamilyTypeface (resId );
230
246
}
247
+
231
248
recalculate ();
232
249
}
233
250
@@ -281,6 +298,7 @@ Typeface getExpandedTypeface() {
281
298
*/
282
299
void setExpansionFraction (float fraction ) {
283
300
fraction = MathUtils .constrain (fraction , 0f , 1f );
301
+
284
302
if (fraction != mExpandedFraction ) {
285
303
mExpandedFraction = fraction ;
286
304
calculateCurrentOffsets ();
@@ -311,7 +329,11 @@ private void calculateOffsets(final float fraction) {
311
329
mPositionInterpolator );
312
330
setInterpolatedTextSize (lerp (mExpandedTextSize , mCollapsedTextSize ,
313
331
fraction , mTextSizeInterpolator ));
314
- setTextBlend (lerp (0 , 1 , fraction , mTextBlendInterpolator ));
332
+
333
+ // BEGIN MODIFICATION: set text blending
334
+ setTextBlend (lerp (0 , 1 , fraction , null ));
335
+ // END MODIFICATION
336
+
315
337
if (mCollapsedTextColor != mExpandedTextColor ) {
316
338
// If the collapsed and expanded text colors are different, blend them based on the
317
339
// fraction
@@ -331,11 +353,18 @@ private void calculateBaseOffsets() {
331
353
final float currentTextSize = mCurrentTextSize ;
332
354
// We then calculate the collapsed text size, using the same logic
333
355
calculateUsingTextSize (mCollapsedTextSize );
356
+
357
+ // BEGIN MODIFICATION: set mTextToDrawCollapsed and calculate width using mTextLayout
334
358
mTextToDrawCollapsed = mTextToDraw ;
335
359
float width = mTextLayout != null ? mTextLayout .getWidth () : 0 ;
360
+ // END MODIFICATION
361
+
336
362
final int collapsedAbsGravity = GravityCompat .getAbsoluteGravity (mCollapsedTextGravity ,
337
363
mIsRtl ? ViewCompat .LAYOUT_DIRECTION_RTL : ViewCompat .LAYOUT_DIRECTION_LTR );
364
+
365
+ // BEGIN MODIFICATION: calculate height and Y position using mTextLayout
338
366
float textHeight = mTextLayout != null ? mTextLayout .getHeight () : 0 ;
367
+
339
368
switch (collapsedAbsGravity & Gravity .VERTICAL_GRAVITY_MASK ) {
340
369
case Gravity .BOTTOM :
341
370
mCollapsedDrawY = mCollapsedBounds .bottom - textHeight ;
@@ -349,6 +378,8 @@ private void calculateBaseOffsets() {
349
378
mCollapsedDrawY = mCollapsedBounds .centerY () - textOffset ;
350
379
break ;
351
380
}
381
+ // END MODIFICATION
382
+
352
383
switch (collapsedAbsGravity & Gravity .HORIZONTAL_GRAVITY_MASK ) {
353
384
case Gravity .CENTER_HORIZONTAL :
354
385
mCollapsedDrawX = mCollapsedBounds .centerX () - (width / 2 );
@@ -361,10 +392,17 @@ private void calculateBaseOffsets() {
361
392
mCollapsedDrawX = mCollapsedBounds .left ;
362
393
break ;
363
394
}
395
+
364
396
calculateUsingTextSize (mExpandedTextSize );
397
+
398
+ // BEGIN MODIFICATION: calculate width using mTextLayout
365
399
width = mTextLayout != null ? mTextLayout .getWidth () : 0 ;
400
+ // END MODIFICATION
401
+
366
402
final int expandedAbsGravity = GravityCompat .getAbsoluteGravity (mExpandedTextGravity ,
367
403
mIsRtl ? ViewCompat .LAYOUT_DIRECTION_RTL : ViewCompat .LAYOUT_DIRECTION_LTR );
404
+
405
+ // BEGIN MODIFICATION: calculate height and Y position using mTextLayout
368
406
textHeight = mTextLayout != null ? mTextLayout .getHeight () : 0 ;
369
407
switch (expandedAbsGravity & Gravity .VERTICAL_GRAVITY_MASK ) {
370
408
case Gravity .BOTTOM :
@@ -379,6 +417,8 @@ private void calculateBaseOffsets() {
379
417
mExpandedDrawY = mExpandedBounds .centerY () - textOffset ;
380
418
break ;
381
419
}
420
+ // END MODIFICATION
421
+
382
422
switch (expandedAbsGravity & Gravity .HORIZONTAL_GRAVITY_MASK ) {
383
423
case Gravity .CENTER_HORIZONTAL :
384
424
mExpandedDrawX = mExpandedBounds .centerX () - (width / 2 );
@@ -391,6 +431,7 @@ private void calculateBaseOffsets() {
391
431
mExpandedDrawX = mExpandedBounds .left ;
392
432
break ;
393
433
}
434
+
394
435
// The bounds have changed so we need to clear the texture
395
436
clearTexture ();
396
437
// Now reset the text size back to the original
@@ -410,18 +451,25 @@ private void interpolateBounds(float fraction) {
410
451
411
452
public void draw (Canvas canvas ) {
412
453
final int saveCount = canvas .save ();
454
+
413
455
if (mTextToDraw != null && mDrawTitle ) {
414
456
float x = mCurrentDrawX ;
415
457
float y = mCurrentDrawY ;
458
+
416
459
final boolean drawTexture = mUseTexture && mExpandedTitleTexture != null ;
417
460
final float ascent ;
461
+ // MODIFICATION: removed now unused "descent" variable declaration
462
+
418
463
// Update the TextPaint to the current text size
419
464
mTextPaint .setTextSize (mCurrentTextSize );
465
+
466
+ // BEGIN MODIFICATION: new drawing code
420
467
if (drawTexture ) {
421
468
ascent = 0 ;
422
469
} else {
423
470
ascent = mTextPaint .ascent () * mScale ;
424
471
}
472
+
425
473
if (DEBUG_DRAW ) {
426
474
// Just a debug tool, which drawn a Magneta rect in the text bounds
427
475
canvas .drawRect (mCurrentBounds .left , y , mCurrentBounds .right ,
@@ -445,10 +493,12 @@ public void draw(Canvas canvas) {
445
493
canvas .drawText (mTextToDrawCollapsed , 0 , mTextToDrawCollapsed .length (), 0 ,
446
494
-ascent / mScale , mTextPaint );
447
495
}
496
+ // END MODIFICATION
448
497
}
449
498
canvas .restoreToCount (saveCount );
450
499
}
451
500
501
+ // BEGIN MODIFICATION: new getCrossfadeAlpha function
452
502
/**
453
503
* Calculate alpha values for "square crossfade" between two images with transparency see
454
504
* http://javagraphics.blogspot.de/2008/06/crossfades-what-is-and-isnt-possible.html
@@ -464,6 +514,7 @@ private boolean calculateIsRtl(CharSequence text) {
464
514
? TextDirectionHeuristicsCompat .FIRSTSTRONG_RTL
465
515
: TextDirectionHeuristicsCompat .FIRSTSTRONG_LTR ).isRtl (text , 0 , text .length ());
466
516
}
517
+ // END MODIFICATION
467
518
468
519
private void setInterpolatedTextSize (float textSize ) {
469
520
calculateUsingTextSize (textSize );
@@ -472,22 +523,28 @@ private void setInterpolatedTextSize(float textSize) {
472
523
if (mUseTexture ) {
473
524
// Make sure we have an expanded texture if needed
474
525
ensureExpandedTexture ();
526
+ // BEGIN MODIFICATION: added collapsed texture
475
527
ensureCollapsedTexture ();
476
528
}
477
529
ViewCompat .postInvalidateOnAnimation (mView );
530
+ // END MODIFICATION
478
531
}
479
532
533
+ // BEGIN MODIFICATION: new setTextBlend method
480
534
private void setTextBlend (float blend ) {
481
535
mTextBlend = blend ;
482
536
ViewCompat .postInvalidateOnAnimation (mView );
483
537
}
538
+ // END MODIFICATION
484
539
485
540
private void calculateUsingTextSize (final float textSize ) {
486
541
if (mText == null ) return ;
487
542
final float availableWidth ;
488
543
final float newTextSize ;
489
544
boolean updateDrawText = false ;
545
+ // BEGIN MODIFICATION: Add maxLines variable
490
546
int maxLines ;
547
+ // END MODIFICATION
491
548
if (isClose (textSize , mCollapsedTextSize )) {
492
549
availableWidth = mCollapsedBounds .width ();
493
550
newTextSize = mCollapsedTextSize ;
@@ -496,7 +553,9 @@ private void calculateUsingTextSize(final float textSize) {
496
553
mCurrentTypeface = mCollapsedTypeface ;
497
554
updateDrawText = true ;
498
555
}
556
+ // BEGIN MODIFICATION: Set maxLines variable
499
557
maxLines = 1 ;
558
+ // END MODIFICATION
500
559
} else {
501
560
availableWidth = mExpandedBounds .width ();
502
561
newTextSize = mExpandedTextSize ;
@@ -511,7 +570,9 @@ private void calculateUsingTextSize(final float textSize) {
511
570
// Else, we'll scale down from the expanded text size
512
571
mScale = textSize / mExpandedTextSize ;
513
572
}
573
+ // BEGIN MODIFICATION: Set maxLines variable
514
574
maxLines = 3 ;
575
+ // END MODIFICATION
515
576
}
516
577
if (availableWidth > 0 ) {
517
578
updateDrawText = (mCurrentTextSize != newTextSize ) || mBoundsChanged || updateDrawText ;
@@ -522,6 +583,7 @@ private void calculateUsingTextSize(final float textSize) {
522
583
mTextPaint .setTextSize (mCurrentTextSize );
523
584
mTextPaint .setTypeface (mCurrentTypeface );
524
585
586
+ // BEGIN MODIFICATION: Text layout creation and text truncation
525
587
StaticLayout layout = new StaticLayout (mText , mTextPaint , (int ) availableWidth ,
526
588
Layout .Alignment .ALIGN_NORMAL , 1 , 0 , false );
527
589
CharSequence truncatedText ;
@@ -553,6 +615,7 @@ private void calculateUsingTextSize(final float textSize) {
553
615
}
554
616
mTextLayout = new StaticLayout (mTextToDraw , mTextPaint , (int ) availableWidth ,
555
617
Layout .Alignment .ALIGN_NORMAL , 1 , 0 , false );
618
+ // END MODIFICATION
556
619
}
557
620
}
558
621
@@ -562,20 +625,29 @@ private void ensureExpandedTexture() {
562
625
return ;
563
626
}
564
627
calculateOffsets (0f );
628
+
629
+ // BEGIN MODIFICATION: Calculate width and height using mTextLayout and remove
630
+ // mTextureAscent and mTextureDescent assignment
565
631
final int w = mTextLayout .getWidth ();
566
632
final int h = mTextLayout .getHeight ();
633
+ // END MODIFICATION
634
+
567
635
if (w <= 0 && h <= 0 ) {
568
636
return ; // If the width or height are 0, return
569
637
}
570
638
mExpandedTitleTexture = Bitmap .createBitmap (w , h , Bitmap .Config .ARGB_8888 );
639
+
640
+ // BEGIN MODIFICATION: Draw text using mTextLayout
571
641
Canvas c = new Canvas (mExpandedTitleTexture );
572
642
mTextLayout .draw (c );
643
+ // END MODIFICATION
573
644
if (mTexturePaint == null ) {
574
645
// Make sure we have a paint
575
646
mTexturePaint = new Paint (Paint .ANTI_ALIAS_FLAG | Paint .FILTER_BITMAP_FLAG );
576
647
}
577
648
}
578
649
650
+ // BEGIN MODIFICATION: new ensureCollapsedTexture method
579
651
private void ensureCollapsedTexture () {
580
652
if (mCollapsedTitleTexture != null || mCollapsedBounds .isEmpty ()
581
653
|| TextUtils .isEmpty (mTextToDraw )) {
@@ -596,6 +668,7 @@ private void ensureCollapsedTexture() {
596
668
mTexturePaint = new Paint (Paint .ANTI_ALIAS_FLAG | Paint .FILTER_BITMAP_FLAG );
597
669
}
598
670
}
671
+ // END MODIFICATION
599
672
600
673
public void recalculate () {
601
674
if (mView .getHeight () > 0 && mView .getWidth () > 0 ) {
0 commit comments