写博客辛苦了,转载的朋友请标明出处哦,finddreams:(http://blog.csdn.net/finddreams/article/details/40392975)
话不多说,先运行效果图:
谈到自定义View,我们都知道Android系统原生内置不少的View控件,常用的有:
文本控件TextView和EditText,图片控件ImageView,按钮控件 Button和 ImageButton,进度条ProgressBar,单选按钮RadioButton和RadioGroup,复选按钮 CheckBox 等等。
这里有些小细节我们要注意一下,比如说EditText继承自TextView,而TextView是继承View控件,TextView和EditText最大的区别就是前者不可编辑而后者是可以编辑的。
可能很多人不是很明白Button和 ImageButton的区别:
首先,Button控件继承自 TextView 类,ImageButton 继承自 ImageView,他们的继承父类不同。
其次,ImageButton只能显示图片;Button用于显示文字。
最后是相同点,做为按钮控件都可用于响应按钮的点击事件。
系统的控件虽然已经很丰富了,但有时你仍然会觉得原生控件不能够达到你所想要的效果,这时你就会想,能不能自己定义控件呢?答案是肯定的。
通过对android原生控件的研究,我们可以发现android中的控件都是继承View类,如textView、ImageView等,通过重写相关的方法来实现新的效果,通过这个我们得到两点:
1.我们可以在已有控件的基础上,通过重写相关方法来实现我们的需求。
2.继承View类或Viewgroup类,来创建我们所需要的控件。一般来讲,通过继承已有的控件,来自定义控件要简单一点。
下面我就通过一个滑动开关的实例来详细说一下关于自定义控件的步骤:
1、创建类继承View 或View的子类。
- public class SlideSwitchButton extends View
2、创建构造方法:
- public SlideSwitchButton(Context context); // 在代码中new 对象时调用此方法
- public SlideSwitchButton(Context context, AttributeSet attrs); // 在XML布局文件中声明此View,创建对象时,由系统自动调用
- public SlideSwitchButton(Context context, AttributeSet attrs, int defStyle) // 与方法2用法一样,只是多了一个参数:默认样式
- <com.finddreams.slideswitch.SlideSwitchButton
- android:id="@+id/msg_slideSwitch"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="10dip" />
通过如上的步骤即可使用滑动按钮控件了,如果你想要根据滑动开关的不同状态,处理不同的需求,或者说你想自定义滑动开关上左右两边显示的文字,比如说关闭状态时显示已关闭/含,开启状态时显示已开启/不含等等一些反义词。你只需要更改一下下面的代码
- public class MainActivity extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- SlideSwitchButton msgSwitch = (SlideSwitchButton) findViewById(R.id.msg_slideSwitch);
- msgSwitch.setOnSwitchChangedListener(new OnSwitchChangedListener() {
- /**
- * 需要处理的业务需求
- */
- @Override
- public void onSwitchChanged(SlideSwitchButton obj, int status) {
- switch (obj.getId()) {
- case R.id.msg_slideSwitch:
- Toast.makeText(MainActivity.this, "slideSwitch1 状态:" + status, 1).show();
- break;
- default:
- break;
- }
- }
- });
- //可以根据你的项目要求随意定制想要显示的反义词组
- msgSwitch.setText("已开启", "已关闭");
- }
- }
说完自定义的控件,接下来谈谈自定义属性这个看起来高大上的东西,一直都是使用Android系统自带的属性比如说background,id,text等,忽然说能自定义属性,感觉还是满厉害的。那在真实的商业项目中,自定义属性用的到底多不多呢?很明确的告诉你不多,虽然自定义属性做起来并不难,但是不够实用。当然了如果你能做自定义属性的话,那样给人的感觉很高大上,很正规。话不多说,以为滑动开关控件加上自定义属性为例:
1.你需要在values目录下面新建一个名为attrs,其实这个名字是可以任意起的,并不是说取了其他的文件名Android系统就不认识,不过出于规范通常把属性文件命名为attrs。
2. 首先在attrs.xml文件中声明可用属性集的名称,然后在属性集中声明属性,有属性名:name和格式:format 。
- <!-- 声名属性集的名称 -->
- <declare-styleable name="slideswitchbtn">
- <!-- 声名一个属性 name是bg_switch_off 类型为 引用类型 引用资源ID -->
- <attr name="bg_switch_off" format="reference" />
- <!-- 声名一个属性 name是bg_switch_on 类型为 引用类型 引用资源ID -->
- <attr name="bg_switch_on" format="reference" />
- <!-- 声名一个属性 name是switch_thumb 类型为 boolean 类型-->
- <attr name="switch_thumb" format="reference" />
- </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包名一致。
- </pre><pre name="code" class="html"><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:dreams="http://schemas.android.com/apk/res/com.finddreams.slideswitch"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- tools:context=".MainActivity" >
- <com.finddreams.slideswitch.AttrSlideSwitchButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginTop="10dip"
- dreams:bg_switch_off="@drawable/bg_switch_off"
- dreams:bg_switch_on="@drawable/bg_switch_on"
- dreams:switch_thumb="@drawable/switch_thumb" />
4.通过在自定义view的第二个和第三个构造方法当中,通过解析 AttributeSet 对象,获得所需要的属性值。
- //获得自定义的属性
- TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.slideswitchbtn);
- int N = ta.getIndexCount();
- for (int i = 0; i < N; i++) {
- /*
- * 获得某个属性的ID值
- */
- int itemId = ta.getIndex(i);
- switch (itemId) {
- case R.styleable.slideswitchbtn_bg_switch_off:
- //id默认是-1,如果没有找到相关的id就跑出异常
- mSwitch_off = ta.getResourceId(itemId, -1);
- if(mSwitch_off == -1){
- throw new RuntimeException("请设置关闭图片");
- }
- mSwitch_off_Bit=BitmapFactory.decodeResource(resources, ta.getResourceId(itemId, -1));
- break;
- case R.styleable.slideswitchbtn_bg_switch_on:
- mSwitch_on = ta.getResourceId(itemId, -1);
- if(mSwitch_on == -1){
- throw new RuntimeException("请设置打开图片");
- }
- mSwitch_on_Bit = BitmapFactory.decodeResource(getResources(), mSwitch_on);
- mBmpWidth = mSwitch_on_Bit.getWidth();
- mBmpHeight = mSwitch_on_Bit.getHeight();
- break;
- case R.styleable.slideswitchbtn_switch_thumb:
- mSwitch_thumb = ta.getResourceId(itemId, -1);
- if(mSwitch_on == -1){
- throw new RuntimeException("请设置滑动条");
- }
- mSwitch_thumb_Bit = BitmapFactory.decodeResource(getResources(), mSwitch_thumb);
- mThumbWidth = mSwitch_thumb_Bit.getWidth();
- break;
- default:
- break;
- }
- }
- }
5.通过以上的步骤就可以使用自定义属性了,同样的效果两种不同的实现方式,不适用自定义属性会比使用自定义属性要方便,没那么麻烦,但是会让人感觉很正规,符合Android的规范。下面上项目源码,有需要的朋友可以下载看看。http://download.csdn.net/detail/finddreams/8071641