自定义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
如果通过继承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
相关文章推荐
- 【转】几个经常需要自定义的View总结
- 【Cocoa(mac) Application 开发系列之二】总结一些常用控件及自定义View
- 【Cocoa(mac) Application 开发系列之二】总结一些常用控件以及简单在自定义View上绘制字符串
- Android自定义View和ViewGroup——总结于Dave Smith的视频
- Android学习:自定义ViewGroup方法总结
- Android自定义View研究(八)--自定义View总结
- Android 自定义View总结
- 自定义ViewGroup知识总结
- Android自定义View博客阅读总结
- (总结)andorid 自定义View
- Android总结笔记01:自定义View学习(一)
- IOS自定义View实现相应的控件点击方法以及代理的总结(附代码)
- Android开发教程:自定义ViewGroup方法总结
- 自定义View知识总结
- 自定义headerview代码与其知识点总结
- Android自定义View研究(八)--自定义View总结
- Android自定义View研究(八)--自定义View总结
- 自定义viewgroup总结
- Android自定义View滑动事件处理总结
- iOS-UItableview 分割线(自定义+原生)方法总结