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();
}
}
android怎样写一个循环文字滚动的TextView的更多相关文章
- android 开发 写一个RecyclerView布局的聊天室,并且添加RecyclerView的点击事件
实现思维顺序: 1.首先我们需要准备2张.9的png图片(一张图片为左边聊天泡泡,一个图片为右边的聊天泡泡),可以使用draw9patch.bat工具制作,任何图片导入到drawable中. 2.需要 ...
- Android 自己写一个打开图片的Activity
根据记忆中eoe的Intent相关视频,模仿,写一个打开图片的Activity 1.在主Activity的button时间中,通过设置action.category.data打开一个图片.这时代码已经 ...
- 【Vue.js】代码优化:在dom中加一行v-if就可少写一个循环类方法
[问题描述] 把当前用户的购物车中(cartList),商品(good)选中字段checked = true的商品在订单页面中进行展示出来. [一般做法](两次循环) 首先取出当前用户的购物车列表,循 ...
- 自己写一个jQuery垂直滚动栏插件(panel)
html中原生的滚动栏比較难看,所以有些站点,会自己实现滚动栏,导航站点hao123在一个側栏中,就自己定义了垂直滚动栏,效果比較好看,截图例如以下: watermark/2/text/aHR0cDo ...
- 在Android 下写一个检测软件版本号 以自动升级APP 的插件
直接上图上代码: 1.插件类的编写 工程目录结构图: 代码如下: package org.apache.cordova.versionupdate; import org.apache.cordova ...
- Android学习--写一个发送短信的apk,注意布局文件的处理过程!!!
刚开始写Android程序如图发现使用了findViewById方法之后输出的话居然是null(空指针错误),也就是说这个方法没有成功.网上说这样写是在activity_main .xml去找这个ID ...
- 用android去写一个小程序
前言: 软工的一个小作业:实现"黄金分割小游戏", 需要结对编程,队友:陈乐云 共用时两天. 早期思路设计: 采用键值对的形式,以Map作为存储结构.优点:能够将数据与用户对 ...
- Android下写一个永远不会被KILL掉的进程/服务
Android 系统对于内存管理有自己的一套方法,为了保障系统有序稳定的运信,系统内部会自动分配,控制程序的内存使用.当系统觉得当前的资源非常有限的时候,为了保证一些优先级高的程序能运行,就会杀掉一些 ...
- Android Studio 制作一个循环播报的效果
这个就是用到了一个TextView 控件,直接上代码. <TextView android:id="@+id/tv_7" android:layout_width=" ...
随机推荐
- CDN的全称是Content Delivery Network,即内容分发网络
CDN的全称是Content Delivery Network,即内容分发网络 http://baike.baidu.com/link?url=Wd-IGGgslfJemdpuT3Y0BUi88RPQ ...
- linux 分区
1.硬盘分区分为基本分区和扩展分区, 扩展分区分下去就是逻辑分区,而且逻辑分区没有数量上的限制. 2.查看linux系统分区具体情况 fdisk - l 3.查看某个目录是哪个分区下的 df /boo ...
- vsftp关于"550 create directory operation failed"问题解决
前提: 昨天晚上配置好了vsftp, 但登陆后,除了浏览,什么也干不了.(如新建文件/文件夹, 删除文件, 重命名等都不可操作) 都是弹出 "550 create directory ope ...
- 1.3.4 try-with-resources (TWR)
其基本设想是把资源(比如文件或类似的东西)的作用域限定在代码块内,当程序离开这个代码块时,资源会被自动关闭: 要确保try-with-resources生效,正确的用法是为各个资源声明独立变量: 目前 ...
- 【Jquery EasyUI + Servlet】DataGrid,url请求带中文出现乱码的解决方案
demo.jsp: <% String name = "乱码"; %> $(function(){ $('#dg').datagrid({ url: 'DemoServ ...
- Jquery 学习插件第一天
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title&g ...
- PHP判断是否微新浏览器
$inwechat = false; $user_agent = $_SERVER['HTTP_USER_AGENT']; if (strpos($user_agent, 'MicroMessenge ...
- IE6浏览器兼容问题及部分解决方案(网上整理)
作为一个初涉前端技术的IT菜鸟,IE浏览器的兼容问题是一个不得不跨越的坎.为了能够在不同浏览器达到同样的显示效果,就不得不花心思想出办法实现兼容.由于各大主流浏览器内核不同,各自的实现标准有所差异,因 ...
- 导出函数结构 EXPORT_DIRECTORY
typedef struct _IMAGE_EXPORT_DIRECTORY { DWORD Characteristics; DWORD TimeDateStamp; //输出表的创建时间 WORD ...
- ARM汇编指令(未完待续)
ARM指令自己在看的时候,看完之后就忘了,根本记不住,而且有些ARM汇编指令在平常的时候可能根本就用不到,所以也没必要把所有的ARM指令都去记忆,所以自己就想着不去一遍一遍的复习ARM指令,而是在平常 ...