频道栏目
首页 > 程序开发 > 移动开发 > Android > 正文
android图像绘制(四)——SurfaceView问题,自定义控件
2012-02-15 11:13:38           
收藏   我要投稿

自定义控件(类似按钮等)的使用,自定义一个SurfaceView。

如某一块的动态图(自定义相应),或者类似UC浏览器下面的工具栏。

如下图示例:

 \

 

自定义类代码:


[java]
public class ImageSurfaceView extends SurfaceView implements Callback{ 
    //用于控制SurfaceView  
    private SurfaceHolder sfh; 
    private Handler handler = new Handler(); 
    private ImageRunnable imageRunnable = new ImageRunnable(); 
    private Paint paint; 
    private Canvas canvas; 
    private Matrix matrix; 
     
    /**图片的坐标*/ 
    private float imageX, imageY; 
    /**获取的图片*/ 
    private Bitmap bmp; 
    /**图片宽高*/ 
    private float bmpW, bmpH; 
    /**屏幕大小*/ 
    private int screenW, screenH; 
 
    /**
     * SurfaceView初始化函数
     */ 
    public ImageSurfaceView(Context context, AttributeSet attrs) { 
        super(context, attrs); 
        sfh = this.getHolder(); 
        sfh.addCallback(this); 
        paint = new Paint(); 
        paint.setColor(Color.WHITE); 
        paint.setAntiAlias(true); 
        setFocusable(true); 
    } 
    /**
     * SurfaceView视图创建,响应此函数
     */ 
    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
        System.out.println("ImageSurfaceView is surfaceCreated"); 
        screenH = this.getHeight(); 
        screenW = this.getWidth(); 
                handler.post(imageRunnable); 
    } 
    /**
     * 游戏绘图
     */ 
    public void draw() { 
        try { 
            canvas = sfh.lockCanvas(); 
            canvas.drawRGB(0, 0, 0); 
            canvas.save(); 
            //绘制  
            canvas.drawBitmap(bmp, matrix, paint); 
            System.out.println("绘制图像了吗?"); 
            canvas.restore(); 
        } catch (Exception e) { 
            e.printStackTrace(); 
        } finally { 
            if (canvas != null) 
                sfh.unlockCanvasAndPost(canvas); 
        } 
    } 
    /**
     * 触屏事件监听
     */ 
    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
        return true; 
    } 
     
    /**
     * 图片的线程运行
     */ 
    class ImageRunnable implements Runnable{ 
        @Override 
        public void run() { 
            long start = System.currentTimeMillis(); 
            draw(); 
            long end = System.currentTimeMillis(); 
            if (end - start < 500) { 
                handler.postDelayed(this, 200 - (end-start)); 
            }else{ 
                handler.post(this); 
            } 
        } 
    } 
     
    /**
     * SurfaceView视图状态发生改变,响应此函数
     */ 
    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
        System.out.println("ImageSurfaceView is surfaceChanged"); 
    } 
    /**
     * SurfaceView视图消亡时,响应此函数
     */ 
    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
        System.out.println("ImageSurfaceView is surfaceDestroyed"); 
    } 

public class ImageSurfaceView extends SurfaceView implements Callback{
 //用于控制SurfaceView
 private SurfaceHolder sfh;
 private Handler handler = new Handler();
 private ImageRunnable imageRunnable = new ImageRunnable();
 private Paint paint;
 private Canvas canvas;
 private Matrix matrix;
 
 /**图片的坐标*/
 private float imageX, imageY;
 /**获取的图片*/
 private Bitmap bmp;
 /**图片宽高*/
 private float bmpW, bmpH;
 /**屏幕大小*/
 private int screenW, screenH;

 /**
  * SurfaceView初始化函数
  */
 public ImageSurfaceView(Context context, AttributeSet attrs) {
  super(context, attrs);
  sfh = this.getHolder();
  sfh.addCallback(this);
  paint = new Paint();
  paint.setColor(Color.WHITE);
  paint.setAntiAlias(true);
  setFocusable(true);
 }
 /**
  * SurfaceView视图创建,响应此函数
  */
 @Override
 public void surfaceCreated(SurfaceHolder holder) {
  System.out.println("ImageSurfaceView is surfaceCreated");
  screenH = this.getHeight();
  screenW = this.getWidth();
                handler.post(imageRunnable);
 }
 /**
  * 游戏绘图
  */
 public void draw() {
  try {
   canvas = sfh.lockCanvas();
   canvas.drawRGB(0, 0, 0);
   canvas.save();
   //绘制
   canvas.drawBitmap(bmp, matrix, paint);
   System.out.println("绘制图像了吗?");
   canvas.restore();
  } catch (Exception e) {
   e.printStackTrace();
  } finally {
   if (canvas != null)
    sfh.unlockCanvasAndPost(canvas);
  }
 }
 /**
  * 触屏事件监听
  */
 @Override
 public boolean onTouchEvent(MotionEvent event) {
  return true;
 }
 
 /**
  * 图片的线程运行
  */
 class ImageRunnable implements Runnable{
  @Override
  public void run() {
   long start = System.currentTimeMillis();
   draw();
   long end = System.currentTimeMillis();
   if (end - start < 500) {
    handler.postDelayed(this, 200 - (end-start));
   }else{
    handler.post(this);
   }
  }
 }
 
 /**
  * SurfaceView视图状态发生改变,响应此函数
  */
 @Override
 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
  System.out.println("ImageSurfaceView is surfaceChanged");
 }
 /**
  * SurfaceView视图消亡时,响应此函数
  */
 @Override
 public void surfaceDestroyed(SurfaceHolder holder) {
  System.out.println("ImageSurfaceView is surfaceDestroyed");
 }
}

 

layout的xml代码如下(使用方法,类的全地址做为控件名):


[java]
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    > 
     
    <akai.test.getImage.ImageSurfaceView android:id="@+id/myImageView" 
        android:layout_width="fill_parent" 
        android:layout_height="fill_parent" 
        /> 
     
    <LinearLayout android:id="@+id/buttons" 
        android:layout_width="fill_parent" 
        android:layout_height="wrap_content" 
        android:orientation="horizontal" 
        android:background="@android:color/white" 
        > 
        <Button android:id="@+id/getImage" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:text="选择图片" 
            /> 
        <Button android:id="@+id/getImage_ok" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:text="确定" 
            /> 
        <Button android:id="@+id/getImage_cancle" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:text="取消" 
            /> 
    </LinearLayout> 
     
</FrameLayout> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
   
    <akai.test.getImage.ImageSurfaceView android:id="@+id/myImageView"
        android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     />
   
    <LinearLayout android:id="@+id/buttons"
        android:layout_width="fill_parent"
     android:layout_height="wrap_content"
     android:orientation="horizontal"
     android:background="@android:color/white"
     >
     <Button android:id="@+id/getImage"
         android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="选择图片"
         />
     <Button android:id="@+id/getImage_ok"
         android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="确定"
         />
     <Button android:id="@+id/getImage_cancle"
         android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="取消"
         />
    </LinearLayout>
   
</FrameLayout>

 

以上代码为例子,仅供参考!

 

注意以下问题:

1、本类的初始化函数需要加入参数,为:public ImageSurfaceView(Context context, AttributeSet attrs) ;

2、不要在初始化的时候获取screen的宽度和高度,在初始化的时候并还没有执行SurfaceCreated,所以获取宽度和高度要在surfaceCreated或者之后,且在surfaceDestroyed之前;

3、在显示本控件的时候,会执行surfaceCreated和surfaceChanged,当跳转到其他界面的时候则执行surfaceDestroyed(不管是否当前的activity已经销毁),所以如果在跳转回到次控件的时候立刻执行sfh.lockCanvas()的话将会获得空值Null。

 摘自 阿凯的专栏

点击复制链接 与好友分享!回本站首页
相关TAG标签 控件 图像 问题
上一篇:android图像绘制(三)——画布刷屏问题
下一篇:Android 编码规范 | 代码风格指南
相关文章
图文推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站