Android 开发之轻量级文本动画

来源:互联网 发布:java动态代理模式 编辑:程序博客网 时间:2024/06/17 00:51

Android 开发之轻量级文本动画

转载请注明出处 传送门 本文出自【付小华的博客】

引言

在掘金上看到推文,用JS实现了文字动画和数字动画 animate text,效果如下:
图片

文本动画, 几行代码页面效果瞬间就提升了

自己就在Android端简单粗暴地模仿了一个,具体实现就是handler,random,效果如下:
图片

使用

<xxxxxxxx.widget.AnimateText    android:id="@+id/animationText1"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:layout_marginTop="50dp"    android:lines="10"    android:text="\u3000\u3000寄居在桂子山叔叔家中,不觉已是两个多月了,居室的环境极为情幽静谧,古朴自然之中又透着一种雅致。特别是那满山的木樨,中秋一过,便黄灿灿地开满枝头,悠悠的香气随风飘送。昨夜,西风渐紧,刮得楼下梧桐树“沙沙”地响,躺在床上,心想,明晨,又该是花落知多少了!今早推门一看,湿湿的水泥小径上,满是枯枝败叶,再细看枝叶间,黄灿灿的一片,竟是桂花!不由得脱口而出一句诗来:昨夜西风过园林,吹落黄花满地金!不禁心头一动,眼前幻化出父亲的影子来。"    android:textColor="@color/colorPrimary"    android:textSize="16sp" /><Button    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_marginTop="10dp"    android:onClick="animation1"    android:text="重新播放" /><xxxxxxxx.widget.AnimateText    android:id="@+id/animationText2"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:layout_marginTop="50dp"    android:text="666666.66"    android:textColor="@color/colorPrimary"    android:textSize="25sp"    app:changeCount="50"    app:isNumber="true" />    <Button    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:layout_marginTop="10dp"    android:onClick="animation2"    android:text="重新播放" />

代码

import android.content.Context;import android.content.res.TypedArray;import android.os.Handler;import android.os.Looper;import android.support.annotation.Nullable;import android.support.v7.widget.AppCompatTextView;import android.util.AttributeSet;import com.shenhua.newscachedemo.R;import java.util.Random;/** * Created by shenhua on 4/11/2017. * Email shenhuanet@126.com */public class AnimateText extends AppCompatTextView {    private Handler handler = new Handler(Looper.getMainLooper());    private boolean annimaStart = false; // 开始时是否展示动画    private boolean isNumber = false; // 是否渲染为数字动画    private int time = 20;// 动画时长    private int changeCount = 32; // 数字动画数字变化次数    private int startNumber = 0; // 渲染为数字动画时 动画的开始数字    private int endNumber = 0; // 渲染为数字动画时 动画的结束数字    private OnAnimationEndListener listener;// 动画结束时的监听    private String text;// 文本    public AnimateText(Context context) {        this(context, null);    }    public AnimateText(Context context, @Nullable AttributeSet attrs) {        this(context, attrs, 0);    }    public AnimateText(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        if (attrs != null) {            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AnimateText);            annimaStart = a.getBoolean(R.styleable.AnimateText_annimaStart, false);            isNumber = a.getBoolean(R.styleable.AnimateText_isNumber, false);            time = a.getInteger(R.styleable.AnimateText_time, 20);            changeCount = a.getInteger(R.styleable.AnimateText_changeCount, 32);            a.recycle();        }        text = getText().toString();        if (isNumber) {            startNumber = text.length() - 1;            endNumber = (int) Float.parseFloat(text);        }        if (annimaStart) {            startAnimate();        }    }    public void startAnimate() {        this.startAnimate(null);    }    public void startAnimate(final OnAnimationEndListener listener) {        this.listener = listener;        new Thread(new Runnable() {            @Override            public void run() {                if (isNumber) {                    showNumAnimate();                } else {                    showNormalAnimate();                }            }        }).start();    }    private void showNormalAnimate() {        char[] cs = text.toCharArray();        final StringBuffer buffer = new StringBuffer();        for (char c : cs) {            buffer.append(c);            try {                Thread.sleep(time);            } catch (InterruptedException e) {                e.printStackTrace();            }            handler.post(new Runnable() {                @Override                public void run() {                    AnimateText.this.setText(buffer.toString(), BufferType.NORMAL);                }            });        }        handler.post(new Runnable() {            @Override            public void run() {                if (listener != null) {                    listener.onEnd();                }            }        });    }    private void showNumAnimate() {        for (int i = 0; i < changeCount; i++) {            final float t = nextFloat();            try {                Thread.sleep(time);            } catch (InterruptedException e) {                e.printStackTrace();            }            handler.post(new Runnable() {                @Override                public void run() {                    setText(String.valueOf(t), BufferType.NORMAL);                }            });        }        handler.post(new Runnable() {            @Override            public void run() {                setText(text, BufferType.NORMAL);            }        });    }    private float nextFloat() {        return startNumber + ((endNumber - startNumber) * new Random().nextFloat());    }    public int getTime() {        return time;    }    public void setTime(int time) {        this.time = time;    }    public boolean isAnnimaStart() {        return annimaStart;    }    public void setAnnimaStart(boolean annimaStart) {        this.annimaStart = annimaStart;    }    public boolean isNumber() {        return isNumber;    }    public void setNumber(boolean number) {        isNumber = number;    }    public int getStartNumber() {        return startNumber;    }    public void setStartNumber(int startNumber) {        this.startNumber = startNumber;    }    public int getChangeCount() {        return changeCount;    }    public void setChangeCount(int changeCount) {        this.changeCount = changeCount;    }    public void setText(String text) {        this.text = text;        setText(text, BufferType.NORMAL);    }    public OnAnimationEndListener getListener() {        return listener;    }    public void setListener(OnAnimationEndListener listener) {        this.listener = listener;    }    public interface OnAnimationEndListener {        void onEnd();    }}
  • attr.xml
<?xml version="1.0" encoding="utf-8"?><resources>    <declare-styleable name="AnimateText">        <attr name="time" format="integer" />        <attr name="annimaStart" format="boolean" />        <attr name="isNumber" format="boolean" />        <attr name="changeCount" format="integer" />    </declare-styleable></resources>
  • 可使用的方法
    setter 方法均可在外部调用,代码中已有详细说明。

好了,就这么多。

0 0