您的位置:首页 > 其它

自定义view总结一

2014-12-22 19:08 183 查看
自定义滑块

如果通过继承view的形式自定义view的话,一般情况下需要复写onMeasure()和onDraw()方法

一、构造函数

 public MySliderButton(Context context) {

  super(context);

  init(context);

 }

 

 public MySliderButton(Context context, AttributeSet attrs) {

 super(context, attrs);

  init(context);

 }

 

 public MySliderButton(Context context, AttributeSet attrs, int defStyle) {

  super(context, attrs, defStyle);

  init(context);

 }

 

 //初始化资源

 private void init(Context context) {

  //加载三张图片

  this.context = context;

  btBackGround = BitmapFactory.decodeResource(getResources(),R.drawable.kuang);

  btOn = BitmapFactory.decodeResource(getResources(), R.drawable.green);

  btOff = BitmapFactory.decodeResource(getResources(), R.drawable.hui);

  setOnTouchListener(this);//给该view设置监听

  

  //计算背景图片的宽高

  btBackGroundHeight = btBackGround.getHeight();

  btBackGroundWidth = btBackGround.getWidth();

  btOffWidth = btOff.getWidth();

  btOffHeight = btOff.getHeight();

 }

二、

①默认情况下

onMeasure()

 @Override

 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

  super.onMeasure(widthMeasureSpec, heightMeasureSpec);

 }

如果这个方法使用父类默认的方法super.onMeasure(widthMeasureSpec, heightMeasureSpec);

则如果该view不是设置固定的宽和高,则无论设置为match_parent 或 wrap_content都会默认的填充父控件。

 

 @Override

    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

       

        int width  = measureDimension(DEFAULT_VIEW_WIDTH, widthMeasureSpec);

        int height = measureDimension(DEFAULT_VIEW_HEIGHT, heightMeasureSpec);

        setMeasuredDimension(width, height);               

    }

②一般情况下的用法

protected void onMeasureDimension(int defaultSize, int measureSpec ){

 int result = defaultSize;

       

        int specMode = MeasureSpec.getMode(measureSpec);

        int specSize = MeasureSpec.getSize(measureSpec);

               

        if (specMode == MeasureSpec.EXACTLY) {     

            result = specSize; //result直接使用确定值

        }

        else if (specMode == MeasureSpec.AT_MOST) {           

            result = Math.min(defaultSize, specSize); //result不能大于specSize

        } else {     

            result = defaultSize;

        }

       

        return result;

    }

}

③也可以直接设值

 @Override

 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

  //宽高由背景图片计算得来

  setMeasuredDimension(btBackGroundWidth, btBackGroundHeight);

 }

三、OnDraw()用来绘制图片

@Override

 protected void onDraw(Canvas canvas) {

  super.onDraw(canvas);

  System.out.println("执行了onDraw().......");

  Matrix matrix = new Matrix();

  Paint paint = new Paint();

  y = (btBackGroundHeight - btOffHeight)/2;

  float x = 0;

  midWidth = btBackGroundWidth/2 - btOffWidth/2;

  maxWidth = btBackGroundWidth - y*2 - btOffWidth;

  Bitmap bitmap;

  //滑块在拖动

  if(onSlip){

   if(nowX >=maxWidth){//如果超过最右边的边界,则设置为maxwidth

    x = maxWidth;                          

    bitmap = btOn;

   }else if(nowX <= y){

    x = y;

    bitmap = btOff;

   }else{//没超过最右边则设置为拖动的位置

    x = nowX + y;

    if(x > midWidth){

     bitmap = btOn;

    }else{

     bitmap = btOff;

    }

   }

  //初始化滑块

  }else{

   if(nowX <= midWidth){

    x = x + y;

    bitmap = btOff;

   }else{

    x = maxWidth;

    bitmap = btOn;

   }

  }

  //根据手指在屏幕上的移动位置绘制图片

  canvas.drawBitmap(bitmap, x , y, paint);

 }

四、onTouch()

在init()方法中给该view设置了触摸监听setOnTouchListener(this),会回调该方法

@Override

 public boolean onTouch(View v, MotionEvent event) {

  switch (event.getAction()) {

  case MotionEvent.ACTION_DOWN:

   //如果手指触碰屏幕不在该view的范围内,则不响应

   if(event.getX() > btBackGround.getWidth() || event.getY() > btBackGround.getHeight()){

    return false;

   }else{

    onSlip = true;

    downX = event.getX();

    nowX = downX;//记录手指按下的位置

   }

   break;

  case MotionEvent.ACTION_MOVE:

   nowX = event.getX();//记录手指移动过程中的位置

   break;

  case MotionEvent.ACTION_UP:

  //当手指按下时在该控件范围内,当手指滑动出该控件范围时会调用MotionEvent.ACTION_CANCEL

  //如果不处理该事件,如果该view放在listview等控件中时,当上下滑动时有时会出现滑块挂在中间的状态

  case MotionEvent.ACTION_CANCEL:

   onSlip = false;

   nowX = event.getX();

   if(nowX >= midWidth){

    nowStatus = true;

   }else{

    nowStatus = false;

   }

   System.out.println("离开:"+nowX);

   if(listener != null){

    //回调监听中的方法

    listener.OnChanged(MySliderButton.this, nowStatus);

   }

   break;

  }

  //调用该方法后会执行onDraw()方法

  invalidate();

  return true;

 }

五、设置监听

 public void setOnChangedListener(OnChangedListener listener){

  this.listener = listener;

 }

 

 /**

  * 为button提供一个供外部调用的方法,设置一个监听

  * @author zhijianhulian

  *

  */

 public interface OnChangedListener{

  void OnChanged(MySliderButton mySliderButton,boolean checkState);

 }

 

六、提供可以设置状态的方法

 public void setChecked(boolean checked){

  if(checked){

   nowX = btOff.getWidth();

  }else{

   nowX = (btBackGround.getWidth() - btOff.getWidth())/2;

  }

  nowStatus = checked;

 }

 

 

 

代码:http://download.csdn.net/detail/nicolelili1/8287557
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: