Android -- 每日一问:如何实现自定义View?

news2025/4/8 20:20:21

在这里插入图片描述

经典回答

回忆一下,你去面试时常被问到的自定义 View 方面的问题是那些。有没有:

  • invalidate 和 postInvalidate 方法的区别?
  • 自定义 View 的绘制流程?
  • View 的 Touch 事件分发流程?

因为在实际的工作中并不是每个人都会涉及UI的实现,所以有些人没有做过自定义 View 并不能否决这个人在 Android 开发上的能力,包括会问你这方面问题的面试官也可能并没有自定义 View 的经验。所以很多面试中,一般也就是问问如上面的那些机制方面的问题,看面试者是否有一个正确的认识。但如果一个人说他精通自定义View的话,不妨从细节上检验一下他。

在说我怎么检验面试者的自定义View水平之前,先来一道老外的面试题,大家不妨先自己试着敲一下代码看能不能实现。

image.png

效果界面如下:
image.png

这一道题其实把我们刚刚提到的面试常被问到的那些机制问题都涉及到了,你很容易就能查找和了解并可以很好的回答上那几个基础问题,但是你能做出这个自定义View吗?

这就是机制和现实的差距!你有必要了解机制(基础),但了解并不等于会了,会的过程需要一定的积累,只有融会贯通了才能轻而易举地完成这个老外的面试题。

我们简单剖析一下,这个可左右滑动的View中是一组子View组成的,每个子View(圆盘carousel)可以自定界面,但背景的样式是相似(每组背景只是颜色不一样),有点ListView中的Adapter味道,对滑动的过渡是有要求的,这个其实是更真实操作Touch的样例(没有人想看生硬的滑动效果)。那么我们要能实现上面的效果,需要注意以下几个点:

  • ViewGroup的布局(计算一行能显示的圆盘数量和大小)
    圆盘View的效果(背景和半透明过渡)
    左右列表和BaseAdapter
    圆盘View的滑动(需要自动回弹,保证滑动后要有一个圆盘处于中间位置)

  • View & ViewGroup
    自定义View(有时我们也可以叫自定义UI或者自定义UI组件),从实现或者分类上我觉得可以分为三类:

  • 直接继承View
    继承自ViewGroup
    对现有组件的扩展(如继承自TextView)
    第3种方式是比较容易的,因为父组件常常帮我处理了绘制、分发和Touch等事件,我们只需要加入一些特别的功能就行。比如继承自ImageView实现图片圆角显示。

第1和第2种方式,需要我们对前面提到的那些机制问题有一定的了解,也要搞清楚View和ViewGroup在哪些方面有什么区别。

ViewGroup继承自View,是一种特殊的View,可以理解成一种View的容器,它可以装其他的View或其他的ViewGroup。
ViewGroup需要控制子View如何布局,所以必须实现onLayout(在ViewGroup中是抽像方法)。
ViewGroup可以通过onInterceptTouchEvent拦截当前事件,再决定是否分发给子View处理。
ViewGroup默认是不会调用onDraw方法的,如果需要重绘容器的背景需要在构造函数调用setWillNotDraw(false)。

除此之外,要熟悉一些概念(或者类):Canvas, Paint, Matrix,Path & PathMeasure,贝塞尔曲线,SufaceView & OpenGL等等。是不是觉得概念太多了,是的,没有实际做过,你一定会这样想。让你为了面试去准备这么多东西,貌似也起不到多大的作用,面试官不一定会问(除非指明了招专门做自定义UI的开发)。而且就算面试官问了一个你准备好的主题,但他换一种说法问你,如果你只是准备过但并没有掌握的话,也不一定能答得上来。就拿PathMaesure来说,做为面试官一般不会直接问你:“这个PathMeasure有什么方法或者主要是做什么用的啊?”

而往往会用实例来看你的实现思路,例:“如何实现下图的这个箭头图标(png图片)围绕园周运动的自定义View”。如果你的做法不是使用PathMeasure,那么我也会很有兴趣想听听你的思路和实现方法。

121212.gif

灵活使用PathMeasure的常见的两个方法可以轻松的实现很多神奇的效果。
getSegment:截取整个Path的片段;
getPosTan:获取路径上的坐标点和对应点的切线坐标。

使用PathMeasure实现的核心代码:

    path = new Path();
    path.addCircle(0, 0, 200, Path.Direction.CW); //添加一个圆的path
    pathMeasure = new PathMeasure(path, false);

    float[] pos = new float[2];
    float[] tan = new float[2];
    pathMeasure.getPosTan(pathMeasure.getLength() * value, pos, tan);

    float degress = (float) (Math.atan2(tan[1], tan[0]) * 180.0 / Math.PI); // 计算箭头图片的旋转角度

如果面试者不了解PathMeasure的话,也可以问一下图片圆角(或称矩形圆角)或者圆形头像的实现方式,这个也是一个很常见的功能,效果如下图:
image.png

把原图直接做成圆角外,常见有三种方式实现:

  • 使用 Xfermode 混合图层;
  • 使用 BitmapShader;
  • 通过裁剪画布区域实现指定形状的图形(ClipPath)

你的朋友是不是也在准备面试呢?你可以把今天的题目分享给好友,或许你可以帮到他。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/109608.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Go实现】实践GoF的23种设计模式:命令模式

上一篇:【Go实现】实践GoF的23种设计模式:代理模式 简单的分布式应用系统(示例代码工程):https://github.com/ruanrunxue/Practice-Design-Pattern–Go-Implementation 简介 现在的软件系统往往是分层设计。在业务层执…

设计vue3组件

在程序设计过程中,我们经常会遇到很多地方用到相同结构内容的情况,这时,我们想复用一部分代码,这时可以将可复用的UI部分以组件的形态封装,形成一定的组件调用关系。 组件化最简单的就是把一段代码提出来单独写进一个…

Netflix Eureka 2.0.0正式发布:借尸还魂还是虚晃一枪?

本文已被https://yourbatman.cn收录;女娲Knife-Initializr工程可公开访问啦;程序员专用网盘https://wangpan.yourbatman.cn;技术专栏源代码大本营:https://github.com/yourbatman/tech-column-learning;公号后台回复“…

【Web前端HTML5CSS3】09、高度塌陷与 BFC

九、高度塌陷与 BFC 1、高度塌陷 在浮动布局中,父元素的高度默认是被子元素撑开的 当子元素浮动后,其会完全脱离文档流,子元素从文档流中脱离将会无法撑起父元素的高度,导致父元素的高度丢失 父元素高度丢失以后,其…

IU酒店释放轻中端投资活力,开启曲靖酒店新篇章

曲靖位于云南省东北部,是云南连接内地的重要陆路通道,素有“滇黔锁钥”、“入滇门户”、“云南咽喉”之称,是仅次于昆明的云南第二大城市。曾入选“中国十佳宜居城市”榜单10次的城市,拥有3000多年的文明史,早在三国魏…

mock功能

目标 了解mock的作用及使用场景; mock使用场景 mock:假的 前端程序员提到的mock数据的含义是:真的假数据 真的:符合接口规范要求的。 假数据:数据是人为创建出来的,不是真正的业务数据。 什么时候需要m…

客快物流大数据项目(九十七):ClickHouse的SQL语法

文章目录 ClickHouse的SQL语法 一、​​​​​​​常用的SQL命令 二、​​​​​​​​​​​​​​select查询语法 三、insert into语法 四、​​​​​​​​​​​​​​alter语法 ClickHouse的SQL语法 一、​​​​​​​常用的SQL命令 作用 SQL 列出所有数据库 s…

日本知名汽车零部件公司巡礼系列之株式会社135

株式会社135 业务内容: 各种齿轮零件加工(减速机零件) 齿轮马达的齿轮头零件组装加工 轮式起重机齿轮零件加工 其他部位、零件等的加工 公司简介: 资本金:3000万日元 员工数:41名(男33名,女8名&#x…

N维码算法的探索(二),16色的16进制编码表达汉字的试探

前些天写了一篇《N维码算法的探索》,是利用颜色像素对n维码算法扩展的思考。读者非常有限,能够理解的可能需专业人士了。 这种研究的意义何在?不知道。用上了就是有用,用不上也就被历史淘汰了。普通人通常的逻辑是:既…

js获取某一时间到现在的总时间以及svg图标统一管理方法的封装

目录 js获取某一时间到现在的总时间方法封装 一、需求 二、方法 三、使用 js封装一个svg图标管理方法 一、需求 二、实现 三、使用 js获取某一时间到现在的总时间方法封装 一、需求 在做一些信息展示的时候,我们需要展示各种时间,有时是准确的创…

攻防世界-宜兴网信办-inget

题目 访问题目路径 这个题目的意思就是请输入ID,然后尝试绕过,那应该就是SQL注入,但是呢,我是个懒狗,我直接跑sqlmap 先跑数据库名 sqlmap "http://61.147.171.105:51322/?id1" --current-db 爆表 sqlma…

迅为3A5000开发板龙芯自主指令集从里到外100%全国产设计方案

迅为3A5000开发板龙芯处理器自主指令集架构从里到外100%全国产设计方案 iTOP-3A5000 开发板采用全国产龙芯3A5000处理器,基于龙芯自主指令系统(LoongArch)的LA464微结构,并进一步提升频率,降低功耗,优化性能…

低代码多分支协同开发的建设与实践

作者:黄也(胖丁) 引言 随着低代码的普及,在低代码平台上构建企业级应用逐渐成为生产趋势。同时,随着低代码技术的提升,越来越多的复杂应用在低代码平台中完成。在其研发生命周期中,低代码开发者就会面临多人协作、并…

卷积神经网络 CNN 基础概念

目录 一:卷积神经网络 二:局部感受野 三:卷积层 四:池化层 五:激活层 六:全连接层 七:卷积神经网络算法过程 一:卷积神经网络 卷积神经网络(Convolutional Neural Networks,C…

nor flash调试与使用总结

最近项目中使用到norflash,总结一下学习与使用经验 文章目录一、Flash基本概念存储器介绍与Flash在其中定位---非易失存储器类别中嵌入式领域常见设备Flash的典型分类---NorFlash(贵/容量小/读快写慢)与NandFlash(便宜/容量大/读慢…

Zookeeper 4 Zookeeper JavaAPI 操作 4.9 模拟12306 售票案例

Zookeeper 【黑马程序员Zookeeper视频教程,快速入门zookeeper技术】 文章目录Zookeeper4 Zookeeper JavaAPI 操作4.9 模拟12306 售票案例4.9.1 Curator 实现分布式锁 API4.9.2 分布式锁案例 - 模拟12306 售票4 Zookeeper JavaAPI 操作 4.9 模拟12306 售票案例 4.…

企业经常会问到的软件测试面试题及答案,一定要好好记住

相信对于很多软件测试新手来说,技术项目的面试是十分让人头疼的,生怕没回答得好,就会跟这个offer失之交臂,因此,今天,我以身边朋友面试遇到过的几个问题以及刷过的软件测试题库柠檬班中的压中的题目&#x…

Maven 项目模板

Maven 项目模板 Maven 使用 archetype(原型) 来创建自定义的项目结构,形成 Maven 项目模板。 在前面章节我们学到 Maven 使用下面的命令来快速创建 java 项目: mvn archetype:generate 什么是 archetype? archetype 也就是原型&#xff…

终于有人把性能优化讲清楚了!阿里架构师推荐的Java性能权威指南

Java给大部分人的感觉就是慢,有严重的性能问题。其实程序慢的问题,与语言无关,与Java无关。Java应用的性能优化也是一个老生常谈的话题,但是只要我们深入的了解性能调优方法,走遍天下都不怕! 大多数开发人…

mac系统M1pro芯片安装VMware Fusion虚拟机win11操作系统(原创详细版)

VMware22年11月份推出Fusion 13,这是Fusion虚拟软件的最新更新。它允许Mac用户操作虚拟机来运行非macOS操作系统,如Windows 11。 有了Fusion 13,英特尔和苹果芯片Mac用户可以访问Windows 11虚拟机。英特尔Mac提供对Windows 11的全面支持&…