/** * 跑马灯效果 */ public class AlwaysMarqueeTextView extends SurfaceView implements SurfaceHolder.Callback { private SurfaceHolder mHolder; private MyThread myThread; private String mText = "Zenip, MarqueeTextSurfaceView"; private int xOffset = 0; private boolean isSurfaceValid = false; public AlwaysMarqueeTextView(Context context) { super(context); init(); } public AlwaysMarqueeTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } public AlwaysMarqueeTextView(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) { holder.setFixedSize(width, height); } public void setText(String str) { mText = str; } int height = 0, width = 0; @Override public void surfaceCreated(SurfaceHolder holder) { isSurfaceValid = true; height = mHolder.getSurfaceFrame().height(); width = mHolder.getSurfaceFrame().width(); xOffset = width + 10; startScroll(); } @Override public void surfaceDestroyed(SurfaceHolder holder) { isSurfaceValid = false; stopScroll(); } 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(10); } catch (InterruptedException e) { e.printStackTrace(); }//睡眠时间为1秒 } // reset try { xOffset = width + 10; c = holder.lockCanvas(); handlerDrawInternal(c); } catch (Exception e) { e.printStackTrace(); } finally { if (c != null) { holder.unlockCanvasAndPost(c); } } } } private void startScroll() { if (!isSurfaceValid) { return; } myThread.canRun = true; if (!myThread.isAlive()) { xOffset = width + 10; myThread = new MyThread(mHolder); myThread.start(); } } private 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); 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 < (-textWidth - 10)) { xOffset = width +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; } }
android 跑马灯效果
最新推荐文章于 2024-10-18 19:04:33 发布