自定义View的一些注意点

View绘制的源码解读、自定义View和ViewGroup的注意点总结 一直想要总结一下view绘制的一些经验,近期正好在看《Android内核剖析》这本书,借这个机会,结合源码&一些经验,对View的绘制源码进行一些学习、总结,过程中结合实践demo对自定义View的一些经验进行总结。 1.View绘制的源码解读 View整体绘制流程 当一个应用启动时,会启动一个主Activity,Android系统会根据Activity的布局来对它进行绘制。绘制会从根视图ViewRootImpl的performTraversals()方法开始,是一个树形的递归过程,从上到下遍. 阅读详情

View的坐标系

View坐标系

自定义View重写OnTouchEvent(MotionEvent event)方法后Android Studio提示重写performClick(方法)

我们在重写OnTouchEvent(MotionEvent event)方法时,Android Studio总是提示我们“Custom View XXXX overrides onTouchEvent but no performClick more…”, 分析performClick()源码后我们知道:

 public boolean performClick() {
        // We still need to call this method to handle the cases where performClick() was called
        // externally, instead of through performClickInternal()
        notifyAutofillManagerOnClick();

        final boolean result;
        final ListenerInfo li = mListenerInfo;
        if (li != null && li.mOnClickListener != null) {
            playSoundEffect(SoundEffectConstants.CLICK);
            li.mOnClickListener.onClick(this);
            result = true;
        } else {
            result = false;
        }

        sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);

        notifyEnterOrExitForAutoFillIfNeeded(true);

        return result;
    }

performClick() 方法中实际上会执行CustomView.setOnClickListener(){}中的事件(前提是我们设置了setOnClickListener()),而我们重写OnTouchEvent后,setOnClickListener可能会得不到执行,当然,我们发现自己即使不关心Android Studio给出的这个警告,仍然运行正常,我们仔细想想也符合逻辑:既然自定义View重写了OnTouchEvent()方法,那么就不应该再设置setOnClickListener监听事件,Android Studio给出提示只是为了当开发者重写onTouchEvent方法后,又在外部给这个自定义View设置了监听事件,如何能执行到监听事件(setOnClickListener是事件分发的最后一层)。
其实消不消除这个waring都没什么问题,我们在这里说下如何消除这个waring, 首先在控件中重写performClick方法,然后在onTouchEvent中的某个Action行为中执行performClick(),如下所示,

 @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_UP:
                performClick();
                break;
        }

        return false;
    }

    @Override
    public boolean performClick() {
        return super.performClick();
    }

不过,我们还发现,我们即使重写了onTouchEvent方法,依旧可以执行到setOnClickListener级别(我在上面也说了,它并不是执行不到,只是在某些情况下执行不到), 我们在onTouchEvent方法末尾一般会返回父类该方法执行的结果。

@Override
    public boolean onTouchEvent(MotionEvent event) {
        return super.onTouchEvent(event);
    }

我们分析View的onTouchEvent源代码得知,

public boolean onTouchEvent(MotionEvent event) {
switch (action) {
                case MotionEvent.ACTION_UP:
                     if (mPerformClick == null) {
                              mPerformClick = new PerformClick();
                        }
                    if (!post(mPerformClick)) {
                             performClickInternal();
                         }
                 }
}

private final class PerformClick implements Runnable {
        @Override
        public void run() {
            recordGestureClassification(TOUCH_GESTURE_CLASSIFIED__CLASSIFICATION__SINGLE_TAP);
            performClickInternal();
        }
    }


 private boolean performClickInternal() {
        // Must notify autofill manager before performing the click actions to avoid scenarios where
        // the app has a click listener that changes the state of views the autofill service might
        // be interested on.
        notifyAutofillManagerOnClick();

        return performClick();
    }

在父类的Up事件中,同样也会执行performClick(),进而我们就看到了,我们设置的自定义View的setOnClickListener也执行到了。
个人总结:自定义的View如果在onTouchEvent(MotionEvent event)中没有使用过super.onTouchEvent(event)代码的话(在一些文章中也见过直接根据情况返回true/false的),这时候如果也在外部(比如Activity)给这个自定义View设置了setOnClickListener,那么我们就需要在onTouchEvent中根据具体情况来决定把performClick()代码放在哪个位置合适(一般也是放在UP事件中),然后在控件中重写performClick()。不建议在onTouchEvent(MotionEvent event)方法中performClick()与super.onTouchEvent(event)都出现。

Paint关于PorterDuffXfermode的几个问题

PorterDuffXfermode类似数学中关于图形之间的交集,并集,差集问题,需要注意的是:dst是下层,先画上去的图形;src是上层,后画上的图形;用句谚语来形容的话就是“后来者居上”。
首先看下google给出的官方样例,
在这里插入图片描述
但我们真正使用的时候回发现实际情况与此图并不完全符合,具体情况可以查看此博客:https://blog.youkuaiyun.com/wingichoy/article/details/50534175,
这里我们主要说下结论:
首先PorterDuffXfermode会受硬件加速的影响,建议自定义View如果使用PorterDuffXfermode关闭硬件加速;
其次,google给出的官方图成立的前提是存在两个bitmap。

PorterDuffXfermode的各种模式详解https://www.jianshu.com/p/0f64daf202f2
###ViewGroup 中 onInterceptTouchEvent()的几条结论。

  • down事件首先传递到onInterceptTouchEvent()方法;
  • 如果该ViewGroup的onInterceptTouchEvent()方法在接收到down事件并处理完成后return false,则内部View也将会获取到down事件,后续的move,up事件也将继续先传递到该ViewGroup中,之后一样传递给最终的目标childView的onTouchEvent()处理。
  • 如果该ViewGroup的onInterceptTouchEvent()接收down事件并处理完成后return true,则表明子View不需要接收接收事件,后续的move,up事件也不再传递给onInterceptTouchEvent(), 该事件接着交给ViewGroup自身的onTouchEvent()方法去执行。
【Android面试八股文】你能说一说View绘制流程与自定义View注意点吗? 在Android中,自定义View通常需要提供多个构造函数,以适应不同的使用场景。这是最简单的构造函数,直接在代码中创建View实例时使用。context:上下文对象,一般是Activity或Application的实例。在XML布局文件中使用该View时会调用此构造函数。context:上下文对象。attrs:从XML中获取的属性集合。用于指定默认样式属性,对应当前主题中的默认样式。context:上下文对象。attrs:从XML中获取的属性集合。:应用的默认样式属性。 阅读详情

相关推荐

从零到一:Quartus II连接开发板实战,打通绘图、管脚分配、编译与下载全链路

本文详细介绍了使用Quartus II软件连接FPGA开发板并完成首个项目的全流程。从硬件连接到驱动安装,到绘制电路框图、精准分配管脚,再到编译设置与最终下载,手把手指导您打通从设计到硬件实现的完整链路,是FPGA初学者的实战入门指南。

mqtt6iot的博客 717

写一个自定义View你都需要注意什么

本文主要是记录一下继承子View,所需要实现的方法,以及对自己的知识做一下梳理和记录,其中不少内容觉得自己应该是会的,但是实际写起来,还是遇到不少阻碍。

1 810

告别Windows!Oculus Quest 2在Mac M1上的串流实战(scrcpy+SideQuest避坑指南)

本文为Mac M1用户提供了Oculus Quest 2在macOS上实现高清低延迟串流的实战指南。通过使用开源工具scrcpy和SideQuest,绕开官方限制,详细讲解了从环境准备、无线调试到画质与延迟优化的完整步骤,重点解决了Apple Silicon芯片Mac的连接与性能问题,助你告别Windows依赖。

weixin_29224309的博客 308

自定义view系列(3)--给自定义View添加点击事件

这几天一直在看《android开发艺术探索》和《android群英传》中关于自定义view的章节,结合着网上大神的一些心得分享,感觉自定义view这一块受益匪浅,这里做个心得笔记,主要记录一下view与用户交互的一些知识。 自定义view与用户交互用的最多的就是单击事件,其次的还有双击事件、长按事件、滑动事件等,所以就需要做好view的事件监听。 如果我们继承了View,也绘制好了控件,但是不

qiang_xi的专栏 2万+

3分钟搞懂欧式距离变换(EDT):从暴力算法到Felzenszwalb的演进史

本文系统梳理了欧式距离变换(EDT)从暴力算法到高效线性算法的演进历程。重点解析了光栅扫描算法和Felzenszwalb算法的核心思想与实现,并探讨了其在机器人路径规划中生成欧几里得符号距离场(ESDF)的关键应用,为开发者提供了清晰的算法选型与实战指南。

fern8的博客 976

手把手教你用Cadence Virtuoso仿真一个5GHz CMOS分频器:从原理图到后仿,避开那些教科书上没写的坑

本文详细介绍了在Cadence Virtuoso环境中设计5GHz CMOS分频器的完整流程,从原理图设计到后仿真优化,特别关注实际工程中容易被忽视的关键问题。内容涵盖分频器核心指标解析、锁存器拓扑选择、接口设计匹配以及后仿真优化策略,为射频集成电路设计提供实用避坑指南。

weixin_26934905的博客 262

自定义view中控件的点击事件

1:自定义一个view,(本案例只实现一个button按钮的点击事件) package com.bawei.study.view; import android.content.Context; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.

qq_39834764的博客 917

强化学习新手上路:用PPO-Clip轻松玩转Pendulum-v1(PyTorch保姆级教程)

本文提供了一份基于PyTorch的PPO-Clip算法实战教程,指导强化学习新手在Pendulum-v1环境中构建连续控制智能体。教程详细解析了PPO-Clip的核心机制,特别是其Clip机制如何限制策略更新幅度以确保训练稳定,并涵盖了从环境配置、策略网络设计、经验收集到完整训练框架搭建的全过程,是掌握连续动作空间强化学习的实用指南。

weixin_29062963的博客 270

自定义的view中控件的点击事件实现

大多数时候我们需要自定义view实现功能,让代码更简洁化,但是在自定义view中控件,我们需要其实现点击事件,那么该怎么做呢?*1:自定义一个view,(本案例只实现一个button按钮的点击事件)*//自定义的view继承linearlayout public class Views extends LinearLayout{ Click click; Button button;

Miao_Hen的博客 1326

从零构建工业级SPI-CAN网关:CH347与CH9431的软硬件协同设计实战

本文详细介绍了基于CH347和CH9431芯片构建工业级SPI-CAN网关的完整方案。通过硬件架构设计、Linux驱动定制、并发处理优化和EMC抗干扰测试,实现高可靠性通信网关,适用于工业自动化和汽车电子等严苛环境。

spark7igniter的博客 632

神联动:LSTM+卡尔曼滤波!一区大门轻松开!

近来热度飙升,成为时间序列预测和状态估计等领域的香饽饽,非常好发高区!主要在于:这两者结合,不仅能提高模型预测准确性;还能拓展应用场景,为我们的论文创新提供发挥空间,且当下还在蓝海阶段,还不算卷。具体点说:卡尔曼滤波擅长处理线性状态估计和噪声,能使LSTM更好地适应动态环境的变化,减少噪声干扰,降低预测误差。而LSTM通过捕捉长期依赖关系,擅长处理非线性时间序列,能够弥补卡尔曼滤波在这方面的不足,从而把应用场景从传统的状态估计,延伸到金融预测、工业检测、自动驾驶等任务。

2401_82426425的博客 2208

自定义view的注意事项

1、让View支持wrap_content属性 直接继承View或ViewGroup的控件,如果不在onMeasure中做处理,当控件设置wrap_content属性时无法达到预期效果。wrap_content属性会失效。 2、让View支持padding属性 直接继承View的控件,如果不处理padding属性,则padding会失效。如果继承ViewGroup的控件,还需要处理子元素的margin属性。 3、为了让控件使用更方便,尽量添加自定义属性。 4、如果View需要响应用户touch事件,需要处理

愤怒的蜗牛的博客 761

yolov8涨点系列之轻量化主干网络替换

yolov8涨点系列之轻量化主干网络替换,以EfficientVit为例

zhang1379的博客 2887

android 自定义view 注意点,自定义View你更需要注意的事情

自定义控件是android开发中最常见的技术,对于面试来说经常会被问到,然而面试者们的回答也几乎是千变一律,自定义View的原理,原理,原理.当然不可否认自定义View原理是Android开发者必须了解的基础.但是时间开发中更需要了解的是对该View的性能优化.OOM内存优化问题.可以在onDraw中创建对象吗?不建议你在draw或者layout的过程中去实例化对象!我们应该在哪里创建对象?在自定...

weixin_35767338的博客 283

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Android自定义View的注意点

参考android developer,文章适用于用过一点点自定义view的新手。 首先讲两个方法: invalidate(); requestLayout(); invalidate()方法用于指示View的绘画已经失效,需要刷新,使用这个方法会调用View内部的draw方法。 已经失效一般来说就是你在ondraw里面需要的参数变了,就要使用这个方法 requestLayout()方法用于告

风起云涌 894

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

graphics相关控件、bitmap优化注意点、自定义view相关方法api

‌及时回收资源: Activity.onDestroy()时调用bitmap.recycle() 避免静态变量持有bitmap导致内存泄漏。关系:measure()是final方法,由父容器调用并触发测量流程,内部会调用onMeasure()完成实际测量‌,‌ Android 8.0+‌:利用Bitmap.Config.HARDWARE减少GPU内存拷贝(只读场景)‌。// 复用目标Bitmap‌。onMeasure()/onLayout()/onDraw() 测量、布局位置、绘制。

lui0617的博客 351

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

自定义View的注意点

最近在家无事,开始学习android。 自己做了一个自定义的View,布署到main.xml上去,却发现跑的时候老是出现错误。 后来发现,原来是集成View的时候没有写上父类3个参数的构造方法。 估计其内部默认情况下会调用那个构造方法吧。     贴上代码: main.xml <?xml version="1.0" encoding="utf-8"?> <Fra...

110

自定义控制器的View(loadView)及其注意点

自定义控制器的View loadView方法 简介 loadView作用:一般用来创建控制器自定义的View,如果实现了loadView,就说明要自定义控制器的View loadView调用时间:当控制器的view没有创建的时候,就会调用loadView来创建控制器的view loadView使用注意:如果重写loadView里面没有创建控制器的vie...

dijian4220的博客 195

自定义View和自定义属性 注意点

这篇博客也算是一篇读书笔记把。我在学习自定义View的时候看到了 鸿洋_Android自定义View(一) 中涉及到的例子,我就自己尝试也写了一遍,发现里面需要注意的问题如下: 1,在定义的时候把属性定义在value文件夹里面,xml文件的名字没有要求,定义的时候tag name是declare-styleable,里面的item标签是attr 如果有需要itme的属性要加上format 2

空之境界 422

自定义View注意点

触摸事件的多次触发@Override public boolean onTouchEvent(MotionEvent event) { int index = -1; switch (MotionEventCompat.getActionMasked(event)) { case MotionEvent.ACTION_DOWN:

沉寂的月痕 422

手把手教你写一个完整的自定义View

前言 自定义View是Android开发者必须了解的基础 今天,我将手把手教你写一个自定义View,并理清自定义View所有应该的注意点 阅读本文前,请先阅读我写的一系列自定义View文章 自定义View基础 - 最易懂的自定义View原理系列(1) 自定义View Measure过程 - 最易懂的自定义View原理系列(2) 自定义View La...

贵公子丶笔记 776

自定义View

目录 1. 自定义View的分类 自定义View一共分为两大类,具体如下图:  2. 具体介绍 & 使用场景 对于自定义View的类型介绍及使用场景如下图:  3. 使用注意点 在使用自定义View时有很多注意点(坑),希望大家要非常留意:  3.1 支持特殊属性 支持wrap_content  如果不在onMeasure()中对wrap_content作特殊处理...

qq_40295727的博客 273

Android:自定义控件的一些注意点

自定义控件的几个注意点 如果自定义View需要设置一个不变的背景图,为了提高效率,你可以在构造方法中直接设置背景图片。无需在onDraw中绘制Bitmap backgroundBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.your_png); if (backgroun

郑海波(莫川)的优快云博客 2346
上一篇: ThreadLocal介绍
下一篇: 探究RecyclerView复用缓存机制
OneLinee
博客等级 码龄10年 11粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值