按道理跑马灯功能Android已经实现了,但自定义的跑马灯功能是通过SurfaceView来实现,使用子线程来更新视图,性能更好,跑马灯的启动和停止都是由自己控制,更加灵活。
public class MarqueeTextSurfaceView extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder mHolder; private MyThread myThread; private String mText = ""; private boolean isSurfaceValid = false; private float textLength = 0f;// 文本长度 private float viewWidth = 880.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 int speed = 10; private Paint paint = null;// 绘图样式 public MarqueeTextSurfaceView(Context context) { super(context); } public MarqueeTextSurfaceView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public MarqueeTextSurfaceView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { holder.setFixedSize(width, height); } public void setText(String str) {// 设置跑马灯的内容 mText = str; textLength = paint.measureText(mText); temp_view_plus_two_text_length = viewWidth + textLength * 2f; // viewWidth = mHolder.getSurfaceFrame().width(); step = textLength; temp_view_plus_text_length = viewWidth + textLength; } public void setSpeed(int speed) {// 设置跑马灯的速度 this.speed = speed; } public void canScroll() { isSurfaceValid = true; } public void suspend() {// 选中获焦跑马灯暂停 step = temp_view_plus_text_length - 20; } public void init() {// 初始化 setZOrderOnTop(true); mHolder = getHolder(); mHolder.addCallback(this); myThread = new MyThread(mHolder); mHolder.setFormat(PixelFormat.TRANSPARENT); paint = new Paint(Paint.ANTI_ALIAS_FLAG); // 创建画笔 paint.setTextSize(spToPixel(getContext(), 20f)); paint.setColor(getResources().getColor(R.color.marquee)); y = getFontHeight(paint); canScroll(); } @Override public void surfaceCreated(SurfaceHolder holder) { isSurfaceValid = true; } @Override public void surfaceDestroyed(SurfaceHolder holder) { isSurfaceValid = false; } class MyThread extends Thread { private SurfaceHolder holder; public boolean canRun; public MyThread(SurfaceHolder holder) { this.canRun = true; this.holder = holder; } @Override public void run() { Canvas c = null; while (canRun && isSurfaceValid) { try { // Thread.sleep(50); c = holder.lockCanvas();// 锁定画布,一般在锁定后就可以通过其返回的画布对象Canvas,在其上面画图等操作了。 handlerDrawInternal(c); } catch (Exception e) { e.printStackTrace(); } finally { if (c != null) { holder.unlockCanvasAndPost(c);// 结束锁定画图,并提交改变。 } } try { Thread.sleep(30); } catch (InterruptedException e) { e.printStackTrace(); }// 睡眠时间为1秒 } // reset try { c = holder.lockCanvas(); handlerDrawInternal(c); } catch (Exception e) { e.printStackTrace(); } finally { if (c != null) { holder.unlockCanvasAndPost(c); } } } } public void startScroll() {// 跑马灯启动 if (!isSurfaceValid) { return; } // myThread.canRun = true; if (!myThread.isAlive()) { myThread = new MyThread(mHolder); myThread.start(); } } public void stopScroll() {// 跑马灯停止 myThread.canRun = false; isSurfaceValid = false; // myThread.interrupt(); } private void handlerDrawInternal(Canvas canvas) { if (canvas == null) { return; } step += speed; if (step >= temp_view_plus_two_text_length)// 达到一定限值,跑马灯重新进行 step = textLength; canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); canvas.drawText(mText, 0, mText.length(), temp_view_plus_text_length - step, y, paint); } private static float getFontHeight(Paint paint) {// 获得字体高度 Rect bounds = new Rect(); paint.getTextBounds("这", 0, 1, bounds); return bounds.height(); } // private static float pixelsToSp(Context context, Float px) { // float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity; // return px / scaledDensity; // } private static float spToPixel(Context context, Float sp) { float scaledDensity = context.getResources().getDisplayMetrics().scaledDensity; return sp * scaledDensity; } }
欢迎大家下载个人开发的软件:http://android.myapp.com/myapp/detail.htm?apkName=com.yln.history
感谢大家支持!
精彩科技工作室