android如何写一个循环文字滚动的TextView

效果图:

在layout中这样来声明:

	<com.kaixin001.view.ScrollText android:id="@+id/news_statustxt"
		    android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:paddingLeft="10dp"
			android:paddingRight="10dp"
			android:layout_gravity="center_vertical"
			android:textColor="#000000"
			android:textSize="16sp"
			android:hint="@string/news_state_hint"
			android:inputType="text"/>

activity这样来调用:

   private void initStatus(){
    	ivState = (ImageView) findViewById(R.id.news_statusinput);
    	//必须使text长度比控件的宽度大
    	String s = "dsafsdfsdf(#开心)fsgfdg(#闭嘴)fdgdfgdfgdfgdfgdfgfdgfdgfdgfdgdfg";
    	newsModel.setStatus(s);
    	String strModel = newsModel.getStatus();
        setStateText(strModel);

	}

	private void setStateText(String strModel){
		if(!TextUtils.isEmpty(strModel)){
			tvState.setStateList(newsModel.getStateList());
			tvState.setText(strModel);
            tvState.init(getWindowManager(), handler);
            tvState.startScroll();
            tvState.start();
        }
	}
	<pre name="code" class="java"> <span style="white-space:pre">	</span> public void setStatus(String status){
    	this.status = status;
    	if(!TextUtils.isEmpty(status)){
    		stateList = ParseNewsInfoUtil.parseStr(status);
    	}
   <span style="white-space:pre">	</span>}

private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case ScrollText.TEXT_TIMER:if(tvState != null){tvState.scrollText();}break;default:break;}}};


import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.Style;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.WindowManager;
import android.widget.TextView;
import com.kaixin001.item.LinkInfo;
import com.kaixin001.model.StateFaceModel;

public class ScrollText extends TextView {

	public static final int TEXT_TIMER = 100;
	private float textLength = 0f;// 文本长度
	private float viewWidth = 0f;
	private float step = 0f;// 文字的横坐标
	private float y = 0f;// 文字的纵坐标
	private float temp_view_plus_text_length = 0.0f;// 用于计算的临时变量
	private float temp_view_plus_two_text_length = 0.0f;// 用于计算的临时变量
	private boolean isStarting = false;// 是否开始滚动
	private int left = 0;
	private int right = 0;
	private Paint paint = null;// 绘图样式
	private String text = "";// 文本内容
	private Bitmap txtBmp;
	private Canvas txtCanvas;
	private FontMetrics fontMetrics;
	private Timer timer = new Timer();
	private ArrayList<LinkInfo> stateList;

	Handler handler;

	TimerTask task = new TimerTask() {
		public void run() {
			if (handler != null && isStarting) {
				Message msg = Message.obtain();
				msg.what = TEXT_TIMER;
				handler.sendMessage(msg);
			}
		}
	};

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

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

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

	/** */
	/**
	 * 文本初始化,每次更改文本内容或者文本效果等之后都需要重新初始化一下
	 */
	public void init(WindowManager windowManager, Handler handler) {
		try {
			this.handler = handler;
			paint = new Paint();
			paint.setAntiAlias(true);
			paint.setStyle(Style.STROKE);
			paint.setTextSize(getTextSize());
			paint.setColor(getCurrentTextColor());
			text = getText().toString();
			textLength = 0;
			// textLength = paint.measureText(text);
			int len = stateList.size();
			for (int i = 0; i < len; i++) {
				LinkInfo info = stateList.get(i);
				if (info.isFace()) {// 表情符排版
					Bitmap faceBmp = StateFaceModel.getInstance()
							.getSmallFaceIcon(info.getContent());
					int xLen = faceBmp.getWidth();
					textLength += xLen + 4;
					continue;
				}
				String strContent = info.getContent();
				float xLen = paint.measureText(strContent);
				textLength += xLen;
			}
			left = this.getPaddingLeft();
			right = this.getPaddingRight();
			step = textLength;
			fontMetrics = paint.getFontMetrics();

			y = getPaddingTop();// getTextSize() + getPaddingTop();
			txtBmp = null;
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	public void scrollText() {
		if (!isStarting) {
			return;
		}
		invalidate();
		if (viewWidth < textLength) {
			step += 0.5;
			if (step > temp_view_plus_two_text_length) {
				step = textLength;
			}
		}
	}

	public void setStateList(ArrayList<LinkInfo> stateList) {
		this.stateList = stateList;
	}

	private void setTxtBmp() {
		if (txtBmp == null && fontMetrics != null) {
			y = -paint.ascent();// fontMetrics.bottom -
								// fontMetrics.ascent;//(this.getHeight() -
								// (int)fontMetrics.ascent)/2;
			viewWidth = getWidth() - left - right;
			temp_view_plus_text_length = viewWidth + textLength;
			temp_view_plus_two_text_length = viewWidth + textLength * 2;
			txtCanvas = new Canvas();

			int width = (int) viewWidth;
			float height = getHeight();
			txtBmp = Bitmap.createBitmap(width, (int) height, Config.ARGB_8888);
			txtCanvas.setBitmap(txtBmp);

		}
	}

	/** */
	/**
	 * 开始滚动
	 */
	public void startScroll() {
		isStarting = true;
	}

	/** */
	/**
	 * 停止滚动
	 */
	public void stopScroll() {
		isStarting = false;
		// invalidate();
	}

	public void start() {
		timer.schedule(task, 10, 20);
	}

	public void stop() {
		timer.cancel();
	}

	@Override
	public void onDraw(Canvas canvas) {
		try {
			setTxtBmp();
			if (txtBmp == null) {
				return;
			}
			Paint txtPaint = new Paint();
			txtPaint.setColor(Color.WHITE);
			txtPaint.setStyle(Style.FILL);
			txtCanvas.drawRect(0, 0, txtBmp.getWidth(), txtBmp.getHeight(),
					txtPaint);
			txtPaint.setAntiAlias(true);
			txtPaint.setStyle(Style.STROKE);
			txtPaint.setTextSize(getTextSize());
			txtPaint.setColor(getCurrentTextColor());
			float x = 0;
			// step为text的宽度
			if (viewWidth < textLength) {
				x = temp_view_plus_text_length - step;
			}
			int len = stateList.size();
			float curLen = x;
			for (int i = 0; i < len; i++) {
				LinkInfo info = stateList.get(i);
				if (info.isFace()) {// 表情符排版
					Bitmap faceBmp = StateFaceModel.getInstance()
							.getSmallFaceIcon(info.getContent());
					int xLen = faceBmp.getWidth();
					txtCanvas.drawBitmap(faceBmp, curLen + 2, 0, txtPaint);
					curLen += xLen + 4;
					continue;
				}
				String strContent = info.getContent();
				strContent = strContent.replaceAll("\n", " ");
				float xLen = txtPaint.measureText(strContent);
				//因为x的值一直减少,所以文字可以滚动
				txtCanvas.drawText(strContent, curLen, y, txtPaint); //<span style="font-family: Arial, Helvetica, sans-serif;">txtCanvas早drawtext.txtBmp上也自然也带有这些text</span>

				curLen += xLen;
			}
			canvas.drawBitmap(txtBmp, left, 0, paint);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
		super.onSizeChanged(w, h, oldw, oldh);
		txtBmp = null;
		setTxtBmp();
	}
}

代码:http://download.csdn.net/detail/baidu_nod/7736733

android如何写一个循环文字滚动的TextView

时间: 2024-12-24 08:43:26

android如何写一个循环文字滚动的TextView的相关文章

使用IntentService给自己的Android应用写一个文件下载器。

接着上一篇的http://www.cnblogs.com/zhengxt/p/3657833.html,当我们想给自己的APP写一个文件下载器时,可以用重写IntentService来实现. 使用IntentService有几个好处,IntentService继承于Service,适合拿来处理一些耗时又不需要去管它的任务.把要执行的任务用Intent加入到队列中,IntentService会有一个工作线程来取出队列中的Intent来处理.需要实现抽象方法onHandleIntent方法来执行这些

android如何写一个自定义的dialog可以在Title的位置弹出来

先上效果图: Title的Layout为: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="@dimen/title_h

android如何写一个投票或是表达观点的界面

先上图: 把这些表示观点的view放在一个LinearLayout里: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/repost_vote_tag_list" android:layout_width="fill_parent" android:layout_height="wrap_conten

Android学习--写一个发送短信的apk,注意布局文件的处理过程!!!

刚开始写Android程序如图发现使用了findViewById方法之后输出的话居然是null(空指针错误),也就是说这个方法没有成功.网上说这样写是在activity_main .xml去找这个ID所代表的控件,而现在使用的ADT在layout下除了activity_main .xml还多生成了一个fragment_main.xml.我就是把控件写在了后一个布局文件中.想请问下,使用什么样的方法是在fragment_main.xml去寻找控件呢? 回答:在PlaceHolderFragment

写一个循环,不断的问客户想买什么 ,当用户选择一个商品编号,就把对应的商品加入购物车 ,最终用户输入q退出时,答应购物车的商品

写一个循环,不断的问客户想买什么 ,当用户选择一个商品编号,就把对应的商品加入购物车 ,最终用户输入q退出时,答应购物车的商品products=[["Iphone8",68888],["MacpPro",14800],["Coffee",31],["小米",2499],["Book",80],["Nlke",799]]shopping_cart=[]print(".....商品

html里面有一个控制文字滚动的标签marquee,比较有用。

本节笔者讲述HTML代码中比较特殊的标签,它能使网页中的文字滚动,并且可以控制其滚动的属性. 制作滚动文字 通过本章前面的学习,读者已经能够很好地控制各种段落文字的显示方式,不过无论怎么设置,文字都是静态的.本节笔者讲述HTML代码中比较特殊的标签,它能使网页中的文字滚动,并且可以控制其滚动的属性. 4.3.1 设置文字滚动 HTML技术中使文字滚动的方法是使用双标签<marquee></marquee>.在HTML代码中可使其作用区文字滚动,默认为从右到左,循环滚动.在D:\we

Android 自己写一个打开图片的Activity

根据记忆中eoe的Intent相关视频,模仿,写一个打开图片的Activity 1.在主Activity的button时间中,通过设置action.category.data打开一个图片.这时代码已经可以运行,将使用系统默认的工具打开图片. Intent intentImage = new Intent(Intent.ACTION_VIEW); intentImage.addCategory(Intent.CATEGORY_DEFAULT); File file = new File("/sto

用android去写一个小程序

前言: 软工的一个小作业:实现"黄金分割小游戏", 需要结对编程,队友:陈乐云(http://www.cnblogs.com/clyln/),用时两天. 早期思路设计: 采用键值对的形式,以Map作为存储结构.优点:能够将数据与用户对应,缺点:采用java实现过于复杂,工程量过大,需要消耗大量资源,类型转换容易出错. 后期思路设计: 采用二维数组:第一行用于存储用户输入原始数据,第二行用于存储中间数据(第一行的与G值做差的绝对值),第三行用于保存用户得分. 优点:实现简单,易于运算 分

Android下写一个永远不会被KILL掉的进程/服务

Android 系统对于内存管理有自己的一套方法,为了保障系统有序稳定的运信,系统内部会自动分配,控制程序的内存使用.当系统觉得当前的资源非常有限的时候,为了保 证一些优先级高的程序能运行,就会杀掉一些他认为不重要的程序或者服务来释放内存.这样就能保证真正对用户有用的程序仍然再运行.如果你的 Service 碰上了这种情况,多半会先被杀掉.但如果你增加 Service 的优先级就能让他多留一会,我们可以用 setForeground(true) 来设置 Service 的优先级. 为什么是 fo