效果图:
上半部分为一个显示摄像头拍摄到的情景的窗口及一条来回循环移动的线条,下半部分为一个无功能的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>要实现帧布局中的效果,首先编写一个继承自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)添加回调函数,
原文:http://blog.csdn.net/miaoyunzexiaobao/article/details/42105587