Android自定义View

继承已知Layout(如RelativeLayout和LinearLayout)

创建构造函数:

//该构造函数一般在Java文件中创建控件使用
public DefinedView( Context context ){
    super( context );
    LayoutInflater.from(context).inflate(R.layout.definedview, this);
    ...
    //或者直接调用下一个函数,即使用以下代码:
    this( context, null );
}
//该构造函数一般在xml文件中创建控件时候调用
public DefinedView( Context context, AttributeSet attrs){
    super(context, attrs);
    LayoutInflater.from(context).inflate(R.layout.definedview, this);
    【1】...
}

对于这个构造函数,因为会在这里读取attrs文件来获得各项参数,所以还需要进行一系列复杂的操作:
1. 在res/values目录下创建一个attrs_definedview.xml文件,以resources作为最外层根标签,并定义styleable标签,如:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="DefinedView">
        <attr name="textSize"           format="dimension"/>
        <attr name="text"               format="string" />
        <attr name="viewColor"    format="color" />
        <!--
        dimension表示尺寸,一般是一些以dp,sp,px等单位的内容
        string表示字符串,一般是text的内容
        color表示颜色,一般是背景等的内容
        -->
    </declare-styleable>
</resources>

值得注意的是,在这里所创建的styleable name必须和控件的名称保持一致,才能够顺利的使用xml文件来指定该控件的某些属性。

2. 在构造函数(在之前的【1】处)中读取所创建的styleable内容

TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.DefinedView);
//解析String
String text = array.getString(R.styleable.DefinedView_text);
if(text == null || text.isEmpty() )
    text = "default text";

//解析Dimension
float textSize = array.getDimension(R.styleable.DefinedView_textSize, 20sp);

//解析color,后一个值表示未设置时的默认值
int color = array.getColor(R.styleable.DefinedView_viewColor, Color.RED);

//务必记得调用recycle()
array.recycle();

创建点击响应

Android的事件分发
  • 分发函数

事件分发一般会分发给几个函数来处理:该View中用户所设定的onTouchListener的onTouch()函数,该View中系统自带的onTouchEvent()函数,该View中系统自带的dispatchTouchEvent()函数和只存在与ViewGroup和Activity中的onInterceptTouchEvent()函数

  • 分发函数返回值
    对于以上函数而言,其返回值与作用如下
函数名称返回true返回false
dispatchTouchEvent事件分配完成,本身不处理事件分配失败,交由自身处理
onTouch事件处理完成事件处理失败(或用户未定义)
onTouchEvent事件处理完成事件处理失败
onInterceptTouchEvent拦截事件自己处理不拦截,分发事件

值得注意的是,onTouchEvent()函数是系统已经定义好的函数,对于View默认返回值时true,对于ViewGroup默认返回值时false

  • Event的分发顺序:
    1. Activity获取事件以后调用dispatchTouchEvent()进行事件分发。
    2. ViewGroup获取事件以后同样调用dispatchTouchEvent()尝试分发,而在dispatchTouchEvent()中,则会分别进行如下步骤:
1、onFilterTouchEventForSecurity()
//是否需要分发事件。当View上层有遮蔽且设置android:filterTouchesWhenObscured
//[对应Java文件内调用函数:setFilterTouchesWhenObscured(boolean) ]为true时,不分发事件,
函数返回false;否则需要分发事件,则进行目标和状态清空等操作。
2、onInterceptTouchEvent()
//是否需要拦截事件,返回true表示事件被拦截,不再分发给子View;默认
//值是false。
3、进行事件分发.
//如果之前的1、2步均表示需要进行事件分发,则此时将事件分发给其子
//View(ViewGroup)。
4、检查子View是否处理事件。
//如果子View顺利处理了该事件(即子View的onTouch或者onTouchEvent()
//返回了true),则此时dispatchTouchEvent()函数返回true,分发结束。
5、onTouchListener.onTouch()
//如果所有子View(ViewGroup)均表示处理不了,则由该ViewGroup自己调
//用其设定的onTouchListnener的onTouch函数,当返回true时表示事件处
//理完成,dispatchTouchEvent函数返回true,分发结束。
6、ViewGroup.onTouchEvent()
在这个过程中捕捉到ACTION_DOWN和ACTION_UP后会执行onClick()
//如果之前onTouch()也表示处理不了,或者压根就没设置,这时则由
//ViewGroup中已经定义好的onTouchEvent()函数来处理事件,当返回true
//时表示事件处理完成,函数返回true,分发成功结束;而当返回false的时候
//ViewGroup表示自己也未处理,则dispatchTouchEvent()函数返回false


View的点击位置及函数获取值

调用event.getX()和event.getY()获取到的X和Y的值均为相对于当前View的坐标,所以ACTION_MOVE和ACTION_UP这两个操作所得到的值均有可能超出View的范围,其值也有可能小于0。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值