六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 35|回复: 0

自定义控件(SurfaceView与view结合)

[复制链接]

升级  25.33%

21

主题

21

主题

21

主题

秀才

Rank: 2

积分
88
 楼主| 发表于 2013-1-26 16:33:59 | 显示全部楼层 |阅读模式
 
自定义控件(SurfaceView与view结合)

作者:Legend
QQ:158067568
上一节小试牛刀,介绍了一个简单的SurfaceView的例子,如果用于实际开发,那还差得远呢。本节介绍SurfaceView与View结合使用的例子,SurfaceView部分与球类稍作改动,这里就不在赘述。主要介绍一下如何在View中成功的把SurfaceView添加进来,并且通过widget中默认的控件来操作自定义的SurfaceView。
View中添加SurfaceView

还记得我上一节中的SurfaceView类BallSurfaceView的构造方法么?BallSurfaceView(Context context)没错就是这个,但是如果我们要在view中添加,还是用这个构造方法就会报错。感谢mars老师的Android群,里面的大虾们帮我解决了这个问题。
其实只要使用如下构造方法,然后注意几点就ok了。
      
public BallSurfaceView(Context context, AttributeSet attrs) {super(context,attrs);….. 就是上面的构造方法,是符合view的。AttributeSet是提供一些设置的类,可以参考API。
但是值得注意的是,不要再SurfaceView中去绑定View,这样会带来意想不到的错误。
实现

我将把代码全部贴出,供大家参考。
 
package cn.edu.heut.zcl; import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.view.SurfaceHolder;import android.view.SurfaceView; public class BallSurfaceView extends SurfaceViewimplements SurfaceHolder.Callback{//       SportActivity sportActivity ;//调用该SurfaceView的上下文引用         private Ball ball ;//小球         public static final int initX = 100;         public static final int initY = 100;         SurfaceHolder holder ;         public int screenWidth ;         public int screenHeight ;         public BallSurfaceView(Context context, AttributeSet attrs) {                   super(context,attrs);                   ball = new Ball(initX, initY, this);                   holder = this.getHolder();                   holder.addCallback(this);                     //获得屏幕尺寸        DisplayMetrics dm = new DisplayMetrics();    dm = context.getApplicationContext().getResources().getDisplayMetrics();              screenWidth = dm.widthPixels;              screenHeight = dm.heightPixels;         }          @Override         protected void onDraw(Canvas canvas) {                   super.onDraw(canvas);                                     if(canvas == null) canvas = holder.lockCanvas();//锁定画布                   Paint p = new Paint();                   int c = p.getColor();                   p.setColor(Color.WHITE);//设置背景白色                   if(canvas != null)                   canvas.drawRect(0, 0, screenWidth, screenHeight, p);                   p.setColor(c);                   ball.onDraw(canvas);                   holder.unlockCanvasAndPost(canvas);//释放锁         }          @Override         public void surfaceChanged(SurfaceHolder holder, int format, int width,                            int height) {                           }          @Override         public void surfaceCreated(SurfaceHolder holder) {                   new RefreshThread().start();         }          @Override         public void surfaceDestroyed(SurfaceHolder holder) {                           }                 public void setStop(){                   ball.setStop(true);         }         public void setStart(){                   ball.setStop(false);         }         public void setRestart(){                   ball.setPosition(initX, initY);                   ball.setMaxHeight(initY);         }         private class RefreshThread extends Thread{                    @Override                   public void run() {                             while(true){                                     Canvas canvas = null;                                     try{                                               onDraw(canvas);                                     }catch(Exception e){                                               e.printStackTrace();                                     }                                                                         try {                                               Thread.sleep(40);                                     } catch (InterruptedException e) {                                               e.printStackTrace();                                     }                            }                   }                           }        }  package cn.edu.heut.zcl; import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.util.DisplayMetrics; /** * 球类 * @author zcl * */public class Ball {                   /**          * 球的高          */         public static final int HEIGHT = 93;         /**          * 球的宽          */         public static final int WIDTH = 93;          private static final int STEPLENGTH = 10;//每次运动的间距         private static final float REDUCEPERCENTAGE =  0.35F;//递减系数         private int stepReduce ;//每次反向运动的缩短的距离                 private boolean stop = false;                 public void setStop(boolean stop) {                   this.stop = stop;         }         private float runX ;//球的位置         private float runY ;//球的位置         private BallSurfaceView bsv ;         private boolean upDirection = false;//if true,up direction,or is down direction         private float maxHeight ;//当前运动最高的高度         private Paint paint ;                 Bitmap ballBitmap ;//球的图片         public Ball(float initX , float initY , BallSurfaceView bsv){                   this.runX  = initX;                   this.runY = initY ;                   maxHeight = initY;                   this.bsv = bsv;                   ballBitmap = BitmapFactory.decodeResource(bsv.getResources(), R.drawable.ball);//加载图片                   paint = new Paint();         }                 public void onDraw(Canvas canvas) {                   int c = paint.getColor();//保存颜色,之后还原为之前颜色                   if( !stop ) boundaryTest();                   if(canvas != null) canvas.drawBitmap(ballBitmap,runX,runY,paint);                   paint.setColor(c);                   if( !stop ) move();         }         /**          * 运动          */         private void move() {                   if(maxHeight >= (bsv.screenHeight - HEIGHT)) {                            return;                   }                   if(upDirection){//向上                            runY = runY + STEPLENGTH ;                   }else{                            runY = runY - STEPLENGTH ;                   }         }          /**          * 边界检测,使球不会飞出边界          */         private void boundaryTest(){                    if(runY > bsv.screenHeight - HEIGHT){//向下运动到头                            upDirection = !upDirection;//方向置反                            runY = bsv.screenHeight - HEIGHT;                            stepReduce = (int) (maxHeight * REDUCEPERCENTAGE);                            maxHeight = maxHeight + stepReduce ;//最大高度递减                                              }                   if(runY < maxHeight ){//向上运动到头                            upDirection = !upDirection;//方向置反                            if(maxHeight >= (bsv.screenHeight - HEIGHT)) return;                            runY = maxHeight ;                                              }         }         public void setPosition(float x,float y){                   this.runX = x;                   this.runY = y;         }         public void setMaxHeight(float y){                   this.maxHeight = y;         }}  package cn.edu.heut.zcl; import android.app.Activity;import android.content.pm.ActivityInfo;import android.os.Bundle;import android.util.DisplayMetrics;import android.view.View;import android.view.Window;import android.view.WindowManager;import android.widget.Button; public class SportActivity extends Activity {                 Button butStop;         Button butStart;         Button butRestart;                 BallSurfaceView bsv ;    /** Called when the activity is first created. */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);//        bsv = new BallSurfaceView(this);            //下两句为设置全屏        requestWindowFeature(Window.FEATURE_NO_TITLE);                   getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN ,                                  WindowManager.LayoutParams.FLAG_FULLSCREEN);               setContentView(R.layout.main);        butStop =(Button)findViewById(R.id.butStop);        butStop.setOnClickListener(new listener());        butStart =(Button)findViewById(R.id.butStart);        butStart.setOnClickListener(new listener());        butRestart =(Button)findViewById(R.id.butRestart);        butRestart.setOnClickListener(new listener());        bsv = (BallSurfaceView) findViewById(R.id.ballSurfaceView);    }    class listener implements View.OnClickListener{                    @Override                   public void onClick(View v) {                            Button but = (Button)v;                            switch(but.getId()){                            case R.id.butStop:                                     bsv.setStop();                                     break;                            case R.id.butStart:                                     bsv.setStart();                                     break;                            case R.id.butRestart:                                     bsv.setRestart();                                     break;                            }                                              }       }   }  <?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"    >    <LinearLayout    android:orientation="horizontal"    android:layout_width="fill_parent"    android:layout_height="wrap_content"    >    <Button android:id="@+id/butStop"    android:text="stop"    android:layout_height="wrap_content"    android:layout_width="wrap_content"    >    </Button>    <Button android:id="@+id/butStart"    android:text="Start"    android:layout_height="wrap_content"    android:layout_width="wrap_content"    >    </Button>    <Button android:id="@+id/butRestart"    android:text="ReStart"    android:layout_height="wrap_content"    android:layout_width="wrap_content"    >    </Button>    </LinearLayout>    <FrameLayout       android:layout_width="fill_parent"       android:layout_height="wrap_content">       <cn.edu.heut.zcl.BallSurfaceView           android:id="@+id/ballSurfaceView"            android:layout_width="fill_parent"            android:layout_height="fill_parent">       </cn.edu.heut.zcl.BallSurfaceView>    </FrameLayout></LinearLayout>  
有问题的留言,篮球运动是直接修改的上一节的例子,需要代码的留下邮箱。
 
 
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表