// Path: htextview-base/src/main/java/com/hanks/htextview/base/DefaultAnimatorListener.java
// public class DefaultAnimatorListener implements Animator.AnimatorListener {
//     @Override
//     public void onAnimationStart(Animator animation) {
//         // no-op
//     }
// 
//     @Override
//     public void onAnimationEnd(Animator animation) {
//         // no-op
//     }
// 
//     @Override
//     public void onAnimationCancel(Animator animation) {
//         // no-op
//     }
// 
//     @Override
//     public void onAnimationRepeat(Animator animation) {
//         // no-op
//     }
// }
// 
// Path: htextview-base/src/main/java/com/hanks/htextview/base/HText.java
// public abstract class HText implements IHText {
// 
//     protected int mHeight, mWidth;
//     protected CharSequence mText, mOldText;
//     protected TextPaint mPaint, mOldPaint;
//     protected HTextView mHTextView;
//     protected List<Float> gapList = new ArrayList<>();
//     protected List<Float> oldGapList = new ArrayList<>();
//     protected float progress; // 0 ~ 1
//     protected float mTextSize;
//     protected float oldStartX = 0;
//     protected AnimationListener animationListener;
// 
//     public void setProgress(float progress) {
//         this.progress = progress;
//         mHTextView.invalidate();
//     }
// 
//     @Override
//     public void init(HTextView hTextView, AttributeSet attrs, int defStyle) {
//         mHTextView = hTextView;
//         mOldText = "";
//         mText = hTextView.getText();
//         progress = 1;
// 
//         mPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
//         mOldPaint = new TextPaint(mPaint);
// 
//         mHTextView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
//             @Override
//             public void onGlobalLayout() {
//                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
//                     mHTextView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
//                 } else {
//                     mHTextView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
//                 }
//                 mTextSize = mHTextView.getTextSize();
//                 mWidth = mHTextView.getWidth();
//                 mHeight = mHTextView.getHeight();
//                 oldStartX = 0;
// 
//                 try {
//                     int layoutDirection = ViewCompat.getLayoutDirection(mHTextView);
// 
//                     oldStartX = layoutDirection == LAYOUT_DIRECTION_LTR
//                             ? mHTextView.getLayout().getLineLeft(0)
//                             : mHTextView.getLayout().getLineRight(0);
// 
//                 } catch (Exception e) {
//                     e.printStackTrace();
//                 }
// 
//                 initVariables();
//             }
//         });
//         prepareAnimate();
//     }
// 
//     private void prepareAnimate() {
//         mTextSize = mHTextView.getTextSize();
//         mPaint.setTextSize(mTextSize);
//         mPaint.setColor(mHTextView.getCurrentTextColor());
//         mPaint.setTypeface(mHTextView.getTypeface());
//         gapList.clear();
//         for (int i = 0; i < mText.length(); i++) {
//             gapList.add(mPaint.measureText(String.valueOf(mText.charAt(i))));
//         }
//         mOldPaint.setTextSize(mTextSize);
//         mOldPaint.setColor(mHTextView.getCurrentTextColor());
//         mOldPaint.setTypeface(mHTextView.getTypeface());
//         oldGapList.clear();
//         for (int i = 0; i < mOldText.length(); i++) {
//             oldGapList.add(mOldPaint.measureText(String.valueOf(mOldText.charAt(i))));
//         }
//     }
// 
//     @Override
//     public void animateText(CharSequence text) {
//         mHTextView.setText(text);
//         mOldText = mText;
//         mText = text;
//         prepareAnimate();
//         animatePrepare(text);
//         animateStart(text);
//     }
// 
//     @Override
//     public void setAnimationListener(AnimationListener listener) {
//         animationListener = listener;
//     }
// 
//     @Override
//     public void onDraw(Canvas canvas) {
//         drawFrame(canvas);
//     }
// 
//     protected abstract void initVariables();
// 
//     protected abstract void animateStart(CharSequence text);
// 
//     protected abstract void animatePrepare(CharSequence text);
// 
//     protected abstract void drawFrame(Canvas canvas);
// }
// 
// Path: htextview-base/src/main/java/com/hanks/htextview/base/HTextView.java
// public abstract class HTextView extends TextView {
//     public HTextView(Context context) {
//         this(context, null);
//     }
// 
//     public HTextView(Context context, AttributeSet attrs) {
//         this(context, attrs, 0);
//     }
// 
//     public HTextView(Context context, AttributeSet attrs, int defStyleAttr) {
//         super(context, attrs, defStyleAttr);
//     }
// 
//     public abstract void setAnimationListener(AnimationListener listener);
// 
//     public abstract void setProgress(float progress);
// 
//     public abstract void animateText(CharSequence text);
// }


import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.text.Layout;
import android.util.AttributeSet;
import android.view.animation.LinearInterpolator;
import com.hanks.htextview.base.DefaultAnimatorListener;
import com.hanks.htextview.base.HText;
import com.hanks.htextview.base.HTextView;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
package com.hanks.htextview.fade;





/**
 * fade effect
 * Created by hanks on 2017/3/14.
 */

public class FadeText extends HText {

    private Random random;
    private int animationDuration;
    private List<Integer> alphaList;
    private int DEFAULT_DURATION = 2000;

    @Override
// Path: htextview-base/src/main/java/com/hanks/htextview/base/DefaultAnimatorListener.java
// public class DefaultAnimatorListener implements Animator.AnimatorListener {
//     @Override
//     public void onAnimationStart(Animator animation) {
//         // no-op
//     }
// 
//     @Override
//     public void onAnimationEnd(Animator animation) {
//         // no-op
//     }
// 
//     @Override
//     public void onAnimationCancel(Animator animation) {
//         // no-op
//     }
// 
//     @Override
//     public void onAnimationRepeat(Animator animation) {
//         // no-op
//     }
// }
// 
// Path: htextview-base/src/main/java/com/hanks/htextview/base/HText.java
// public abstract class HText implements IHText {
// 
//     protected int mHeight, mWidth;
//     protected CharSequence mText, mOldText;
//     protected TextPaint mPaint, mOldPaint;
//     protected HTextView mHTextView;
//     protected List<Float> gapList = new ArrayList<>();
//     protected List<Float> oldGapList = new ArrayList<>();
//     protected float progress; // 0 ~ 1
//     protected float mTextSize;
//     protected float oldStartX = 0;
//     protected AnimationListener animationListener;
// 
//     public void setProgress(float progress) {
//         this.progress = progress;
//         mHTextView.invalidate();
//     }
// 
//     @Override
//     public void init(HTextView hTextView, AttributeSet attrs, int defStyle) {
//         mHTextView = hTextView;
//         mOldText = "";
//         mText = hTextView.getText();
//         progress = 1;
// 
//         mPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
//         mOldPaint = new TextPaint(mPaint);
// 
//         mHTextView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
//             @Override
//             public void onGlobalLayout() {
//                 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
//                     mHTextView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
//                 } else {
//                     mHTextView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
//                 }
//                 mTextSize = mHTextView.getTextSize();
//                 mWidth = mHTextView.getWidth();
//                 mHeight = mHTextView.getHeight();
//                 oldStartX = 0;
// 
//                 try {
//                     int layoutDirection = ViewCompat.getLayoutDirection(mHTextView);
// 
//                     oldStartX = layoutDirection == LAYOUT_DIRECTION_LTR
//                             ? mHTextView.getLayout().getLineLeft(0)
//                             : mHTextView.getLayout().getLineRight(0);
// 
//                 } catch (Exception e) {
//                     e.printStackTrace();
//                 }
// 
//                 initVariables();
//             }
//         });
//         prepareAnimate();
//     }
// 
//     private void prepareAnimate() {
//         mTextSize = mHTextView.getTextSize();
//         mPaint.setTextSize(mTextSize);
//         mPaint.setColor(mHTextView.getCurrentTextColor());
//         mPaint.setTypeface(mHTextView.getTypeface());
//         gapList.clear();
//         for (int i = 0; i < mText.length(); i++) {
//             gapList.add(mPaint.measureText(String.valueOf(mText.charAt(i))));
//         }
//         mOldPaint.setTextSize(mTextSize);
//         mOldPaint.setColor(mHTextView.getCurrentTextColor());
//         mOldPaint.setTypeface(mHTextView.getTypeface());
//         oldGapList.clear();
//         for (int i = 0; i < mOldText.length(); i++) {
//             oldGapList.add(mOldPaint.measureText(String.valueOf(mOldText.charAt(i))));
//         }
//     }
// 
//     @Override
//     public void animateText(CharSequence text) {
//         mHTextView.setText(text);
//         mOldText = mText;
//         mText = text;
//         prepareAnimate();
//         animatePrepare(text);
//         animateStart(text);
//     }
// 
//     @Override
//     public void setAnimationListener(AnimationListener listener) {
//         animationListener = listener;
//     }
// 
//     @Override
//     public void onDraw(Canvas canvas) {
//         drawFrame(canvas);
//     }
// 
//     protected abstract void initVariables();
// 
//     protected abstract void animateStart(CharSequence text);
// 
//     protected abstract void animatePrepare(CharSequence text);
// 
//     protected abstract void drawFrame(Canvas canvas);
// }
// 
// Path: htextview-base/src/main/java/com/hanks/htextview/base/HTextView.java
// public abstract class HTextView extends TextView {
//     public HTextView(Context context) {
//         this(context, null);
//     }
// 
//     public HTextView(Context context, AttributeSet attrs) {
//         this(context, attrs, 0);
//     }
// 
//     public HTextView(Context context, AttributeSet attrs, int defStyleAttr) {
//         super(context, attrs, defStyleAttr);
//     }
// 
//     public abstract void setAnimationListener(AnimationListener listener);
// 
//     public abstract void setProgress(float progress);
// 
//     public abstract void animateText(CharSequence text);
// }


// Path: htextview-fade/src/main/java/com/hanks/htextview/fade/FadeText.java
import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.text.Layout;
import android.util.AttributeSet;
import android.view.animation.LinearInterpolator;
import com.hanks.htextview.base.DefaultAnimatorListener;
import com.hanks.htextview.base.HText;
import com.hanks.htextview.base.HTextView;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

package com.hanks.htextview.fade;





/**
 * fade effect
 * Created by hanks on 2017/3/14.
 */

public class FadeText extends HText {

    private Random random;
    private int animationDuration;
    private List<Integer> alphaList;
    private int DEFAULT_DURATION = 2000;

    @Override
    public void init(HTextView hTextView, AttributeSet attrs, int defStyle) {