自定义TextView滚动

public class AnimTextView extends TextView{
    private static final String TAG = AnimTextView.class.getSimpleName();
    private float mFold = 1.0f;//其他列的动画时常的倍数
    private float mW;//单列的宽
    private int mLayoutH;//StaticLayout高
    private float mSpacingmult = 1.0f;//StaticLayout行间距的倍数1.0为正常值

    private int mAddMax = 3;//控制递增动画,递增的量
    private ArrayList<String> mStrList = new ArrayList<String>();//生成的String集合
    private ArrayList<Scroller> mScrList = new ArrayList<Scroller>();//滚动类集合
    private ArrayList<StaticLayout> mLayoutList = new ArrayList<StaticLayout>();//绘制String的Layout集合

    public AnimTextView(Context context) {
        super(context);
    }

    public AnimTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public AnimTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * 开启新数据替换老数据的动画
     * @param oldNum 老数据
     * @param newNum 新数据
     */
    public void setText(String oldNum, String newNum) {
        super.setText(newNum);
        if (TextUtils.isEmpty(oldNum) || TextUtils.isEmpty(newNum)) {
            return;
        }
        clearList();
        makeUnequalData(newNum, oldNum);
    }

    private void makeUnequalData(String oldNum, String newNum){
        StringBuilder sb = new StringBuilder();;
        int l1 = oldNum.length()-1;
        int l2 = newNum.length()-1;
        for (; l1>-1 ||l2 > -1; --l1,--l2) {
            sb.setLength(0);
            mStrList.add(0,sb.append(l1>-1?oldNum.charAt(l1):'0').append("\n").append(l2>-1?newNum.charAt(l2):'0').toString());
        }
    }

    /**
     * 开启递增动画
     * 例:传入值528,会生成三组String,分别是:
     * "5\n6\n7\n8","2\n3\n4\n5","8\n9\n0\n1"
     * 这里的规则是按照mAddMax的条件,生成一串递增+1的字符串
     */
    public void setText(String content, boolean isAnim) {
        super.setText(content);
        clearList();
        for (int i = 0; i < content.length(); i++) {
            char c = content.charAt(i);
            makeData(Integer.parseInt(c + ""));
        }
    }

    public void startAnim() {
        if (mStrList.size() == 0)return;
        int mDur = 1500;//第一列动画的时间基数
        float x = 1+ (mStrList.size() * 0.06f < 0.1?0:mStrList.size() * 0.06f);
        x = x>1.30f?1.30f:x;
        mW = (float) ((getWidth() / mStrList.size())* x);
        mLayoutH = 0;
        TextPaint p = getPaint();
        p.setColor(getCurrentTextColor());
        for (int i = 0; i < mStrList.size(); i++) {
            if (!TextUtils.isEmpty(mStrList.get(i))) {
                StaticLayout layout = new StaticLayout(mStrList.get(i), p, (int) mW, Layout.Alignment.ALIGN_CENTER, mSpacingmult, 0.0F, true);
                mLayoutList.add(layout);
                Scroller scroller = new Scroller(getContext());
                mLayoutH = layout.getHeight();
                scroller.startScroll(0, -mLayoutH, 0, mLayoutH, mDur);
                mScrList.add(scroller);
                mDur = (int) (mDur * mFold);
            }
        }
    }

    private void clearList(){
        mStrList.clear();
        mScrList.clear();
        mLayoutList.clear();
    }

    //按照字体大小+includpad的和返回控件的大小(消除background是大图片的时候是按照图片大小)
    @Override
    protected int getSuggestedMinimumHeight() {
        return Build.VERSION.SDK_INT >16 ? getMinimumHeight():0;
    }

    @Override
    protected int getSuggestedMinimumWidth() {
        return Build.VERSION.SDK_INT >16 ? getMinimumWidth():0;
    }

    private void makeData(int data) {
        StringBuilder sb = new StringBuilder();
        sb.append(data);
        for (int i = 1; i <= mAddMax; i++) {
            int num = data + i;
            if (num > 9) num = num % 10;
            sb.append("\n" + num);
        }
        mStrList.add(sb.toString());
    }

    private String mLast = null;
    @Override
    protected void onDraw(Canvas canvas) {
        CharSequence str = getText();
        if (str == null)return;
        if (str != mLast){
            mLast = str.toString();
            startAnim();
            postInvalidate();
            return;
        }
        if (mStrList.size() == 0 ||mScrList.size() == 0 || mLayoutList.size() == 0){
            super.onDraw(canvas);
            return;
        }
        try {
            boolean invalidate = false;
            for (int i = 0; i < mStrList.size(); i++) {
                canvas.save();
                canvas.translate(i * 3 * mW / 4, 0);
                Scroller scroller = mScrList.get(i);
                if (scroller != null && scroller.computeScrollOffset()) {
                    canvas.translate(0, scroller.getCurrY());
                    invalidate = true;
                }
                StaticLayout layout = mLayoutList.get(i);
                if (layout != null) layout.draw(canvas);
                canvas.restore();
            }
            if (invalidate) postInvalidate();
        }catch (Exception e){
            e.printStackTrace();
        }

        //super.onDraw(canvas);
    }

    public void clearLast(){
        mLast = null;
    }
}

使用方法:

tvAnimtv.setText("0",eduBean.getCreditscore());//0为滚动之前的文字,后面一个参数为滚动之后的文字

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值