view+SurfaceView实现条码扫描效果

效果图:

上半部分为一个显示摄像头拍摄到的情景的窗口及一条来回循环移动的线条,下半部分为一个无功能的Btn

布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="0px"
        android:layout_weight=".3" >

        <SurfaceView
            android:id="@+id/preview_view"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent" />

        <com.example.viewtest.PicView
            android:id="@+id/capture_viewfinder_view"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="@android:color/transparent" />
    </FrameLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0px"
        android:layout_weight=".7" >

        <Button
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:text="hello" />
    </LinearLayout>

</LinearLayout>

本布局中一个大的线性布局内嵌了帧布局和线性布局两个小布局,其中两个布局分别占屏幕的30%和70%

要实现帧布局中的效果,首先编写一个继承自View的类PicView,这个类的效果为在屏幕上画一条从左至右移动的红色线条。

code:

package com.example.viewtest;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.View;

public class PicView extends View {

	private static final long ANIMATION_DELAY = 10L;
	private Paint paint;
	private int xLinePos = 0;

	private int canvasWidth = 0;
	private int canvasHeight = 0;

	public PicView(Context context, AttributeSet attrs) {
		super(context, attrs);
		paint = new Paint(Paint.ANTI_ALIAS_FLAG); // 开启反锯齿
		paint.setColor(Color.RED);
	}

	@Override
	public void onDraw(Canvas canvas) {
		canvasWidth = canvas.getWidth();
		canvasHeight = canvas.getHeight();

		drawLine(canvas);

		postInvalidateDelayed(ANIMATION_DELAY, 0, 0, canvasWidth, canvasHeight);

	}

	private void drawLine(Canvas canvas) {
		// 获取屏幕的宽和高
		int iLineBegin = canvasWidth / 5;
		int iLineEnd = canvasWidth * 4 / 5;
		int iFrameHigh = canvasHeight;
		if (++xLinePos == iLineEnd)
			xLinePos = iLineBegin;

		canvas.drawRect(xLinePos, 0, xLinePos + 1, iFrameHigh, paint);
	}
}

类中设置刷新时间为ANIMATION_DELAY,postInvalidateDelayed函数的功能为告诉系统界面过期,需要刷新,请求系统刷新界面。在onDraw中通过postInvalidateDelayed(ANIMATION_DELAY, 0, 0, canvasWidth, canvasHeight);函数,使系统每间隔一段时间(ANIMATION_DELAY)后重复调用onDraw函数刷新屏幕( 0, 0, canvasWidth, canvasHeight),在调用onDraw的过程中又一次调用了postInvalidateDelayed,循环。。。

onDraw函数中通过drawLine函数在界面中绘制了一条线,其中每次调用时通过改变xLinePos调节线条的位置。

完成本类后在布局文件activity_main.xml中添加即可:

    <com.example.viewtest.PicView
            android:id="@+id/capture_viewfinder_view"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="@android:color/transparent" />

综上,onDraw的总体效果为间隔一段时间后向系统发送一个界面无效的消息,使界面重新调用onDraw绘制,而每次绘制时线的位置均向前移动一些,最后在视觉上达到了绘制一条从左向右重复移动的线条的效果。

摄像头效果实现:

在MainActivity中实现接口SurfaceHolder.Callback。

code:

package com.example.viewtest;

import java.io.IOException;

import android.app.Activity;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MainActivity extends Activity implements SurfaceHolder.Callback {

	private SurfaceHolder surfaceHolder;
	private Camera camera;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
		surfaceHolder = surfaceView.getHolder();
		surfaceHolder.addCallback(this);
		surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
		// TODO Auto-generated method stub

	}

	@Override
	public void surfaceCreated(SurfaceHolder arg0) {
		// TODO Auto-generated method stub
		camera = Camera.open();

		Camera.Parameters parameters = camera.getParameters();
		parameters.setPreviewSize(480, 320); // 设置
		camera.setParameters(parameters);
		try {
			camera.setPreviewDisplay(surfaceHolder);
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
		camera.startPreview();
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder arg0) {
		// TODO Auto-generated method stub
		if (camera != null) {
			camera.stopPreview();
		}
		camera.release();
		camera = null;
	}

}

在onCreate中先获得布局文件里SurfaceView控件,之后通过SurfaceHolder对其进行控制。SurfaceHolder通过addCallBack(this)添加回调函数,

SurfaceHolder 类:

它是一个用于控制surface的接口,它提供了控制surface 的大小,格式,上面的像素,即监视其改变的。

SurfaceView的getHolder()函数可以获取SurfaceHolder对象,Surface 就在SurfaceHolder对象内。虽然Surface保存了当前窗口的像素数据,但是在使用过程中是不直接和Surface打交道的,由SurfaceHolder的Canvas lockCanvas()或则Canvas lockCanvas()函数来获取Canvas对象,通过在Canvas上绘制内容来修改Surface中的数据。如果Surface不可编辑或则尚未创建调用该函数会返回null,在
unlockCanvas() 和 lockCanvas()中Surface的内容是不缓存的,所以需要完全重绘Surface的内容,为了提高效率只重绘变化的部分则可以调用lockCanvas(Rect rect)函数来指定一个rect区域,这样该区域外的内容会缓存起来。在调用lockCanvas函数获取Canvas后,SurfaceView会获取Surface的一个同步锁直到调用unlockCanvasAndPost(Canvas canvas)函数才释放该锁,这里的同步机制保证在Surface绘制过程中不会被改变(被摧毁、修改)。

callback接口:

只要继承SurfaceView类并实现SurfaceHolder.Callback接口就可以实现一个自定义的SurfaceView了,SurfaceHolder.Callback在底层的Surface状态发生变化的时候通知View,SurfaceHolder.Callback具有如下的接口:

?surfaceCreated(SurfaceHolder holder):当Surface第一次创建后会立即调用该函数。程序可以在该函数中做些和绘制界面相关的初始化工作,一般情况下都是在另外的线程来绘制界面,所以不要在这个函数中绘制Surface。

?surfaceChanged(SurfaceHolder holder, int format, int width,int height):当Surface的状态(大小和格式)发生变化的时候会调用该函数,在surfaceCreated调用后该函数至少会被调用一次。

调用surfaceChanged时系统将打开摄像头并将预览图置于指定的SurfaceView中

时间: 2024-10-20 21:27:08

view+SurfaceView实现条码扫描效果的相关文章

android条码扫描程序

源码下载地址: 地址1:https://github.com/alivebao/BarCodeReader 地址2:http://download.csdn.net/detail/miaoyunzexiaobao/8297201 参考链接: zxing入门:http://www.cnblogs.com/liuan/archive/2012/01/05/2312714.html BitmapLuminanceSource类实现:http://blog.csdn.net/xyz_fly/articl

能够在子线程绘画的View SurfaceView

转载请注明出处:王亟亟的大牛之路 近期两天都没有写文章,一方面是自己在看书.一方面不知道写什么,本来昨天想写Glide或者RxAndroid的东西结果公司的"狗屎"网怎么都刷不好Gradle我也是无语了(FQ也没用).准备今天背着笔记本 回家搞.真是服了.. 抱怨的话不说了,来看下这一篇要讲的主角 SurfaceView,关于SurfaceView的文章事实上在别的一些网站上也有,由于我之前没写过,所以也就一直没整这部分的内容(别人写的好坏反正找好的点自己吸收吧,嘿嘿) 问题:Surf

可以在子线程绘画的View SurfaceView

转载请注明出处:王亟亟的大牛之路 最近两天都没有写文章,一方面是自己在看书,一方面不知道写什么,本来昨天想写Glide或者RxAndroid的东西结果公司的"狗屎"网怎么都刷不好Gradle我也是无语了(翻墙也没用),准备今天背着笔记本 回家搞,真是服了.. 抱怨的话不说了,来看下这一篇要讲的主角 SurfaceView,关于SurfaceView的文章其实在别的一些站点上也有,因为我之前没写过,所以也就一直没整这部分的内容(别人写的好坏反正找好的点自己吸收吧,嘿嘿) 问题:Surfa

条码扫描二维码扫描—ZXing android 改进版本

看了Vurtexゞ. 文章<[Android实例] 条码扫描二维码扫描——ZXing android 源码简化 (附:支持中文) >的基础上对代码进行了修改 1.增加了将代码嵌套入自己工程后传值的办法(初学,如果有更好的方法也希望告诉我,先谢谢了) 2.扫码界面进行了处理(初步实现了现有某些软件的样子,至于长的像谁就不说了) //画四个角的代码<br>paint.setColor(frameColor); canvas.drawRect(15 + frame.left, 15 +

android: View, SurfaceView, GLSurfaceView, TextureView 区别与联系

区别与联系 View: 显示视图,内置画布,提供了图形绘制函数.触屏事件.按键事件函数等,必须在UI主线程内更新画面,速度较慢: SurfaceView: 基于view视图进行拓展的视图类,更适合2D游戏的开发,是view的子类,使用了双缓冲机制,即:允许在子线程中更新画面,所以刷新界面速度比view快. GLSurfaceView: 基于SurfaceView视图再次进行拓展的视图类,在SurfaceView基础上封装了EGL环境管理以及render线程,专用于3D游戏开发的视图.是Surfa

怎么在我们的App中集成条码扫描功能?

现在很多App都有条码扫描功能,有的手机比如某米在照相机中集成了条码扫描功能,但是还有一部分手机没有这样的集成,比如韩国某星,需要自己下载一个条码扫描App.今天我们就来看看怎么在自己的App中集成一个条码扫描的功能. 本文源码下载地址http://download.csdn.net/detail/u012702547/9101419 先来看张效果图: 自己开发一个条码扫描显然是非常不现实的,我们可以使用GitHub上的开源控件ZXing来实现这样一个功能. 使用ZXing当然要先下载:http

街机扫描线之为图片添加扫描效果

为图片添加一些额外效果,会使图片更耐看一些,下面来看看如何为一张普通图片添加扫描效果. 首先是下载软件,可到软件主页下载:街机扫描线_v10(正式版) 看一下制作先后的对比图: 原图效果: 制作后加入了扫描效果的效果图: 用街机扫描线制作这种效果图只需简单的几步操作即可完成,貌似用PS做这种效果图也可以做出来,但是会很复杂.下面说一下制作方法. 1.用任意看图软件或浏览器打开一张需要制作扫描效果的图片,也可直接在网页上制作. 2.下载 街机扫描线 之后解压到任意目录,运行 街机扫描线_v10(正

仓库入仓-手机条码扫描

一般大型仓库入库时,会需要选择仓位 然而,当你拉着一车的商品要入仓时,会面临一个问题,那就是怎么对应上架单,来一个一个商品进行准确无误的入仓 针对这个问题,我们来做一个场景: 我的客户拿了200款饰品,要求录入公共仓 每一款商品都按照要求,粘贴了商品条码 并且系统已经为每个商品计算出了具体的存放仓位,就等着入仓了 小杨兴高采烈的拿着小推车到了货架旁,对着上架单里的第一个商品, 在小推车里翻来翻去,十几分钟过去了,仍然没有找到相应的商品... 时间过的很快,一下子1个小时过去,小杨还没有上架完成.

手持PDA智能条码扫描RFID打印POS机

手持PDA智能条码扫描RFID打印POS机   一.系统稳定性: 1.硬件稳定性: 采用了华为海思(国内唯一可以媲美全球顶级的CPU+射频方案厂商,可以和英伟达等一决高下)手机方案,CPU+射频浑然一体,经过数千万手机出货验证,性能稳定可靠.常规的WINCE+GSM模组组装出来的产品,不能拨打电话,仅能传输数据,而且稳定性很差. 2.系统稳定 Mobile6.5操作系统是wince系统的完美.最终升级版.注重人性化和交互界面(类似于win98和Win XP的区别).再次基础上面有经过华为数百人团