歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android SurfaceView使用 筆記

Android SurfaceView使用 筆記

日期:2017/3/1 10:16:54   编辑:Linux編程

SurfaceView 是一個繼承了View但是由於一般的View有這很大區別的類.

這是由於 SurfaceView 的繪制方法和原來的View不同.在 View 中系統不允許主線程外的線程控制 UI .但是 SurfaceView 卻可以 .下面是我總結的幾個要點:

1. 首先需要實現 View 的構造方法.( 如果 需要在XML 文件中布局需要實現public S(Context context, AttributeSet attrs) 這個構造方法 )

2. 由於需要對SurfaceView 進行監控所以需要實現 SurfaceHolder.Callback 這個接口( 可以用內部類或者方法實現.) 這個接口需要實現三個方法:

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {} //大小改變的時候被調用到.

public void surfaceCreated(SurfaceHolder holder) {} // 創建的時候被調用到

public void surfaceDestroyed(SurfaceHolder holder) {} //銷毀的時候被調用

3.在SurfaceView 中屏幕接觸處理和 布局處理和View一樣.

4. 使用繪制的時候和 View 完全不一樣.他是使用 SufaceHodler 的方法

public canvas holder.lockCanvas();

public void unlockCanvasAndPost(canvas);

第一個方法可以調用出一個Canvas 畫布.在上面繪制所需的畫面.然後調用第二個方法.這樣就可以在屏幕上面繪制出來的.

View中的 invalidate()方法需要在主線程中調用(postInvalidate()不同).但是 SurfaceView不需要.SurfaceView繪制效率比View高.

5.SurfaceView中如果需要請求重新布局同樣使用 requestLayout();

6. 和View一樣重要的一些方法:

onMeasure(int ,int); 是使用 View 前需要調用的方法. 通知View進行自身尺寸測量.如果自己重寫的話測量完自身大小注意需要調用setMeasuredDimension(int, int);這個方法設置控件大小.

onLayout(boolean,int,int,int,int); 這個方法使父控件具體分配給當前View的具體位置的方法.

下面是一個小例子 :

main.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
android:focusable = "true"
/>
<com.en.demo.SVD
android:layout_width="fill_parent"
android:layout_height="wrap_content"

/>
</LinearLayout>


SurfaceView 子類 SVD:


import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class SVD extends SurfaceView implements SurfaceHolder.Callback, Runnable{


SurfaceHolder holder;

public SVD(Context context, AttributeSet attrs) {
super(context, attrs);
System.out.println("init()");

holder = getHolder();

holder.addCallback(this);
}

public void draw(){
System.out.println(" draw()");

Canvas canvas = holder.lockCanvas();

draw(canvas);

holder.unlockCanvasAndPost(canvas);
}


@Override
public void draw(Canvas canvas) {
canvas.drawColor(0xff7f7f7f + (run << 3));
}


@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.setMeasuredDimension(130, 100);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
System.out.println("width:"+width+" height:"+height);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
System.out.println(" create ");

new Thread(this).start();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {

this.holder = null;
}

int run = 10;
@Override
public void run() {
// TODO Auto-generated method stub
try{
while( run-- > 0){

draw();

Thread.sleep(1000);
}
}catch(Exception e){
e.printStackTrace();
}
}
}

Activity 中 的onCreate(Bundle)

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}

Copyright © Linux教程網 All Rights Reserved