textview进阶总结

写在开头

textview,在android中算是很平常的一个控件了,但是基于它的使用还是可以有很多的扩展的!在这总结了下以前项目中用的一些使用,记录下来,供自己还有他人学习!在这分为四部分:

1. textview跑马灯效果,及多条textiview同时滚动出现的问题及解决!
2. 仿淘宝竖直滚动的textview
3. 仿支付宝自动滚动到某一个数字的自定义效果
4. 富文本实现各种组合自定义textview

demo地址https://github.com/loveAndroidAndroid/android-study

效果图如下

这里写图片描述这里写图片描述这里写图片描述

多条跑马灯效果(具体demo看文末链接)

一个textview的跑马灯效果通过修改layout文件就可以,如下:

    android:ellipsize="marquee"
        android:focusable="true"
        android:focusableInTouchMode="true"
        //循环滚动
        android:marqueeRepeatLimit="marquee_forever"

当要求多条textview同时滚动时会出现一些问题,会发现只有一条在滚动,其实这是焦点的问题,因为只有一个textview右焦点。其实解决也不麻烦,我们要自定义我们的自己的textview

    public class FocusedTextView extends TextView {

    public FocusedTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

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

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

    // 检测有没有焦点 返回true 让TextView认为有焦点
    @Override
    public boolean isFocused() {
        return true;
    }

    // 焦点的改变
    @Override
    protected void onFocusChanged(boolean focused, int direction,
                                  Rect previouslyFocusedRect) {
        // 注意参1 改成true 就算焦点改变 也不会停止跑马灯,因为在此处返回true,text默认都有焦点
        super.onFocusChanged(true, direction, previouslyFocusedRect);
    }
}

仿淘宝竖直滚动textview

这里也是通过自定义textview实现。

    public class ScrollTextView extends TextSwitcher implements ViewSwitcher.ViewFactory {

    private Context context;

    // inAnimation,outAnimation分别构成翻页的进出动画
    private ScrollAnimation inAnimation;
    private ScrollAnimation outAnimation;
    private String titleLeft;

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

    public ScrollTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }

    private void init() {
    //创建两个view
        setFactory(this);
        inAnimation = createAnim(-90, 0, true, true);
        outAnimation = createAnim(0, 90, false, true);
        //设置动画
        setInAnimation(inAnimation);
        setOutAnimation(outAnimation);

    }

    private ScrollAnimation createAnim(float start, float end, boolean turnIn,
                                       boolean turnUp) {
        final ScrollAnimation rotation = new ScrollAnimation(start, end,
                turnIn, turnUp);
        //设置时间
        rotation.setDuration(800);
        rotation.setFillAfter(false);
        rotation.setInterpolator(new AccelerateInterpolator());

        return rotation;
    }

    /**
     * 这里返回的TextView,就是我们看到的View
     */
    @Override
    public View makeView() {
        TextView textView = new TextView(context);
        textView.setGravity(Gravity.LEFT);
        textView.setTextSize(15);
        textView.setTextColor(Color.WHITE);
        textView.setGravity(Gravity.CENTER_VERTICAL);// gravity center_vertical
        textView.setText("");
        textView.setSingleLine(true);
        textView.setEllipsize(TextUtils.TruncateAt.END);
        return textView;
    }

    public void next() {
        if (getInAnimation() != inAnimation) {
            setInAnimation(inAnimation);
        }
        if (getOutAnimation() != outAnimation) {
            setOutAnimation(outAnimation);
        }
    }
    //滚动动画
    class ScrollAnimation extends Animation {
        private final float mFromDegrees;
        private final float mToDegrees;
        private float mCenterX;
        private float mCenterY;
        private final boolean mTurnIn;
        private final boolean mTurnUp;
        private Camera mCamera;

        public ScrollAnimation(float fromDegrees, float toDegrees,
                               boolean turnIn, boolean turnUp) {
            mFromDegrees = fromDegrees;
            mToDegrees = toDegrees;
            mTurnIn = turnIn;
            mTurnUp = turnUp;
        }

        @Override
        public void initialize(int width, int height, int parentWidth,
                               int parentHeight) {
            super.initialize(width, height, parentWidth, parentHeight);
            mCamera = new Camera();
            mCenterY = getHeight() / 2;
            mCenterX = getWidth() / 2;
        }

        @Override
        protected void applyTransformation(float interpolatedTime,
                                           Transformation t) {
            final float fromDegrees = mFromDegrees;
            float degrees = fromDegrees
                    + ((mToDegrees - fromDegrees) * interpolatedTime);

            final float centerX = mCenterX;
            final float centerY = mCenterY;
            final Camera camera = mCamera;
            final int derection = mTurnUp ? 1 : -1;

            final Matrix matrix = t.getMatrix();

            camera.save();
            if (mTurnIn) {
                camera.translate(0.0f, derection * mCenterY
                        * (interpolatedTime - 1.0f), 0.0f);
            } else {
                camera.translate(0.0f, derection * mCenterY
                        * (interpolatedTime), 0.0f);
            }
            camera.getMatrix(matrix);
            camera.restore();

            matrix.preTranslate(-centerX, -centerY);
            matrix.postTranslate(centerX, centerY);
        }
    }
}

自动滚动textview

滚动动画只用值动画ValueAnimator 实现。可设置内容类型,动画时间等!
本实现参考大神博客,又不懂的大家讨论。

/**
 * 数字滚动的textView
 */
public class NumberRunningTextView extends TextView {

    private static final int MONEY_TYPE = 0;
    private static final int NUM_TYPE = 1;

    private int textType;//内容的类型,默认是金钱类型
    private boolean useCommaFormat;//是否使用每三位数字一个逗号的格式,让数字显得比较好看,默认使用
    private boolean runWhenChange;//是否当内容有改变才使用动画,默认是
    private int duration;//动画的周期,默认为1000ms
    private int minNum;//显示数字最少要达到这个数字才滚动 默认为1
    private float minMoney;//显示金额最少要达到这个数字才滚动 默认为0.3

    private DecimalFormat formatter = new DecimalFormat("0.00");// 格式化金额,保留两位小数
    private String preStr;


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

    public NumberRunningTextView(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.textViewStyle);
    }

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

        TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.NumberRunningTextView);
        duration = ta.getInt(R.styleable.NumberRunningTextView_duration, 1000);
        textType = ta.getInt(R.styleable.NumberRunningTextView_textType, MONEY_TYPE);
        useCommaFormat = ta.getBoolean(R.styleable.NumberRunningTextView_useCommaFormat, true);
        runWhenChange = ta.getBoolean(R.styleable.NumberRunningTextView_runWhenChange,true);
        minNum = ta.getInt(R.styleable.NumberRunningTextView_minNum, 3);
        minMoney = ta.getFloat(R.styleable.NumberRunningTextView_minMoney,0.1f);

        ta.recycle();
    }


    /**
     * 设置需要滚动的金钱(必须为正数)或整数(必须为正数)的字符串
     *
     * @param str
     */
    public void setContent(String str) {
        //如果是当内容改变的时候才执行滚动动画,判断内容是否有变化
        if (runWhenChange){
            if (TextUtils.isEmpty(preStr)){
                //如果上一次的str为空
                preStr = str;
                useAnimByType(str);
                return;
            }

            //如果上一次的str不为空,判断两次内容是否一致
            if (preStr.equals(str)){
                //如果两次内容一致,则不做处理
                return;
            }

            preStr = str;//如果两次内容不一致,记录最新的str
        }

        useAnimByType(str);
    }

    private void useAnimByType(String str) {
        if (textType == MONEY_TYPE) {
            playMoneyAnim(str);
        } else if (textType == NUM_TYPE){
            playNumAnim(str);
        }
    }


    /**
     * 播放金钱数字动画的方法
     *
     * @param moneyStr
     */
    public void playMoneyAnim(String moneyStr) {
        String money = moneyStr.replace(",", "").replace("-", "");//如果传入的数字已经是使用逗号格式化过的,或者含有符号,去除逗号和负号
        try {
            float finalFloat = Float.parseFloat(money);
            if (finalFloat < minMoney) {
                //如果传入的为0,则直接使用setText()
                setText(moneyStr);
                return;
            }
            ValueAnimator floatAnimator =  ValueAnimator.ofFloat(0, finalFloat);
            floatAnimator.setDuration(duration);
            floatAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    float currentNum = (float) animation.getAnimatedValue();
                    String str = formatter.format(Double.parseDouble(String.valueOf(currentNum)));//格式化成两位小数
                    // 更新显示的内容
                    if (useCommaFormat) {
                        //使用每三位数字一个逗号的格式
                        String formatStr = StringUtils.addComma(str);//三位一个逗号格式的字符串
                        setText(formatStr);
                    } else {
                        setText(str);
                    }
                }
            });
            floatAnimator.start();
        } catch (NumberFormatException e) {
            e.printStackTrace();
            this.setText(moneyStr);//如果转换Double失败则直接用setText
        }
    }

    /**
     * 播放数字动画的方法
     *
     * @param numStr
     */
    public void playNumAnim(String numStr) {
        String num = numStr.replace(",", "").replace("-", "");//如果传入的数字已经是使用逗号格式化过的,或者含有符号,去除逗号和负号
        try {
            int finalNum = Integer.parseInt(num);
            if (finalNum < minNum) {
                //由于是整数,每次是递增1,所以如果传入的数字比帧数小,则直接使用setText()
                this.setText(numStr);
                return;
            }
            ValueAnimator intAnimator = new ValueAnimator().ofInt(0, finalNum);
            intAnimator.setDuration(duration);
            intAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    int currentNum = (int) animation.getAnimatedValue();
                    setText(String.valueOf(currentNum));
                }
            });
            intAnimator.start();
        } catch (NumberFormatException e) {
            e.printStackTrace();
            setText(numStr);//如果转换Double失败则直接用setText
        }
    }
}

使用很简单了

    tvMoney.setContent("1454.00");
        tvNum.setContent("300");

富文本实现各种效果

以前总结过,想看的请看下面链接,其中还要一些别的总结!

http://blog.csdn.net/say_from_wen/article/details/76177299

写在文末

关于textview的使用,大家有什么好的自定义和别人大神的链接也发出来,一起学习,共同进步!

  • 6
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值