package com.itap.voiceemoticon.widget; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.PorterDuff.Mode; import android.graphics.Rect; import android.util.AttributeSet; import android.view.SurfaceHolder; import android.view.SurfaceView; import com.tadpolemusic.R; import com.tadpolemusic.TMLog; /** * 跑马灯效果 * <br>========================== * <br> author:Zenip * <br> email:lxyczh@gmail.com * <br> create:2013-1-26下午12:02:43 * <br>========================== */ public class MarqueeTextSurfaceView extends SurfaceView implements SurfaceHolder.Callback { static final String TAG = "MarqueeTextSurfaceView"; private SurfaceHolder mHolder; private MyThread myThread; private String mText = "Zenip, MarqueeTextSurfaceView"; private int xOffset = 0; private boolean isSurfaceValid = false; public MarqueeTextSurfaceView(Context context) { super(context); init(); } public MarqueeTextSurfaceView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } public MarqueeTextSurfaceView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public void init() { setZOrderOnTop(true); mHolder = getHolder(); mHolder.addCallback(this); myThread = new MyThread(mHolder); mHolder.setFormat(PixelFormat.TRANSPARENT); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { TMLog.step(TAG, "surfaceChanged"); holder.setFixedSize(width, height); } public void setText(String str) { mText = str; } @Override public void surfaceCreated(SurfaceHolder holder) { TMLog.step(TAG, "surfaceCreated"); isSurfaceValid = true; } @Override public void surfaceDestroyed(SurfaceHolder holder) { TMLog.step(TAG, "surfaceDestroyed"); 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 { 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 { xOffset = 0; 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()) { xOffset = 0; myThread = new MyThread(mHolder); myThread.start(); } } public void stopScroll() { myThread.canRun = false; xOffset = 0; } private void handlerDrawInternal(Canvas canvas) { if (canvas == null) { return; } canvas.drawColor(Color.TRANSPARENT, Mode.CLEAR); Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); //创建画笔 paint.setTextSize(spToPixel(getContext(), 12f)); paint.setColor(Color.WHITE); // font height float fontHeight = getFontHeight(paint); int height = mHolder.getSurfaceFrame().height(); int width = mHolder.getSurfaceFrame().width(); Rect textBound = new Rect(); paint.getTextBounds(mText.toCharArray(), 0, mText.length(), textBound); int textWidth = textBound.width(); // base line float baseLineY = height / 2 + fontHeight / 2; canvas.drawText(mText, xOffset, baseLineY, paint); if (xOffset > (width + 10)) { xOffset = -textWidth - 10; } else { xOffset += 1; } } 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; } }