android 自定义View1 笔记

来源:互联网 发布:java解压zip文件乱码 编辑:程序博客网 时间:2024/05/16 01:02

定义 View的常用方法:

onFinishInflate() //当View中所有的子控件 均被映射成xml后触发onMeasure(int, int) //确定所有子元素的大小onLayout(boolean, int, int, int, int) //当View分配所有的子元素的大小和位置时触发onSizeChanged(int, int, int, int) //当view的大小发生变化时触发onDraw(Canvas)
onKeyDown(int, KeyEvent) //有按键按下后触发onKeyUp(int, KeyEvent) //有按键按下后弹起时触发onTrackballEvent(MotionEvent) //轨迹球事件onTouchEvent(MotionEvent) //触屏事件onFocusChanged(boolean, int, Rect) //当View获取 或失去焦点时触发 onWindowFocusChanged(boolean) //当窗口包含的view获取或失去焦点时触发onAttachedToWindow() //当view被附着到一个窗口时触发onDetachedFromWindow() //当view离开附着的窗口时触发,该方法和onAttachedToWindow() 是相反的。onWindowVisibilityChanged(int) //当窗口中包含的可见的view发生变化时触发

  以上是View实现的一些基本接口的回调方法,一般我们需要处理画布的显示时,重写onDraw(Canvas)用的的是最多的:

view plain
  1.   @Override  
  2.   protected void onDraw(Canvas canvas) {  
  3.     //这里我们直接使用canvas对象处理当前的画布,比如说使用Paint来选择要填充的颜色  
  4.   Paint paintBackground = new Paint();  
  5.   paintBackground.setColor(getResources().getColor(R.color.xxx));  //从Res中找到名为xxx的color颜色定义  
  6.   canvas.drawRect(00, getWidth(), getHeight(), paintBackground); //设置当前画布的背景颜色为paintBackground中定义的颜色,以0,0作为为起点,以当前画布的宽度和高度为重点即整块画布来填充,具体的请查看Android123未来讲到的Canvas和Paint,在Canvas中我们可以实现画路径,图形,区域,线。而Paint作为绘画方式的对象可以设置颜色,大小,甚至字体的类型等等。  
  7. }  

 

当然还有就是处理窗口还原状态问题(一般用于横竖屏切换),除了在Activity中可以调用外,开发游戏时我们尽量在View中使用类似

view plain
  1. @Override  
  2.   protected Parcelable onSaveInstanceState() {  
  3.       Parcelable p = super.onSaveInstanceState();  
  4.       Bundle bundle = new Bundle();  
  5.       bundle.putInt("x", pX);  
  6.       bundle.putInt("y", pY);  
  7.       bundle.putParcelable("android123_state", p);  
  8.       return bundle;  
  9.   }  
  10.   @Override  
  11.   protected void onRestoreInstanceState(Parcelable state) {   
  12.       Bundle bundle = (Bundle) state;  
  13.       dosomething(bundle.getInt("x"), bundle.getInt("y")); //获取刚才存储的x和y信息  
  14.       super.onRestoreInstanceState(bundle.getParcelable("android123_state"));  
  15.       return;  
  16.   } 


有关Android的自定义 View ,我们在View中需要处理以下几种问题: 1.控制事件 2.刷新View 3. 绘制View。

  1. 对于控制事件今天我们只处理按键事件onKeyDown,以后的文章中将会讲到屏幕 触控的具体处理onTouchEvent以及Sensor重力感应等方法。

  2. 刷新view的方法这里主要有invalidate(int l, int t, int r, int b) 刷新局部,四个参数分别为左、上、右、下。整个view刷新 invalidate(),刷新一个矩形区域 invalidate(Rect dirty) ,刷新一个特性Drawable, invalidateDrawable(Drawable drawable) ,执行invalidate类的方法将会设置 view为无效,最终导致onDraw方法被重新调用。由于今天的view比较简单,Android123提示大家如果在线程中刷新,除了使用handler方式外,可以在Thread中直接使用postInvalidate方法来实现。

  3. 绘制View主要是onDraw()中通过形参canvas来处理,相关的绘制主要有drawRect、drawLine、drawPath等等。 view方法内部还重写了很多接口,其回调方法可以帮助我们判断出view的位置和大小,比如onMeasure(int, int) Called to determine the size requirements for this view and all of its children.  、onLayout(boolean, int, int, int, int) Called when this view should assign a size and position to all of its children 和onSizeChanged(int, int, int, int) Called when the size of this view has changed. 具体的作用,大家可以用Logcat获取 当view变化时每个形参的变动。

  下面cwjView是我们为今后游戏设计的一个简单自定义View框架,我们可以看到在Android平台 自定义view还是很简单的,同时Java 支持多继承可以帮助我们不断的完善复杂的问题。

view plain
  1. public class cwjView extends View {  
  2.     public cwjView(Context context) {  
  3.       
  4.       super(context);  
  5.       
  6.       setFocusable(true); //允许获得焦点  
  7.       setFocusableInTouchMode(true); //获取焦点时允许触控  
  8.         
  9.   }  
  10.   @Override  
  11.   protected Parcelable onSaveInstanceState() {  //处理窗口保存事件  
  12.       Parcelable pSaved = super.onSaveInstanceState();  
  13.       
  14.       Bundle bundle = new Bundle();  
  15.     //dosomething  
  16.       return bundle;  
  17.   }  
  18.   @Override  
  19.   protected void onRestoreInstanceState(Parcelable state) {  //处理窗口还原事件  
  20.       
  21.       Bundle bundle = (Bundle) state;  
  22.     //dosomething  
  23.     super.onRestoreInstanceState(bundle.getParcelable("cwj"));  
  24.       return;  
  25.   }  
  26.       @Override  
  27.   protected void onSizeChanged(int w, int h, int oldw, int oldh) //处理窗口大小变化事件  
  28.   {  
  29.       super.onSizeChanged(w, h, oldw, oldh);  
  30.   }  
  31.   @Override  
  32.   protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)    
  33.   {  
  34.       super.onMeasure(widthMeasureSpec, heightMeasureSpec); //如果不让父类处理记住调用setMeasuredDimension  
  35.   }  
  36.   @Override  
  37.   protected void onLayout (boolean changed, int left, int top, int right, int bottom)  
  38.   {  
  39.     super.onLayout (changed,left,top, ight,bottom) ;  
  40.   }  
  41.   @Override  
  42.   protected void onDraw(Canvas canvas) {  
  43.       
  44.       Paint bg = new Paint();  
  45.       bg.setColor(Color.Red);  
  46.       canvas.drawRect(00, getWidth()/2, getHeight()/2, bg); //将view的左上角四分之一填充为红色    
  47.       
  48.   }  
  49.   @Override  
  50.   public boolean onTouchEvent(MotionEvent event) {  
  51.         return super.onTouchEvent(event); //让父类处理屏幕触控事件  
  52.   }  
  53.   @Override  
  54.   public boolean onKeyDown(int keyCode, KeyEvent event) { //处理按键事件,响应的轨迹球事件为 public boolean onTrackballEvent (MotionEvent event)   
  55.         
  56.       switch (keyCode) {  
  57.       case KeyEvent.KEYCODE_DPAD_UP:  
  58.         
  59.         break;  
  60.       case KeyEvent.KEYCODE_DPAD_DOWN:  
  61.           
  62.         break;  
  63.       case KeyEvent.KEYCODE_DPAD_LEFT:  
  64.           
  65.         break;  
  66.       case KeyEvent.KEYCODE_DPAD_RIGHT:  
  67.         
  68.         break;  
  69.         
  70.       case KeyEvent.KEYCODE_DPAD_CENTER: //处理中键按下  
  71.         
  72.         break;  
  73.       default:  
  74.         return super.onKeyDown(keyCode, event);  
  75.       }  
  76.       return true;  
  77.   }  
  78. }  

 

上面我们可以看到onMeasure使用的是父类的处理方法,如果我们需要解决 自定义View的大小,可以尝试下面的方法

view plain
  1. @Override  
  2. protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec)    
  3. {  
  4.     height = View.MeasureSpec.getSize(heightMeasureSpec);   
  5.     width = View.MeasureSpec.getSize(widthMeasureSpec);   
  6.     setMeasuredDimension(width,height);  //这里面是原始的大小,需要重新计算可以修改本行  
  7.   //dosomething  
  8. }  

原创粉丝点击