前段时间写了不少关于自定义View相关的文章 , 最近两个项目同时开工,忙成狗了,这不是不写博客的理由哈,今晚写一篇关于SurfaceView相关的博客 ,
还是和以前一样,今天写一个基本用法 ,下一篇写一篇常用的用法 ,这个是一个简单的绘制动态的View, 以前一直是继承View, 但是有时动态比较多的话 ,比如上一篇吃豆豆的View,因为绘制的频率颇高,用SurfaceView是比较好的 , 不然画面看起来会有点卡顿的现象,
先看一个SurfaceView写的一个progressBar的图
图片是看不出SurfaceView的有点,但是频繁绘制图片的话,比如说绘制股票走势图,心跳图,性能的有事就明显不一样了,直接看代码
今天只是一个简答的实现, 代码比较简单,
1:需要继承SurfaceView , SurfaceHolder.callBack,和线程的Runnable
2 :线程里面写一个死循环,不停的绘制 ,
3 :View创建的时候,开始绘制 ,View销毁的时候,停止绘制,增加一个Boolean类型的控制值
4:绘制的时候,需要锁住holder .
5:然后就是在该停止的时候加一个判断 ,不要做无用的绘制,消耗内存
看代码,注释比较详细
=================================================================
package com.reeman.demo.viewcustom;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable {
SurfaceHolder mHolder;
Canvas mCanvas;
private boolean mIsDrawing;
public MySurfaceView(Context context) {
this(context, null);
}
public MySurfaceView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public MySurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView();
}
Paint mPaint;
private void initView() {
mHolder = getHolder();
mHolder.addCallback(this);
//使用键盘可以获取焦点
setFocusable(true);
//触摸可以获取焦点
setFocusableInTouchMode(true);
//博爱吃屏幕常亮
this.setKeepScreenOn(true);
//paint初始化
mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.FILL);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mIsDrawing = true;
new Thread(this).start();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mIsDrawing = false;
}
@Override
public void run() {
while (mIsDrawing) {
draw();
}
}
private void draw() {
try {
mCanvas = mHolder.lockCanvas();
drawSomeThing(mCanvas);
} catch (Exception e) {
} finally {
if (mCanvas != null) {
mHolder.unlockCanvasAndPost(mCanvas);
}
}
}
public int current_progress = 50;
public void setProgress(int progress) {
this.current_progress = progress;
invalidate();
//绘制完成之后,停止绘制。
if (progress < 100) {
mIsDrawing = true;
} else {
mIsDrawing = false;
}
}
int width = 800;
int height = 50;
private void drawSomeThing(Canvas canvas) {
Log.i("main", "=======" + System.currentTimeMillis());
int left = getWidth() / 2 - width / 2;
int top = getHeight() / 2 - height / 2;
int bottom = getHeight() / 2 + height / 2;
int right = left + (width * current_progress / 100);
canvas.drawRect(left, top, right, bottom, mPaint);
}
}
布局代码=======================
<com.reeman.demo.viewcustom.MySurfaceView
android:id="@+id/surface"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_centerInParent="true" />
====================================================
package com.reeman.demo.viewcustom;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private MySurfaceView surface;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
surface = (MySurfaceView) findViewById(R.id.surface);
inti();
}
int i = 0;
boolean isRun = true;
private void inti() {
new Thread() {
@Override
public void run() {
super.run();
while (isRun) {
try {
Thread.sleep(50);
} catch (Exception e) {
}
i++;
handler.post(new Runnable() {
@Override
public void run() {
surface.setProgress(i);
if (i > 99) {
isRun = false;
}
}
});
}
}
}.start();
}
private Handler handler = new Handler();
}
使用起来和其他的自定义View,看起来没有什么差别 ,唯一的不同就是,开了线程去绘制 , 效率可以大大提升 , 内存消耗 和在主线程绘制,明显有区别 ,
下一章写一个实例,股票走势图,或者和MediaPlayer结合使用的 。
大家晚安
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)