Android-两种方式实现走马灯效果

第一种方法(很普遍,很简单的在xml布局文件中设置TextView的属性):

<TextView
        android:id="@+id/tv_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ellipsize="marquee"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:marqueeRepeatLimit="marquee_forever"
        android:singleLine="true"
        android:textSize="28sp"
        android:text="路漫漫其修远兮,吾将上下而求索"
        android:textColor="#00ff00"
        android:scrollHorizontally="true"/>

重要代码:

//设置为跑马灯显示

android:ellipsize="marquee"

//获取焦点
          android:focusable="true"

//可以通过toucth来获得focus
          android:focusableInTouchMode="true"

//设置重复的次数
          android:marqueeRepeatLimit="marquee_forever"

//单行显示文字
        android:singleLine="true"

2.第二种方法,由于大部分走马灯文字会在手机屏幕的右侧开始,这需要自定义控件来实现了

java代码:

package com.example.cameratestdemo;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

/**
 * 自定义控件循环走马灯的实现
 *
 * @author cyf 继承自TextView
 */
public class Util extends TextView implements Runnable {
    private static final String TAG = "MarqueeTextView";
    // 设置跑马灯重复的次数,次数
    private int circleTimes = 3;
    //记录已经重复了多少遍
    private int hasCircled = 0;
    private int currentScrollPos = 0;
    // 跑马灯走一遍需要的时间(秒数)
    private int circleSpeed = 10;
    // 文字的宽度
    private int textWidth = 0;

    private boolean isMeasured = false;
    // Handler机制
    private Handler handler;
    private boolean flag = false;

    // 构造方法
    public Util(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        this.removeCallbacks(this);
        post(this);
    }
    /**
     * 画笔工具
     */
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (!isMeasured) {
            getTextWidth();
            isMeasured = true;
        }
    }

    @Override
    public void setVisibility(int visibility) {
        // 二次进入时初始化成员变量
        flag = false;
        isMeasured = false;
        this.hasCircled = 0;
        super.setVisibility(visibility);
    }

    @Override
    public void run() {
        // 起始滚动位置
        currentScrollPos += 1;
        scrollTo(currentScrollPos, 0);
        // Log.i(TAG, "pos"+currentScrollPos);
        // 判断滚动一次
        if (currentScrollPos >= textWidth) {
            // 从屏幕右侧开始出现
            currentScrollPos = -this.getWidth();
            //记录的滚动次数大设定的次数代表滚动完成,这个控件就可以隐藏了
            if (hasCircled >= this.circleTimes) {
                this.setVisibility(View.GONE);
                flag = true;
            }
            hasCircled += 1;
        }

        if (!flag) {
            // 滚动时间间隔
            postDelayed(this, circleSpeed);
        }
    }

    /**
     * 获取文本显示长度
     */

    private void getTextWidth() {
        Paint paint = this.getPaint();
        String str = this.getText().toString();
        Log.i(TAG, str);
        if (str == null) {
            textWidth = 0;
        }
        textWidth = (int) paint.measureText(str);
    }

    /**
     * 设置滚动次数,达到次数后设置不可见
     *
     * @param circleTimes
     */
    public void setCircleTimes(int circleTimes) {
        this.circleTimes = circleTimes;
    }

    public void setSpeed(int speed) {
        this.circleSpeed = speed;
    }

    public void startScrollShow() {
        if (this.getVisibility() == View.GONE)
            this.setVisibility(View.VISIBLE);
        this.removeCallbacks(this);
        post(this);
    }

    private void stopScroll() {
        handler.removeCallbacks(this);
    }
}

布局文件中呀使用自定义控件了:

<com.example.cameratestdemo.Util
        android:id="@+id/tv_text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ellipsize="marquee"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:marqueeRepeatLimit="marquee_forever"
        android:scrollHorizontally="true"
        android:singleLine="true"
        android:text="路漫漫其修远兮,吾将上下而求索"
        android:textColor="#00ff00"
        android:textSize="28sp" >
    </com.example.cameratestdemo.Util>

源码下载:

http://yunpan.cn/c3kL7ILLL7tCt  访问密码 bd75

欢迎提出意见,希望可以给大家带来帮助,谢谢

时间: 2024-11-07 03:39:58

Android-两种方式实现走马灯效果的相关文章

Android 两种方式实现类似水波扩散效果

原文链接 https://mp.weixin.qq.com/s/M19tp_ShOO6esKdozi7Nlg 两种方式实现类似水波扩散效果,先上图为敬 自定义view实现 动画实现 自定义view实现 思路分析:通过canvas画圆,每次改变圆半径和透明度,当半径达到一定程度,再次从中心开始绘圆,达到不同层级的效果,通过不断绘制达到view扩散效果 private Paint centerPaint; //中心圆paint private int radius = 100; //中心圆半径 pr

Android 两种方式播放视频

主MainActivity的布局配置文件 这是activity_main.xml.主要出现两个按钮,按钮一通过mediaplayer播放,按钮二通过videoview播放 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:layout_wid

【转】android创建Popwindow弹出菜单的两种方式

方法一的Activity [java] view plaincopy package com.app.test02; import android.app.Activity; import android.os.Bundle; import android.view.Gravity; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import

Android中EditText显示明文与密文的两种方式

效果图   布局文件 <?xml version="1.0" encoding="utf-8"?> <!-- Android中EditText显示明文与密文的两种方式 --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/to

Android 应用开发 之通过AsyncTask与ThreadPool(线程池)两种方式异步加载大量数据的分析与对比--转载

 在加载大量数据的时候,经常会用到异步加载,所谓异步加载,就是把耗时的工作放到子线程里执行,当数据加载完毕的时候再到主线程进行UI刷新.在数据量非常大的情况下,我们通常会使用两种技术来进行异步加载,一是通过AsyncTask来实现,另一种方式则是通过ThreadPool来实现,今天我们就通过一个例子来讲解和对比这两种实现方式.     项目的结构如下所示:     在今天这个例子里,我们用到了之前一篇文章中写过的一个自定义控件,如果有同学感兴趣的话可以点击这里来先研究下这个控件的实现,为了配合异

Android实战简易教程-第四十九枪(两种方式实现网络图片异步加载)

加载图片属于比较耗时的工作,我们需要异步进行加载,异步加载有两种方式:1.通过AsyncTask类进行:2.通过Handler来实现,下面我们就来看一下如何通过这两种方式实现网络图片的异步加载. 一.AsyncTask方式 1.main.xml: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.co

Android提交数据到服务器的两种方式四种方法

Android应用开发中,会经常要提交数据到服务器和从服务器得到数据,本文主要是给出了利用http协议采用HttpClient方式向服务器提交数据的方法. /** * @author Dylan * 本类封装了Android中向web服务器提交数据的两种方式四种方法 */ public class SubmitDataByHttpClientAndOrdinaryWay { /** * 使用get请求以普通方式提交数据 * @param map 传递进来的数据,以map的形式进行了封装 * @p

Android解析XML文档的两种方式的简单对比

Android之所以会用到解析XML文档,不仅与JAVA对XML的解析比较简单,而且还因为XML是Android在网络间传递信息的主要存储方式.下面我简单谈谈Android对XML文档解析的两种方式:dom和sax.dom解析方式是,解析方法将一个XML文件看成是一棵树.由数据结构的知识我们知道对树的处理比较简单,就是对树的节点进行增,删,改,查,这也是dom的一个最大优点.但是,dom方式在解析的时候是一次性就将整个XML文档读进内存,这坏处不用我说了吧,我宝贵的内存是禁不起这么折腾的. sa

Android模拟点击的两种方式

导论 在Android中模拟一个点击事件有两种方式是通过模拟MotionEvent来实现:一种是通过ADB来实现 第一种:模拟MotionEvent 通用方法如下: private void setSimulateClick(View view, float x, float y) { long downTime = SystemClock.uptimeMillis(); final MotionEvent downEvent = MotionEvent.obtain(downTime, dow