react-native-navigation的迁移库

CollapsingTextView.java 5.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. package com.reactnativenavigation.views.collapsingToolbar;
  2. import android.annotation.SuppressLint;
  3. import android.content.Context;
  4. import android.graphics.Canvas;
  5. import android.graphics.Color;
  6. import android.graphics.Paint;
  7. import android.support.annotation.CheckResult;
  8. import android.support.annotation.FloatRange;
  9. import android.support.v4.widget.TextViewCompat;
  10. import android.support.v7.widget.TintTypedArray;
  11. import android.text.TextPaint;
  12. import android.text.TextUtils;
  13. import android.view.animation.DecelerateInterpolator;
  14. import android.view.animation.Interpolator;
  15. import android.widget.FrameLayout;
  16. import android.widget.LinearLayout;
  17. import android.widget.TextView;
  18. import com.reactnativenavigation.R;
  19. import com.reactnativenavigation.params.StyleParams;
  20. import com.reactnativenavigation.utils.ViewUtils;
  21. public class CollapsingTextView extends FrameLayout {
  22. private static final float TEXT_SCALE_FACTOR = 1.75f;
  23. private static final float INTERPOLATOR_EASING_FACTOR = 0.5f;
  24. private final int collapsedHeight;
  25. private TextView dummy;
  26. private CharSequence textToDraw;
  27. private CharSequence expendedTextToDraw;
  28. private String originalText;
  29. private TextPaint paint;
  30. private float initialY = -1;
  31. private float currentY;
  32. private float collapseY;
  33. private float collapseFraction;
  34. private Interpolator scaleInterpolator;
  35. private float expendedTextSize;
  36. private float collapsedTextSize;
  37. public CollapsingTextView(Context context, int collapsedHeight) {
  38. super(context);
  39. this.collapsedHeight = collapsedHeight;
  40. setWillNotDraw(false);
  41. createDummyTextView(context);
  42. createTextPaint();
  43. scaleInterpolator = new DecelerateInterpolator(INTERPOLATOR_EASING_FACTOR);
  44. setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
  45. }
  46. @SuppressLint("PrivateResource")
  47. private void createDummyTextView(Context context) {
  48. final TintTypedArray a = TintTypedArray.obtainStyledAttributes(getContext(), null,
  49. R.styleable.Toolbar, R.attr.toolbarStyle, 0);
  50. int titleTextAppearance =
  51. a.getResourceId(R.styleable.Toolbar_titleTextAppearance, 0);
  52. a.recycle();
  53. dummy = new TextView(context);
  54. dummy.setSingleLine();
  55. dummy.setEllipsize(TextUtils.TruncateAt.END);
  56. TextViewCompat.setTextAppearance(dummy, titleTextAppearance);
  57. collapsedTextSize = dummy.getTextSize();
  58. expendedTextSize = collapsedTextSize * TEXT_SCALE_FACTOR;
  59. dummy.setTextSize(ViewUtils.convertPixelToSp(expendedTextSize));
  60. dummy.setVisibility(INVISIBLE);
  61. addView(dummy, new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
  62. }
  63. private void createTextPaint() {
  64. paint = new TextPaint(Paint.ANTI_ALIAS_FLAG | Paint.LINEAR_TEXT_FLAG);
  65. paint.setColor(Color.WHITE);
  66. paint.setTextSize(expendedTextSize);
  67. }
  68. public void setText(String text) {
  69. this.originalText = text;
  70. dummy.setText(text);
  71. }
  72. public void setTextColor(StyleParams params) {
  73. if (params.titleBarTitleColor.hasColor()) {
  74. paint.setColor(params.titleBarTitleColor.getColor());
  75. }
  76. }
  77. public void collapseBy(float translation) {
  78. collapseFraction = calculateFraction(translation);
  79. currentY = linearInterpolation(initialY, collapseY, collapseFraction);
  80. invalidate();
  81. }
  82. /*
  83. * A value of {@code 0.0} indicates that the layout is fully expanded.
  84. * A value of {@code 1.0} indicates that the layout is fully collapsed.
  85. */
  86. @FloatRange(from = 0.0, to = 1.0)
  87. private float calculateFraction(float translation) {
  88. return Math.abs(translation / (getMeasuredHeight() - collapsedHeight));
  89. }
  90. @Override
  91. protected void onDraw(Canvas canvas) {
  92. super.onDraw(canvas);
  93. if (initialY == -1) {
  94. calculateTextPosition(canvas);
  95. }
  96. paint.setTextSize(linearInterpolation(expendedTextSize, collapsedTextSize, collapseFraction));
  97. calculateTextToDraw();
  98. canvas.drawText(textToDraw, 0, textToDraw.length(), 0, currentY, paint);
  99. }
  100. private void calculateTextToDraw() {
  101. if (currentY == collapseY) {
  102. textToDraw = calculateText();
  103. } else {
  104. if (expendedTextToDraw == null) {
  105. expendedTextToDraw = calculateText();
  106. }
  107. textToDraw = expendedTextToDraw;
  108. }
  109. }
  110. private void calculateTextPosition(Canvas canvas) {
  111. final int[] positionOnScreen = new int[2];
  112. getLocationInWindow(positionOnScreen);
  113. currentY = initialY = positionOnScreen[1] + canvas.getHeight() - dummy.getMeasuredHeight();
  114. float bottomMargin = ViewUtils.convertDpToPixel(10);
  115. collapseY = positionOnScreen[1] + bottomMargin;
  116. }
  117. private float linearInterpolation(float from, float to, float fraction) {
  118. fraction = scaleInterpolator.getInterpolation(fraction);
  119. return from + (fraction * (to - from));
  120. }
  121. @CheckResult
  122. private String calculateText() {
  123. return (String) TextUtils.ellipsize(originalText, paint,
  124. getWidth(), TextUtils.TruncateAt.END);
  125. }
  126. }