Android三种方式实现TextView跑马灯效果

来源:互联网 发布:淘宝上货软件哪个好用 编辑:程序博客网 时间:2024/05/24 04:23

写了好几次Android跑马灯效果。今天总结一下,方便以后查看。

以下记录三种方式实现TextView文字滚动的效果,最后一种没试过。

第一种:原生的android自带的跑马灯效果。直接申明TextView属性。

第二种:改造TextView,自定义View继承的TextView,利用Runnable循环调用onDraw()方法更新视图。

第三种:利用HorizontalScrollView控件的特性,里面加个TextView,通过定时器让HorizontalScrollView循环滑动,达到跑马灯效果。

第四种:还有一种方法是用平移动画无限循环移动view的方式,没用过。

前三种方法的利弊:

三种方法都有微妙的差别,并对兼容性有要求。

第一种:速度不能控制,焦点不在TextView上时不能滚动。但因为这是安卓系统的功能,所以基本不用考虑兼容性。还有,当文本长度小于控件长度时也是没有跑马灯效果的。

第二种:可以控制速度、滚动方向。但是部分设备上会有兼容性问题,比如部分设备上出现闪动,而且很难解决,因为这种方式是通过不断重新图形绘制实现,所以会出现这个问题。

第三种:可以控制速度,方向,但是因为HorizontalScrollView控件的特性限制,从scrollTo(x,y)方法就知道,从x=0到x=”文本长度”的过程中是很顺畅的,但是移动到两端的时候就会出现卡顿的现象,不能很流畅的延一个方向移动。

下面可以看代码:

第一种很简单:

<TextView        android:id="@+id/myTextView"        android:layout_width="50dp"        android:layout_height="wrap_content"        android:layout_centerInParent="true"        android:ellipsize="marquee"        android:focusable="true"        android:marqueeRepeatLimit="marquee_forever"        android:singleLine="true"        android:text="文本区域"        android:textColor="@android:color/black" > </TextView>

这段代码就可以实现跑马灯的效果。

第二种:

自定义的TextView

public class MarqueeTextView extends TextView implements Runnable {    private int currentScrollX;// 当前滚动的位置    private boolean isStop = false;    private int textWidth;    private boolean isMeasure = false;    public MarqueeTextView(Context context) {            super(context);            // TODO Auto-generated constructor stub    }    public MarqueeTextView(Context context, AttributeSet attrs) {            super(context, attrs);    }    public MarqueeTextView(Context context, AttributeSet attrs, int defStyle) {            super(context, attrs, defStyle);    }    @Override    protected void onDraw(Canvas canvas) {            // TODO Auto-generated method stub            super.onDraw(canvas);            if (!isMeasure) {// 文字宽度只需获取一次就可以了                    getTextWidth();                    isMeasure = true;            }    }    /**     * 获取文字宽度     */    private void getTextWidth() {            Paint paint = this.getPaint();            String str = this.getText().toString();            textWidth = (int) paint.measureText(str);    }    @Override    public void run() {            currentScrollX -= 1;// 滚动速度            scrollTo(currentScrollX, 0);            if (isStop) {                    return;            }            if (getScrollX() <= -(this.getWidth())) {                    scrollTo(textWidth, 0);                    currentScrollX = textWidth;    //              return;            }            postDelayed(this, 10);    }    // 开始滚动    public void startScroll() {            isStop = false;            this.removeCallbacks(this);            post(this);    }    // 停止滚动    public void stopScroll() {            isStop = true;    }    // 从头开始滚动    public void startFor0() {        currentScrollX = 0;        startScroll();    }    @Override    public void setText(CharSequence text, BufferType type) {        // TODO Auto-generated method stub        super.setText(text, type);        startScroll();    }    @Override    public void destroyDrawingCache() {        // TODO Auto-generated method stub        super.destroyDrawingCache();    }}

这个自定义控件只要在layout文件中引用即可:

public class HorizontalScorllTextView extends HorizontalScrollView implements Runnable{    int currentScrollX = 0;// 当前滚动的位置    TextView tv;    public HorizontalScorllTextView(Context context) {        super(context);        initView(context);    }    public HorizontalScorllTextView(Context context, AttributeSet attrs) {        super(context, attrs);        initView(context);    }    public HorizontalScorllTextView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        initView(context);    }    void initView(Context context){        View v = LayoutInflater.from(context).inflate(R.layout.scroll_layout, null);        tv = (TextView)v.findViewById(R.id.tv_video_name);        this.addView(v);    }    public void setText(String text){        tv.setText(text);        startScroll();    }    private void startScroll(){        this.removeCallbacks(this);        post(this);    }    @Override    public void run() {        // TODO Auto-generated method stub        currentScrollX ++;// 滚动速度        scrollTo(currentScrollX, 0);        if (currentScrollX >= tv.getWidth()) {                scrollTo(0, 0);                currentScrollX = 0;        }        postDelayed(this, 50);    }}

这种方法跟第二种差不多,只是文本是在构造函数中加进来一个layout文件,就是引进了textview,然后跟第二种方式一样循环滚动scrollview。

还有一个需要注意的地方就是第三种方法必须要在java代码中使用setText()方法,因为这控件中是在setText中使能滑动功能的。

0 0
原创粉丝点击