打造一个动态切换文本的TextView

效果图

此处输入图片的描述

思路

继承自TextView,在指定时间调用setText()方法切换文本,并且设置进入退出动画

代码解析

代码不多,简洁明了

public class FadingTextView extends TextView {

    private Animation fadeInAnimation, fadeOutAnimation;//切换文本动画

    private int duration;//切换时间,默认3秒

    private final int DEFAULT_DURATION = 3000;

    private CharSequence[] textContents;//文本内容

    private int textPosition = 0;//当前显示的文本角标

    private boolean isShown;//是否可见

    public FadingTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        fadeInAnimation = AnimationUtils.loadAnimation(context, R.anim.fade_in);
        fadeOutAnimation = AnimationUtils.loadAnimation(context, R.anim.fade_out);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FadingTextView);
        duration = a.getInteger(R.styleable.FadingTextView_duration, DEFAULT_DURATION);
        textContents = a.getTextArray(R.styleable.FadingTextView_texts);
        a.recycle();
    }

    public FadingTextView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public FadingTextView(Context context) {
        this(context, null);
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        isShown = true;
        start();
    }

    @Override
    protected void onDetachedFromWindow() {//涉及动画,需要在detach方法停止不然会造成内存泄漏
        super.onDetachedFromWindow();
        stop();
    }

    /**
     * 设置文本内容
     *
     * @param texts
     */
    public void setTexts(String... texts) {
        if (texts.length < 1) {
            throw new IllegalArgumentException("This TextView's contents' length must more than 1");
        }
        textContents = texts;
    }

    /**
     * 设置文本内容
     *
     * @param resourceId
     */
    public void setTexts(@ArrayRes int resourceId) {
        String[] texts = getContext().getResources().getStringArray(resourceId);
        if (texts != null) {
            if (texts.length < 1) {
                throw new IllegalArgumentException("This TextView's contents' length must more than 1");
            }
            textContents = texts;
        }
    }

    /**
     * 设置持续时间
     *
     * @param duration
     */
    public void setDuration(int duration) {
        if (duration < 1) {
            throw new IllegalArgumentException("duration must more than 1");
        }
        this.duration = duration;
    }

    /**
     * 获取设置的文本内容
     *
     * @return
     */
    public CharSequence[] getTextContents() {
        return textContents;
    }

    /**
     * 开始
     */
    private void start() {
        setText(textContents[textPosition]);
        startAnimation(fadeInAnimation);
        postDelayed(animRunnable, duration);
    }

    /**
     * 停止
     */
    private void stop() {
        if (getAnimation() != null) {
            getAnimation().cancel();
        }
        isShown = false;
        removeCallbacks(animRunnable);
    }

    private final Runnable animRunnable = new Runnable() {
        @Override
        public void run() {
            startAnimation(fadeOutAnimation);
            getAnimation().setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {

                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    if (isShown) {
                        textPosition = (textPosition == (textContents.length - 1)) ? 0 : (textPosition + 1);
                        start();
                    }

                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }
            });
        }
    };
}

准备工作:

自定义属性的声明,获取,动画的初始化工作

  • 自定义属性声明
  <declare-styleable name="FadingTextView">
        <attr name="duration" format="integer" />
        <attr name="texts" format="reference" />
    </declare-styleable>
  • 自定义属性的获取
 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.FadingTextView);
        duration = a.getInteger(R.styleable.FadingTextView_duration, DEFAULT_DURATION);
        textContents = a.getTextArray(R.styleable.FadingTextView_texts);
        a.recycle();
  • 动画的声明跟获取
fade_in
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha
        android:duration="@android:integer/config_longAnimTime"
        android:fromAlpha="0.0"
        android:toAlpha="1.0"
        android:interpolator="@android:anim/linear_interpolator"
        />
</set>

fade_out
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha
        android:duration="@android:integer/config_longAnimTime"
        android:fromAlpha="1.0"
        android:toAlpha="0.0"
        android:interpolator="@android:anim/linear_interpolator"
        />
</set>

获取动画

  fadeInAnimation = AnimationUtils.loadAnimation(context, R.anim.fade_in);
  fadeOutAnimation = AnimationUtils.loadAnimation(context, R.anim.fade_out);

第一步:

既然是动态切换文本,那需要的text文本肯定是需要多个,不然无法达到切换的目的

 /**
     * 设置文本内容
     *
     * @param texts
     */
    public void setTexts(String... texts) {
        if (texts.length < 1) {
            throw new IllegalArgumentException("This TextView's contents' length must more than 1");
        }
        textContents = texts;
    }

    /**
     * 设置文本内容
     *
     * @param resourceId
     */
    public void setTexts(@ArrayRes int resourceId) {
        String[] texts = getContext().getResources().getStringArray(resourceId);
        if (texts.length < 1) {
            throw new IllegalArgumentException("This TextView's contents' length must more than 1");
        }
        textContents = texts;
    }

第二步:

给TextView设置文本、动画,达到渐变效果


    /**
     * 开始
     */
    private void start() {
        setText(textContents[textPosition]);
        startAnimation(fadeInAnimation);
        postDelayed(animRunnable, duration);
    }

第三步:

定时更新文本内容

 private final Runnable animRunnable = new Runnable() {
        @Override
        public void run() {
            startAnimation(fadeOutAnimation);
            getAnimation().setAnimationListener(new Animation.AnimationListener() {
                @Override
                public void onAnimationStart(Animation animation) {

                }

                @Override
                public void onAnimationEnd(Animation animation) {
                    if (isShown) {
                        textPosition = (textPosition == (textContents.length - 1)) ? 0 : (textPosition + 1);
                        start();
                    }

                }

                @Override
                public void onAnimationRepeat(Animation animation) {

                }
            });
        }
    };

第四步:

资源的回收

 @Override
    protected void onDetachedFromWindow() {//涉及动画,需要在detach方法停止不然会造成内存泄漏
        super.onDetachedFromWindow();
        stop();
    }
     /**
     * 停止
     */
    private void stop() {
        if (getAnimation() != null) {
            getAnimation().cancel();
        }
        isShown = false;
        removeCallbacks(animRunnable);
    }

第五步:

使用

  <com.qfxl.android.fadingTextView.FadingTextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textColor="@android:color/white"
        android:textSize="30sp"
        qfxl:duration="2000"
        qfxl:texts="@array/arrayTest" />

总结

这个是闲暇时间逛github的时候看到的,觉得挺实用简单,就写了一下。
没事多逛逛github,会发现很多惊喜

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值