`
yaolinnan
  • 浏览: 58049 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
文章分类
社区版块
存档分类
最新评论

Android自定义跑马灯实现(SurfaceView)

 
阅读更多

     按道理跑马灯功能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

感谢大家支持!

精彩科技工作室
分享到:
评论

相关推荐

    android surfaceview自定义拍照 绘制头像轮廓

    这个项目"android surfaceview自定义拍照 绘制头像轮廓"是基于网上现有的示例代码进行了修改,用于实现一个自定义的拍照功能,并且在拍摄的照片上能够绘制出人像的轮廓。下面我们将深入探讨`SurfaceView`以及如何...

    Android自定义SurfaceView——实现画板功能

    本示例中的“Android自定义SurfaceView——实现画板功能”旨在教你如何利用`SurfaceView`创建一个可以画画的应用。`SurfaceView`是Android系统提供的一种用于高效显示动态图像的视图组件,它拥有自己的渲染线程,...

    android自定义相机SurfaceView形式

    android自定义相机SurfaceView形式,SurfaceView是一个功能强大的控件,它拥有独立的绘图表面(不与其宿主窗口共享同一个绘图表面)。由于其拥有独立的绘图表面,因此SurfaceView的UI就可以在一个独立的线程中进行...

    Android圆形相机预览窗口,圆形SurfaceView

    总结起来,实现Android圆形相机预览窗口需要对SurfaceView有深入的理解,包括如何自定义视图、绘制路径以及与相机的交互。通过这个过程,开发者不仅可以创建独特的用户界面,还能提升应用程序的创新性和用户体验。在...

    Android SurfaceView 实现图片缩放 滑动

    综上所述,通过结合SurfaceView、手势检测和矩阵变换,我们可以实现在Android应用中对图片的流畅缩放和滑动操作。然而,由于SurfaceView的特性,这个过程可能会比使用ImageView等其他组件更为复杂。因此,开发者需要...

    Android自定义SurfaceView 拍照,删除+浏览+自动对焦

    在Android应用开发中,自定义SurfaceView来实现拍照、视频录制以及高级功能是一个常见的需求。本文将深入探讨如何使用SurfaceView来创建一个功能完善的拍照应用,包括删除、浏览照片以及自动对焦等功能。 首先,...

    Android自定义view,实现多画面播放器

    本项目"Android自定义view,实现多画面播放器"就是这样一个实例,它旨在提供一个能够同时展示多个视频流并支持交互操作的视图。 首先,自定义View的基本流程包括: 1. 创建一个新的View类,通常继承自View或已有的...

    Android中SurfaceView截屏

    本文将详细介绍如何在Android中实现`SurfaceView`的截屏功能。 首先,了解`SurfaceView`的基本原理。`SurfaceView`创建了一个独立的窗口,并在自己的Surface上绘制内容。这使得它可以在后台线程进行高效的绘制,但...

    android 自定义view之进度条(混合模式)

    1. **自定义View基础**:在Android中,自定义View通常通过继承已有的View或 ViewGroup 类,并重写关键方法来实现。这些方法包括`onDraw()`,用于绘制View的内容;`onMeasure()`,用于确定View的大小;以及`onLayout...

    Android自定义Camera实现拍照功能

    Android自定义Camera实现拍照功能 Android操作系统中,Camera是一个非常重要的组件,通过Camera,我们可以实现拍照、录像等功能。在Android系统中,Camera组件可以分为两种:前置摄像头和后置摄像头。前置摄像头...

    android 自定义控件 小球圆周运动

    在Android开发中,自定义控件是实现独特用户界面效果的重要手段。本教程将深入探讨如何创建一个自定义控件,让小球沿着圆周进行运动。这个过程涉及到Canvas绘图、动画处理以及Android帧率控制等多个核心知识点。 ...

    android自定义SurfaceView源代码

    综上所述,这份"android自定义SurfaceView源代码"可能是为了提供一个高效的游戏渲染框架,利用SurfaceView的优势,实现流畅的动画效果和响应式用户交互。通过分析和学习这个源代码,开发者可以更好地理解和掌握...

    surfaceview 多点触控移动放大缩小

    综上所述,实现SurfaceView的多点触控移动放大缩小涉及到了Android的触摸事件处理、矩阵变换、多线程编程等多个知识点。通过理解并熟练运用这些技术,可以为用户提供流畅且响应迅速的交互体验。在实际开发中,可以...

    android自定义相机带取景框

    创建一个矩形或者其他的形状作为取景框,可以使用ImageView、View或者自定义ViewGroup实现。在布局文件中设定它的大小和位置,使其覆盖在CameraPreview上。你可以使用Shape Drawable定义形状,并通过设置背景颜色或...

    Android自定义相机——身份证扫描界面

    在Android应用开发中,创建一个自定义相机以实现身份证扫描功能是常见的需求。这涉及到对Android系统的相机API的深入理解和自定义布局设计。本篇将详细介绍如何构建这样一个系统,主要针对Android 6.0(API级别23)...

    Android 自定义画布canvas 实现绘制和清空画布功能

    首先,我们需要创建一个自定义View类,这个类将继承自Android的View或SurfaceView。在这个自定义View中,我们将重写`onDraw()`方法,这是绘制图形的主要入口。在`onDraw()`方法中,系统会为我们提供一个Canvas对象,...

    Android自定义照相机实现只拍摄矩形区域(重传)

    首先,要实现自定义相机只拍摄矩形区域,我们需要创建一个继承自`SurfaceView`的类,并覆写`onMeasure`方法来设置相机预览的尺寸。这一步至关重要,因为它决定了相机预览的画面大小,进而影响到矩形区域的显示。我们...

    android 自定义抽奖转盘

    以上就是实现Android自定义抽奖转盘的主要步骤。在实际开发中,可能还需要处理更多细节,例如动画的平滑性、奖品的动态加载、网络数据的同步等。通过不断地调试和优化,可以创建出一个既美观又实用的抽奖转盘组件。

    android surfaceview 悬浮窗圆角 windowmanager

    要实现`SurfaceView`的圆角效果,一种常见的方法是使用自定义的`ViewGroup`来包裹`SurfaceView`,并在此`ViewGroup`上设置圆角。这通常涉及到对`onDraw()`方法的重写,通过`Canvas`进行裁剪或绘制圆形遮罩来达到圆角...

    Android-HeartView通过继承SurfaceView实现直播点亮功能的心形效果

    本案例中的“Android-HeartView通过继承SurfaceView实现直播点亮功能的心形效果”就是一个典型的自定义视图实例,主要涉及到Android图形绘制、SurfaceView的使用以及动画效果的实现。 1. **自定义视图(Custom View...

Global site tag (gtag.js) - Google Analytics