android自定义控件

来源:互联网 发布:淘宝能寄到国外吗 编辑:程序博客网 时间:2024/06/03 19:32

当android现有的控件不能满足我们的需求的时候,我们一般要自定义自己的控件。

自定义控件的实现并不特别难,关键在理解需求及注意实现的细节。

现在举个例子实现开关按钮的自定义控件。

需求:

1.点击按钮,切换开关状态。

2.拖动按钮,切换开关状态。

注意细节问题:

1.用户拖动控件的时候,有点击屏幕的事件,这个时候注册监听点击事件会被响应。说白了就是拖动和点击混淆了。

即用户明明想拖动的,你却实现了拖动完成+点击。

2.拖动是超越边界。

3.拖动到中途停止拖动,状态无法选择。

解决问题方法:

1.用户拖动控件的距离超过5,认为用户意图是拖动,禁用点击功能;否则,认为用户是点击意图,实现点击功能。

2.拖动位置小于最小位置,设置为0;超过最大位置,设置为最大边界。

3.拖动到中途的位置与中线(昨天起始位置与最大位置的中线)比较,小于中线归为起始状态,大于或等于中线为截止的状态。

@Override
/**
* 测量尺寸时的回调方法 这个方法我以前比较少用所以这里mark
*/
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//super.onMeasure(widthMeasureSpec, heightMeasureSpec);

/**
* 设置当前view的大小
* width  :view的宽度
* height :view的高度   (单位:像素)
*/
setMeasuredDimension(backgroundBitmap.getWidth(),backgroundBitmap.getHeight());
}

加上自定义属性(常用于封装组件给自己或他人使用)

首先在res/values/attrs.xml设置

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <!-- 声名属性集的名称 -->
    <declare-styleable name="MySwitchBtn">

        <!-- 声名一个属性  name是my_background(开关背景图)   类型为 引用类型      引用资源ID -->
        <attr name="my_background" format="reference" />
        <!-- 声名一个属性  name是my_slide_btn(开关按钮图)   类型为 引用类型      引用资源ID -->
        <attr name="my_slide_btn" format="reference" />
        <!-- 声名一个属性  name是curr_state (初始开关状态)  类型为 boolean 类型-->
        <attr name="curr_state" format="boolean" />
    </declare-styleable>
</resources>

在自定义控件类中解析自定义属性

MySwitchBtn.java

//获得自定义的属性TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.MySwitchBtn);//获取自定义属性个数int N = ta.getIndexCount();
for (int i = 0; i < N; i++) {<span style="white-space:pre"></span>/*<span style="white-space:pre"></span> * 获得某个属性的ID值<span style="white-space:pre"></span> */<span style="white-space:pre"></span>int itemId = ta.getIndex(i);<span style="white-space:pre"></span>switch (itemId) {<span style="white-space:pre"></span>case R.styleable.MySwitchBtn_curr_state:<span style="white-space:pre"></span>currState = ta.getBoolean(itemId, false);//获取自定义属性value<span style="white-space:pre"></span><span style="white-space:pre"></span>break;<span style="white-space:pre"></span>case R.styleable.<span style="font-family: Arial, Helvetica, sans-serif;">MySwitchBtn</span><span style="font-family: Arial, Helvetica, sans-serif;">_my_background:</span><span style="white-space:pre"></span>backgroundId = ta.getResourceId(itemId, -1);//获取背景图片的id<span style="white-space:pre"></span>if(backgroundId == -1){<span style="white-space:pre"></span>throw new RuntimeException("请设置背景图片");<span style="white-space:pre"></span>}<span style="white-space:pre"></span>backgroundBitmap = BitmapFactory.decodeResource(getResources(), backgroundId);<span style="white-space:pre"></span><span style="white-space:pre"></span>break;<span style="white-space:pre"></span>case R.styleable.MySwitchBtn_my_slide_btn:<span style="white-space:pre"></span>slideBtnId = ta.getResourceId(itemId, -1);//获取开关图片的id
<span style="white-space:pre"></span><span style="font-family: Arial, Helvetica, sans-serif;">if(</span><span style="font-family: Arial, Helvetica, sans-serif;">slideBtnId </span><span style="font-family: Arial, Helvetica, sans-serif;">== -1){</span><span style="white-space:pre"></span><pre name="code" class="java"><span></span>throw new RuntimeException("请设置背景图片");<span></span>}

slideBtn = BitmapFactory.decodeResource(getResources(), slideBtnId);

break;


default:
break;
}

}


这样的话我们就完成了这三个自定义控件属性的定义及获取解析。

0 0
原创粉丝点击