`
李楚男
  • 浏览: 117807 次
  • 性别: 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把位置写死吗?

相关推荐

    Android自定义控件-温度控制旋转按钮.zip

    "Android自定义控件-温度控制旋转按钮.zip"是一个专为实现温度调节功能而设计的自定义控件示例。这个控件模拟了一个可以旋转的按钮,用户通过旋转来调整温度值,常见于空调或加热系统的用户界面中。 首先,`...

    C#自定义控件--Popup窗口提醒完整源码2019

    本资源“C#自定义控件--Popup窗口提醒完整源码2019”提供了一个关于如何在C#中创建自定义控件,特别是实现Popup窗口提醒功能的示例代码。 Popup窗口在许多应用中都有广泛的应用,如提示信息、警告信息或菜单项的...

    C#自定义控件--Popup窗口提醒完整源码

    综上所述,"C#自定义控件--Popup窗口提醒完整源码"涉及了C#编程中的面向对象设计、用户界面设计、事件处理、动画实现等多个重要知识点,是一个综合性的编程实践案例。通过深入学习和理解这部分源码,开发者可以提升...

    Android高级应用源码-android自定义控件-侧滑菜单.rar

    "Android高级应用源码-android自定义控件-侧滑菜单.rar"这个压缩包文件提供了一个关于如何在Android应用程序中实现自定义侧滑菜单的示例源代码。侧滑菜单是一种常见的UI设计模式,通常用于在主屏幕和辅助功能之间...

    C#自定义控件--Popup窗口提醒完整源码__(0521).rar

    本压缩包“C#自定义控件--Popup窗口提醒完整源码__(0521).rar”提供了一个具体的实例,展示了如何在C#环境中实现一个Popup窗口提醒控件。Popup窗口通常用于显示临时通知、提示信息或用户操作反馈,它可以在用户界面...

    安卓自定义控件相关-Android自定义控件源码.rar

    为了实现独特的交互效果或视觉样式,开发者需要创建自定义控件来扩展系统的功能。 2. **自定义控件的类型**: - **视图(View)类派生**:直接继承自View类,适用于创建简单的图形或交互元素。 - **视图组...

    android自定义控件-侧滑菜单

    在Android应用开发中,自定义控件是提升用户体验和实现独特设计的重要手段。侧滑菜单,也称为抽屉式导航,是一种常见的UI设计模式,它允许用户从屏幕边缘滑动以显示附加的操作或导航选项。在本文中,我们将深入探讨...

    安卓自定义控件相关-Android屏幕自适应Demo.rar

    3. **实例应用**:在"Android屏幕自适应Demo"中,可能包含了一些自定义控件的实现,例如自定义按钮、滑动条或者其他具有特殊功能的视图。开发者可以通过查看源代码学习如何实现这些控件。 二、屏幕自适应 1. **...

    安卓自定义控件相关-HoloEverywhere-master自定义控件大全.rar

    【Android自定义控件】在Android开发中,自定义控件是实现个性化界面和功能扩展的重要手段。HoloEverywhere项目是针对Android平台的一个库,它使得开发者可以在Android 2.1及以上版本的设备上使用Android 4.0(Ice ...

    Android自定义控件-仿淘宝ios客户端天猫商品详情界面动效

    一个自定义控件继承自ScrollView,下拉时header会放大松开后会恢复原状,上滑时header会被下面的内容吃掉盖住而且会稍稍往上滑,在header高度范围内滑动时导航栏背景和导航栏的按钮会反向改变透明度形成一种对比效果。

    C#自定义控件之-winform美化

    自定义控件是WinForms中实现个性化UI的关键。你可以通过继承现有的控件,如Button、Label等,然后重写绘制方法,添加额外的功能或改变其显示样式。例如,你可以创建一个圆角按钮或者带有渐变色背景的文本框。 2. *...

    Android 自定义控件DemoCustomView-ImageButton

    3. **绘制逻辑**:自定义控件往往需要重写`onDraw()`方法来实现自己的绘图逻辑。在这个练习中,可能包括了修改按钮的形状、添加自定义边框、更改默认的按下效果等。 4. **属性动画**:为了提供更丰富的交互体验,...

    自定义控件Demo

    3. 自定义开关按钮:可能实现了风格独特的开关按钮,如滑动式开关或圆形开关。 4. 自定义下拉刷新控件:类似于SwipeRefreshLayout,但可能增加了更多的动画效果或者交互方式。 5. 自定义布局:例如瀑布流布局,...

    Android开发--自定义控件实现listview的滑动删除item

    本篇文章将详细讲解如何在Android中通过自定义控件来实现ListView的滑动删除功能。 首先,我们需要了解ListView的基本工作原理。ListView利用Adapter来绑定数据源,并通过ViewHolder优化性能,减少视图复用时的...

    C# 自定义控件实例 C# 自定义控件实例

    在C#编程中,自定义控件是一种非常重要的技术,它允许开发者根据特定需求扩展或创建新的用户界面元素。自定义控件可以是现有控件的简单修改,也可以是完全新颖的设计,为应用程序提供独特的交互体验。在这个实例中,...

    android 自定义控件实现demo收集 及 框架收集

    自定义控件可以是简单的样式修改,如改变按钮的颜色和形状,也可以是复杂的交互设计,如自定义滑动选择器或动画效果。实现自定义控件通常涉及以下步骤: 1. 继承已存在的View类(如Button、TextView等)或 ...

    自定义控件与属性

    自定义控件通常通过继承已有的View或ViewGroup类来实现。例如,如果你想要创建一个自定义按钮,你可以从Button类继承。首先,你需要创建一个新的Java类,并实现`onDraw()`方法,这是自定义控件绘制的核心。在`...

    自定义控件开发--[浮动工具条]

    在Android应用开发中,自定义控件是一种常见的需求,它能帮助开发者实现独特且符合特定需求的用户界面。本文将深入探讨如何开发一个自定义的浮动工具条,这是一个在许多移动应用中都能见到的交互元素,它通常包含一...

Global site tag (gtag.js) - Google Analytics