自定义控件:用户根据自己需求,自己定制的控件。


方式: 继承已有控件、继承view、 继承viewGroup



1.继承view,定制单一控件


2.继承ViewGroup,定制控件组



例: 自定义滑动开关


 1. 继续View , 在构造方法中初始化图片资源


 2.  实现onMeasure方法,用来测量控件的宽和高


 3. 实现onDrawy方法, 把控件画出业。


 4. 实现onTouchEvent方法,实现控件的滑动,并改变状态 ,调用invalidate重新绘制控件


  5. 定义接口,在onTouchEvent方法, MotionEvent.ACTION_UP时判断状态,并实现事件回调



1.

public SlideButton(Context context, AttributeSet attrs) { 

 

    super(context, attrs); 

 

    initBitmap(); 

 

   } 

 

  /** 

 

    * 初始化图片 

 

    */ 

 

   private void initBitmap() { 

 

    slideButtonBG = BitmapFactory.decodeResource(getResources(), 

 

      R.drawable.slide_button_background); 

 

    switchBG = BitmapFactory.decodeResource(getResources(), 

 

      R.drawable.switch_background); 

 

   }



2. 


/** 

 

    * 测量当前开关的宽高时回调 

 

    */ 

 

   @Override 

 

   protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 

 

    // 设置开关的宽高 

 

    setMeasuredDimension(switchBG.getWidth(), switchBG.getHeight()); 

 

   }



3. 


/** 

 

    * 绘制当前控件的方法 

 

    */ 

 

   @Override 

 

   protected void onDraw(Canvas canvas) { 

 

    // 1.把滑动开关的背景画到画布上 

 

    canvas.drawBitmap(switchBG, 0, 0, null); 

 

    // 2. 绘制滑动块显示的位置 ,开或关 

 

    if(isSliding) { 

 

     int left = currentX - (slideButtonBG.getWidth()/2); 

 

     if(left < 0) { 

 

      left = 0; 

 

     } else if(left > switchBG.getWidth() - slideButtonBG.getWidth()) { 

 

      left = switchBG.getWidth() - slideButtonBG.getWidth(); 

 

     } 

 

     canvas.drawBitmap(slideButtonBG, left, 0, null); 

 

    } else { 

 

     if (currentState) { // 绘制开关为开的状态 

 

      canvas.drawBitmap(slideButtonBG, switchBG.getWidth() 

 

        - slideButtonBG.getWidth(), 0, null); 

 

     } else { // 绘制开关为关的状态 

 

      canvas.drawBitmap(slideButtonBG, 0, 0, null); 

 
 
 
 

     } 

 

    } 

 

    super.onDraw(canvas); 

 

   }



4.

/** 

 

    * 当产生触摸事件时回调的方法 

 

    */ 

 

   @Override 

 

   public boolean onTouchEvent(MotionEvent event) { 

 

    switch (event.getAction()) { 

 

    case MotionEvent.ACTION_DOWN: 

 

     currentX = (int) event.getX(); 

 

     isSliding = true; 

 

     break; 

 

    case MotionEvent.ACTION_MOVE: 

 

     currentX = (int) event.getX(); 

 
 
 
 
 
 
 

     break; 

 

    case MotionEvent.ACTION_UP: 

 

     isSliding = false ; 

 

      

 

     //判断当前滑动块,偏向于哪一边, 如果滑动块的中心点小于背景的中心点,设置为关闭状态 , 

 

     int bgCenter = switchBG.getWidth() / 2 ; 

 

     boolean state = currentX > bgCenter; 

 

      

 

      

 

     //调用用户的监听 事件 

 

     if(state != currentState && mListener != null) { 

 

      mListener.onToggleStateChanged(state); 

 

     } 

 

    

 

     currentState = state; 

 

      

 

     break; 

 

    } 

 

    

 

    invalidate(); //刷新当前控件 ,会引起onDraw方法的调用 

 

    return true; 

 

   }