关于安卓View的setEnabled和setClickable的思考

本文探讨了Android开发中View的setEnabled和setClickable属性如何影响事件分发,以及它们与setOnClickListener和setOnTouchListener的交互。通过不同场景分析,展示了如何控制上层视图是否拦截及传递点击事件,提供了实战应用建议,并分享了作者在实现广告浮层时的经验。

我们讲结合setOnClickListener和setOnTouchListener以及setEnabled和setClickable的相互影响。

以及View遮盖是否能穿透事件进行分析阐述。

首先我们搞一个布局:

<?xml version="1.0" encoding="utf-8"?>
<com.example.airy.click.R1
    android:id="@+id/r1"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.airy.click.MainActivity">

    <ImageView
        android:id="@+id/im1"
        android:background="#123123"
        android:layout_width="100dp"
        android:layout_height="100dp" />
    <ImageView
        android:id="@+id/im2"
        android:alpha="0.5"
        android:background="#afd1c1"
        android:layout_width="200dp"
        android:layout_height="200dp" />


</com.example.airy.click.R1>

m2位于m1的上层且比m1更大。两者都在一个自定义的R1 extends RelativeLayout中。

首先场景1

二者都注册setOnClickListener。结果是m2可以触发,m1不可以。这很简单。

场景2

如果我们不希望m2被点击,那么我们在场景1的基础上

imageView2.setEnabled(false);

我们测试发现,m2的点击不会触发,m1同样也不会。

场景3

imageView2.setClickable(false);

使用这种方式解除m2的点击,

我们测试发现m2所覆盖下的m1区域是可以被触发点击的。
实战场景
【如果我们需要上层覆盖VIEW不可被点击并且要将点击事件穿透下去,我们选用setClickable方法】
如果我们需要上层覆盖VIEW不可被点击并且不需要将点击事件穿透下去,我们选用setEnabled方法】

接下来

场景4

我们给m2追加注册setOnTouchListener事件。并且禁止setClickable

imageView2.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                showtoast("onTouch22");
                return true;
            }
        });
 imageView2.setClickable(false);

结果是如果OnTouchListener return ture那么事件会被m2吃掉。m1点击事件不会穿透,如果return false那么事件将会穿透m1会触发点击。但是对于m2的setOnTouchListener只能接受到一个down事件并不能接收到完整的事件序列。

场景5

基于场景4变为

  imageView2.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                showtoast("onTouch22");
                return true;
            }
        });
       imageView2.setEnabled(false);

测试结果,无论retrun true和false,setOnClickListener和setOnTouchListener方法都不会被调用,m1也接受不到任何事件。

实战场景

【VIEW不可被点击并且setOnTouchListener不被调用且事件不穿透下去可以使用setEnabled】

知识点比较基础,但再项目实战中相对实用。从view事件分发的角度确实也可以解释这几个现象,最近博主也是在做一个广告浮层类似的东西总结出的经验和大家分享。

哪里可以找到我:

我的Github: https://github.com/AndroidMsky

我的博客主页: http://blog.youkuaiyun.com/androidmsky

欢迎加作者自营安卓开发交流群:

308372687

这里写图片描述

评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值