Android开发自定义View之滑动按钮与自定义属性

时间:2024-05-20 17:51:27

写博客辛苦了,转载的朋友请标明出处哦,finddreams:(http://blog.****.net/finddreams/article/details/40392975)  

     话不多说,先运行效果图:

 Android开发自定义View之滑动按钮与自定义属性Android开发自定义View之滑动按钮与自定义属性

       

       谈到自定义View,我们都知道Android系统原生内置不少的View控件,常用的有:

       文本控件TextViewEditText,图片控件ImageView,按钮控件 Button和 ImageButton,进度条ProgressBar,单选按钮RadioButtonRadioGroup,复选按钮 CheckBox  等等。

       这里有些小细节我们要注意一下,比如说EditText继承自TextView,而TextView是继承View控件,TextViewEditText最大的区别就是前者不可编辑而后者是可以编辑的。

 

       可能很多人不是很明白Button ImageButton的区别:

       首先,Button控件继承自 TextView 类,ImageButton 继承自 ImageView,他们的继承父类不同。

       其次,ImageButton只能显示图片;Button用于显示文字。

       最后是相同点,做为按钮控件都可用于响应按钮的点击事件。

 

       系统的控件虽然已经很丰富了,但有时你仍然会觉得原生控件不能够达到你所想要的效果,这时你就会想,能不能自己定义控件呢?答案是肯定的。

       通过对android原生控件的研究,我们可以发现android中的控件都是继承View类,如textViewImageView,通过重写相关的方法来实现新的效果,通过这个我们得到两点:

      1.我们可以在已有控件的基础上,通过重写相关方法来实现我们的需求。

      2.继承View类或Viewgroup,来创建我们所需要的控件。一般来讲,通过继承已有的控件,来自定义控件要简单一点。

 

      下面我就通过一个滑动开关的实例来详细说一下关于自定义控件的步骤:

      1、创建类继承View View的子类。

[java] view plaincopy
  1. public class SlideSwitchButton extends View  

       2、创建构造方法:

[java] view plaincopy
  1. public SlideSwitchButton(Context context);  // 在代码中new 对象时调用此方法   
  2. public SlideSwitchButton(Context context, AttributeSet attrs);  // 在XML布局文件中声明此View,创建对象时,由系统自动调用  
  3.   
  4. public SlideSwitchButton(Context context, AttributeSet attrs, int defStyle) // 与方法2用法一样,只是多了一个参数:默认样式  

         

[html] view plaincopy
  1. <com.finddreams.slideswitch.SlideSwitchButton  
  2.             android:id="@+id/msg_slideSwitch"  
  3.             android:layout_width="wrap_content"  
  4.             android:layout_height="wrap_content"  
  5.             android:layout_marginTop="10dip" />  
[html] view plaincopy
  1.    

       通过如上的步骤即可使用滑动按钮控件了,如果你想要根据滑动开关的不同状态,处理不同的需求,或者说你想自定义滑动开关上左右两边显示的文字,比如说关闭状态时显示已关闭/含,开启状态时显示已开启/不含等等一些反义词。你只需要更改一下下面的代码

[java] view plaincopy
  1. public class MainActivity extends Activity {  
  2.   
  3. @Override  
  4. protected void onCreate(Bundle savedInstanceState) {  
  5. super.onCreate(savedInstanceState);  
  6. setContentView(R.layout.activity_main);  
  7. SlideSwitchButton msgSwitch = (SlideSwitchButton)   findViewById(R.id.msg_slideSwitch);  
  8. msgSwitch.setOnSwitchChangedListener(new OnSwitchChangedListener() {  
  9. /** 
  10.  * 需要处理的业务需求 
  11.  */  
  12. @Override  
  13. public void onSwitchChanged(SlideSwitchButton obj, int status) {  
  14. switch (obj.getId()) {  
  15. case R.id.msg_slideSwitch:  
  16. Toast.makeText(MainActivity.this"slideSwitch1 状态:" + status, 1).show();  
  17. break;  
  18. default:  
  19. break;  
  20. }  
  21. }  
  22. });  
  23. //可以根据你的项目要求随意定制想要显示的反义词组  
  24. msgSwitch.setText("已开启""已关闭");  
  25. }  
  26. }  
  27.    

       说完自定义的控件,接下来谈谈自定义属性这个看起来高大上的东西,一直都是使用Android系统自带的属性比如说backgroundidtext等,忽然说能自定义属性,感觉还是满厉害的。那在真实的商业项目中,自定义属性用的到底多不多呢?很明确的告诉你不多,虽然自定义属性做起来并不难,但是不够实用。当然了如果你能做自定义属性的话,那样给人的感觉很高大上,很正规。话不多说,以为滑动开关控件加上自定义属性为例:

       1.你需要在values目录下面新建一个名为attrs,其实这个名字是可以任意起的,并不是说取了其他的文件名Android系统就不认识,不过出于规范通常把属性文件命名为attrs

       2. 首先在attrs.xml文件中声明可用属性集的名称,然后在属性集中声明属性,有属性名:name和格式:format 。

[html] view plaincopy
  1. <!-- 声名属性集的名称 -->  
  2.     <declare-styleable name="slideswitchbtn">  
  3.    
  4.         <!-- 声名一个属性  name是bg_switch_off   类型为 引用类型      引用资源ID -->  
  5.         <attr name="bg_switch_off" format="reference" />  
  6.    
  7.         <!-- 声名一个属性  name是bg_switch_on   类型为 引用类型      引用资源ID -->  
  8.         <attr name="bg_switch_on" format="reference" />  
  9.    
  10.         <!-- 声名一个属性  name是switch_thumb   类型为 boolean 类型-->  
  11.         <attr name="switch_thumb" format="reference" />  
  12.           
  13.     </declare-styleable>  

注意:format 的常用类型有

       reference 引用

       color 颜色

       boolean 布尔值

       dimension 尺寸值

       float 浮点值

       integer 整型值

       string 字符串

       enum 布尔值

       3.在布局文件中使用:在使用之前必须声名命名空间,xmlns:dreams="http://schemas.android.com/apk/res/com.finddreams.slideswitch"

说明:xmlns XML name space xml的命名空间的缩写; 

      dreams可为任意写符 

      http://schemas.android.com/apk/res/  此为android固定格式,必须这样写

   com.finddreams.slideswitch  此应用的包名,如manifest配置文件中package包名一致。

[html] view plaincopy
  1. </pre><pre name="code" class="html"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.  xmlns:dreams="http://schemas.android.com/apk/res/com.finddreams.slideswitch"  
  3.     xmlns:tools="http://schemas.android.com/tools"  
  4.     android:layout_width="match_parent"  
  5.     android:layout_height="match_parent"  
  6.     android:orientation="vertical"  
  7.     tools:context=".MainActivity" >  
  8.   
  9.  <com.finddreams.slideswitch.AttrSlideSwitchButton  
  10.             android:layout_width="wrap_content"  
  11.             android:layout_height="wrap_content"  
  12.             android:layout_marginTop="10dip"  
  13.             dreams:bg_switch_off="@drawable/bg_switch_off"  
  14.             dreams:bg_switch_on="@drawable/bg_switch_on"  
  15.             dreams:switch_thumb="@drawable/switch_thumb" />  

       4.通过在自定义view的第二个和第三个构造方法当中,通过解析 AttributeSet 对象,获得所需要的属性值。

[java] view plaincopy
  1. //获得自定义的属性  
  2. TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.slideswitchbtn);  
  3. int N = ta.getIndexCount();  
  4. for (int i = 0; i < N; i++) {  
  5. /* 
  6.  * 获得某个属性的ID值 
  7.  */  
  8. int itemId = ta.getIndex(i);  
  9. switch (itemId) {  
  10. case R.styleable.slideswitchbtn_bg_switch_off:  
  11. //id默认是-1,如果没有找到相关的id就跑出异常  
  12. mSwitch_off = ta.getResourceId(itemId, -1);  
  13. if(mSwitch_off == -1){  
  14. throw new RuntimeException("请设置关闭图片");  
  15. }  
  16. mSwitch_off_Bit=BitmapFactory.decodeResource(resources, ta.getResourceId(itemId, -1));  
  17. break;  
  18. case R.styleable.slideswitchbtn_bg_switch_on:  
  19. mSwitch_on = ta.getResourceId(itemId, -1);  
  20. if(mSwitch_on == -1){  
  21. throw new RuntimeException("请设置打开图片");  
  22. }  
  23. mSwitch_on_Bit = BitmapFactory.decodeResource(getResources(), mSwitch_on);  
  24. mBmpWidth = mSwitch_on_Bit.getWidth();  
  25. mBmpHeight = mSwitch_on_Bit.getHeight();  
  26. break;  
  27. case R.styleable.slideswitchbtn_switch_thumb:  
  28. mSwitch_thumb = ta.getResourceId(itemId, -1);  
  29. if(mSwitch_on == -1){  
  30. throw new RuntimeException("请设置滑动条");  
  31. }  
  32. mSwitch_thumb_Bit = BitmapFactory.decodeResource(getResources(), mSwitch_thumb);  
  33. mThumbWidth = mSwitch_thumb_Bit.getWidth();  
  34. break;  
  35.    
  36. default:  
  37. break;  
  38. }  
  39. }  
  40. }  

5.通过以上的步骤就可以使用自定义属性了,同样的效果两种不同的实现方式,不适用自定义属性会比使用自定义属性要方便,没那么麻烦,但是会让人感觉很正规,符合Android的规范。下面上项目源码,有需要的朋友可以下载看看。http://download.****.net/detail/finddreams/8071641