`
李楚男
  • 浏览: 114581 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

自定义控件---滑动按钮的实现

 
阅读更多
package cn.flyaudio.android;



import android.content.Context;

import android.content.res.TypedArray;

import android.graphics.Bitmap;

import android.graphics.Canvas;

import android.graphics.Paint;

import android.graphics.PixelFormat;

import android.graphics.Rect;

import android.graphics.drawable.Drawable;

import android.util.AttributeSet;

import android.view.MotionEvent;

import android.view.View;

import android.view.View.OnTouchListener;



public class SlipButton extends View implements OnTouchListener {

	

	private String TAG = "SlipButton";

	

	private boolean onSlip = false;//记录用户是否在滑动的变量

	

	private float downX, nowX, oldX;//按下时的x,当前的x



	private Bitmap slip_btn_down, slip_btn_thumb, slip_btn_up, slip_btn_bg;//图片

	

	private Rect slip_thumb_rect;//矩形

	

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

		super(context, attrs, defStyle);

		// TODO Auto-generated constructor stub

		init(context, attrs);

	}

	

	public SlipButton(Context context, AttributeSet attrs) {

		super(context, attrs);

		// TODO Auto-generated constructor stub

		init(context, attrs);

	}



	//初始化

	private void init(Context context, AttributeSet attrs) {

	

		 // 跟values/attrs.xml里面定义的属性绑定

		TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlipButton);

		slip_btn_down = drawableToBitmap(a.getDrawable(R.styleable.SlipButton_slip_btn_down)); //按下图片

		slip_btn_thumb = drawableToBitmap(a.getDrawable(R.styleable.SlipButton_slip_btn_thumb));//滑动图片

		slip_btn_up = drawableToBitmap(a.getDrawable(R.styleable.SlipButton_slip_btn_up)); //为按下的图片

		//返回一个绑定结束的信号给资源

		a.recycle();

		slip_btn_bg = slip_btn_up;

		slip_thumb_rect = new Rect(0, 0, slip_btn_bg.getWidth(), slip_btn_bg.getHeight());

		setOnTouchListener(this);// 设置监听器

	}

	

	//绘制部分

	@Override

	protected void onDraw(Canvas canvas) {

		// TODO Auto-generated method stub

		super.onDraw(canvas);

		Paint paint = new Paint();

		canvas.drawBitmap(slip_btn_bg, 0, 0, paint);

		if(!onSlip){//在没有滑动的情况下

			if(nowX <= slip_btn_bg.getWidth()/2){

				canvas.save();//记录原来的canvas状态

				canvas.clipRect(slip_thumb_rect);

				canvas.drawBitmap(slip_btn_thumb,slip_btn_bg.getWidth()-slip_btn_thumb.getWidth(),0,paint); 

				canvas.restore();//恢复canvas状态

			}else if(nowX > slip_btn_bg.getWidth()/2){

				canvas.save();//记录原来的canvas状态

				canvas.clipRect(slip_thumb_rect);

				canvas.drawBitmap(slip_btn_thumb,0, 0,paint); 

				canvas.restore();//恢复canvas状态

			}

		}else if(onSlip){//在滑动的情况下

				canvas.save();//记录原来的canvas状态

				canvas.clipRect(slip_thumb_rect);

				if(nowX < oldX){//向左滑的时候

					if((nowX-oldX) > slip_btn_bg.getWidth()-slip_btn_thumb.getWidth()){

						canvas.drawBitmap(slip_btn_thumb,nowX-oldX, 0,paint); 

					}else{

						canvas.drawBitmap(slip_btn_thumb,slip_btn_bg.getWidth()-slip_btn_thumb.getWidth(), 0,paint); 

					}

					

				}else if(nowX > oldX ){//向右滑的时候

					if((slip_btn_bg.getWidth()-slip_btn_thumb.getWidth()) +(nowX - oldX) <0){

						canvas.drawBitmap(slip_btn_thumb,(slip_btn_bg.getWidth()-slip_btn_thumb.getWidth()) +(nowX - oldX), 0,paint); 

					}else{

						canvas.drawBitmap(slip_btn_thumb,0, 0,paint); 

					}			

				}

				canvas.restore();//恢复canvas状态

		}

	}

	

	//逻辑控制部分

	@Override

	public boolean onTouch(View v, MotionEvent event) {

		// TODO Auto-generated method stub   

        switch(event.getAction())//根据动作来执行代码   

        {  

        case MotionEvent.ACTION_MOVE://滑动

        	if(event.getX()>slip_btn_bg.getWidth()||event.getY()>slip_btn_bg.getHeight() || event.getX()<0 || event.getY()<0)  

                return false; 

        	slip_btn_bg = slip_btn_down;

            nowX = event.getX();  //得到的是触摸点相对于按钮的坐标

            onSlip = true;  

            break;  

        case MotionEvent.ACTION_DOWN://按下   

        	if(event.getX()>slip_btn_bg.getWidth()||event.getY()>slip_btn_bg.getHeight() || event.getX()<0 || event.getY()<0)  

            return false;  

        	slip_btn_bg = slip_btn_down;

            downX = event.getX();  

            nowX = downX;  

            oldX = downX;

            break;  

        case MotionEvent.ACTION_UP://松开   

        	slip_btn_bg = slip_btn_up;

            onSlip = false;  

            break;  

        default:  

        }  

        invalidate();//重画控件   

        return true;  

    }  

    

    //将drawable转换为bitmap

    public static Bitmap drawableToBitmap(Drawable drawable) {  

        // 取 drawable 的长宽  

        int w = drawable.getIntrinsicWidth();  

        int h = drawable.getIntrinsicHeight();  

        // 取 drawable 的颜色格式  

        Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888  

                : Bitmap.Config.RGB_565;  

        // 建立对应 bitmap  

        Bitmap bitmap = Bitmap.createBitmap(w, h, config);  

        // 建立对应 bitmap 的画布  

        Canvas canvas = new Canvas(bitmap);  

        drawable.setBounds(0, 0, w, h);  

        // 把 drawable 内容画到画布中  

        drawable.draw(canvas);  

        return bitmap;  

    }  

    

}
 
 

今天在公司写了一个自定义控件,主要是一个可以实现左右滑动的自定义按钮。

里面的涉及到的一些知识点主要有:

1、自定义控件的属性的设置;

2、自定义控件怎么继承View这个父类来写控件;

首先是自定义控件属性的设置:

  •           先在values文件夹下写一个xml文件,文件名为:attrs.xml
  • <?xml version="1.0" encoding="utf-8"?>
     <resources>
     <declare-styleable name="SlipButton"><!-- 控件名称-->
      <!-- 属性名称,类型-->
      <attr name="slip_btn_down" format="reference"/>
      <attr name="slip_btn_thumb" format="reference"/>
      <attr name="slip_btn_up" format="reference"/>
     </declare-styleable>
    </resources>
  • 控件属性与XML定义绑定: // 跟values/attrs.xml里面定义的属性绑定
    		TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlipButton);
    		slip_btn_down = drawableToBitmap(a.getDrawable(R.styleable.SlipButton_slip_btn_down)); //按下图片
    		slip_btn_thumb = drawableToBitmap(a.getDrawable(R.styleable.SlipButton_slip_btn_thumb));//滑动图片
    		slip_btn_up = drawableToBitmap(a.getDrawable(R.styleable.SlipButton_slip_btn_up)); //为按下的图片
    		//返回一个绑定结束的信号给资源
    		a.recycle();
  •  //将drawable转换为bitmap
        public static Bitmap drawableToBitmap(Drawable drawable) {  
            // 取 drawable 的长宽  
            int w = drawable.getIntrinsicWidth();  
            int h = drawable.getIntrinsicHeight();  
            // 取 drawable 的颜色格式  
            Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888  
                    : Bitmap.Config.RGB_565;  
            // 建立对应 bitmap  
            Bitmap bitmap = Bitmap.createBitmap(w, h, config);  
            // 建立对应 bitmap 的画布  
            Canvas canvas = new Canvas(bitmap);  
            drawable.setBounds(0, 0, w, h);  
            // 把 drawable 内容画到画布中  
            drawable.draw(canvas);  
            return bitmap; 
    

            TypedArray其实就是一个存放资源的Array,首先从上下文中获取到

  • R.styleable.SlipButton这个属性资源的资源数组。
    attrs是构造函数传进来,应该就是对应attrs.xml文件。
    a.getString(R.styleable.SlipButton_slip_btn_thumb);这句代码就是获取attrs.xml中定义的属性,并将这个属
    性的值传给本控件的slip_btn_thumb.最后,返回一个绑定结束的信号给资源:a.recycle();绑定结束。
    
    在xml中对控件赋初始值:
    <?xml version="1.0" encoding="utf-8"?>
    <!-- 一定要声明命名空间 -->
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    	xmlns:flyaudio="http://schemas.android.com/apk/res/cn.flyaudio.android"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >
     <cn.flyaudio.android.SlipButton
            android:id = "@+id/slipBtn"  
            android:layout_width="wrap_content"   
            android:layout_height="wrap_content"  
            android:layout_marginLeft = "100sp"   
            flyaudio:slip_btn_thumb="@drawable/slip_btn_thumb"
            flyaudio:slip_btn_down="@drawable/slip_btn_down"
            flyaudio:slip_btn_up="@drawable/slip_btn_up"
        />  
    </LinearLayout>
    红色部分首先声明命名空间。命名空间为fsms.路径是http://schemas.android.com/apk/res/
    
    这一部分是不变的,
    后面接的是R的路径:cn.flyaudio.android。
    然后在自定义控件的xml描述中就可以这样使用flyaudio:slip_btn_thumb="@drawable/slip_btn_thumb"
    。这样就实现了自定义控件的初始化赋值。
    

 

分享到:
评论
1 楼 sphway 2012-12-10  
为什么在布局文件中加入android:layout_gravity="center_horizontal"不起作用,难道只能用layout_marginLeft把位置写死吗?

相关推荐

Global site tag (gtag.js) - Google Analytics