ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

自定义View相关面试题

自定义View相关面试题 目录一.ListView中图片错位的问题是怎么产生的有什么好的解决方案二.说一说你对RecycleView的认识。三.RecyclerView与ListView有哪几层缓存机制四.RecyclerView与ListView这几层缓存机制有什么区别和相同点五.请简单描述下View的渲染。掉帧、卡顿的原因六.请简单说一下View的绘制流程。六.谈一谈你对view的刷新机制的认识。七.requestLayout、invalidate与postInvalidate的区别。八.描述下Activity、Window、View三者的关系与联系。九.你是怎么优化自定义view的十.在自定义view时怎么知道View的大小十一.如果创建自定义View那么如何提供获取View属性的接口十二.知道SurfaceView吗谈一谈你对它的认识十三.普通View和SurfaceView的区别?一.ListView中图片错位的问题是怎么产生的有什么好的解决方案因为ListView使用了离屏缓存机制缓存了convertview而且是异步的当整个屏幕刚好能显示7个item时。如果此时上划从而显示第9个item(注意第8个也是新建的view不会进行复用)但它是重用第一个item来显示的而此时又异步进行网络请求第9个item的图片自然比第一个item的图片加载慢所以第9个item就显示第1个的图片。而当向下滑动是因为第9个item的图片此时加载完成所以第1个item又会复用第9个item的图片所以这样就会导致图片错乱了。解决方案是通过imgUrl给ImageView控件设置一个标识并设置一张默认图片。当向上滑动时加载完成时判断imgUrl是否一致一致说明是正确加载的图片这样即使第1个item的加载图片要比第9个的要快但因为此时的标识是第9个item的所以也不会显示第1个item的图片。android listview使用glide异步加载图片错位闪烁问题 - it610.com参考网上方法https://www.jianshu.com/p/f5593b87ee07//获取图像控件的TagStringtag(String)holder.imgView.getTag();//如果不一样则设置为默认图片if(!TextUtils.equals(mDataList.get(position).getUrl(),tag)){holder.imgView.setImageRehttps://www.it610.com/article/1290038983128064000.htm二.说一说你对RecycleView的认识。1.RecycleView的概述。RecycleView是一个滚动控件可以看作的ListView的升级版不仅可以轻松的完成ListView的效果还可以实现其他效果例如网格布局、横向滑动、瀑布流。而且还封装优化了ListView的缺点例如ViewHolder的复用。2.RecycleView的特点。①.RecycleView可以轻松实现线性布局、网格布局、横向线性布局、瀑布流具体通过LayoutManager的子类去指定。GridLayoutManager实现网格布局、LinearLayoutManager实现线性布局、StaggeredGridLayoutManager可以实现瀑布流其中的高度可以根据每个item设置然后就可以实现高度不同的网格布局即瀑布流想要改变分割线可以通过ItemDecoration来设置②.想要给子项添加动画则可以通过ItemAnimator来实现③.ViewHolder已经封装在RecycleView的Adapter中可以直接实现其方法就行④.RecycleView的点击事件可以由开发者根据需求去自行注册或者继承OnItemTouchListener实现自定义的RecycleView监听器。⑤.RecyclerView比ListView多两级缓存支持多个离ItemView缓存支持开发者自定义缓存处理逻辑支持所有RecyclerView共用同一个RecyclerViewPool(缓存池)。⑥.RecyclerView更大的亮点在于提供了局部刷新的接口通过局部刷新就能避免调用许多无用的bindView。3.RecycleView的使用。简单描述下先实现子项布局item然后引入RecycleView控件然后创建自定义的Adapter继承RecycleView的Adapter并实现方法最后在界面中找到RecycleView然后将item界面相关数据设置到自定义的Adapter中最后RecycleView与此Adapter关联。三.RecyclerView与ListView有哪几层缓存机制1.ListView有两层缓存机制分别是①.mActiveViews屏幕内view复用不需要回调createView与bindView意义在于快速重用屏幕上可见的列表项ItemView②.mScrapView即将进入屏幕的view复用不需要回调createView需要回调bindView意义在于缓存离开屏幕的ItemView2.RecycleView有四层缓存机制分别是①.mAttachedScrap屏幕内view复用不需要回调createView与bindView意义在于快速重用屏幕上可见的列表项ItemView和ListView的mActiveViews缓存一致②.mCachedViews即将进入屏幕的view复用不需要回调createView与bindView意义在于缓存离开屏幕的ItemView③.自定义缓存④.mReyclerViewPool可用于多个RecycleView复用意义在于可以实现ViewPager多列表场景下的ItemView缓存四.RecyclerView与ListView这几层缓存机制有什么区别和相同点相同点①.ListView的屏幕内复用与RecycleView的屏幕内复用缓存功能相似意义在于快速重用屏幕上可见的列表项ItemView②.离屏缓存功能相似意义在于缓存离开屏幕的ItemView目的是让即将进入的屏幕ItemView重用不同点①.离屏缓存ListView需要回调bindView()方法RecycleView不需要回调bindView()方法RecycleView有一个RecycleViewPool缓存池可以实现ViewPager多列表场景下的ItemView缓存ListView没有此功能。②.RecycleView缓存的是ViewHolder抽象的可以理解为ViewViewHolderFlag标识符标志flag的作用是判断view是否需要重新bindViewListView缓存的是View。③.RecyclerView中mCacheViews(屏幕外)获取缓存时是通过匹配pos获取目标位置的缓存这样做的好处是当数据源数据不变的情况下无须重新bindView而同样是离屏缓存ListView从mScrapViews根据pos获取相应的缓存但是并没有直接使用而是重新getView即必定会重新bindView。RecyclerView面试必问 - 简书RecyclerView是谷歌官方出的一个用于大量数据展示的新控件可以用来代替传统的ListView更加强大和灵活。 同时也希望能通过本文让大家快速了解Recycler...https://www.jianshu.com/p/d8a23a7e8199五.请简单描述下View的渲染。掉帧、卡顿的原因如果在60Hz的设备上Android系统每个16ms(1000/60)就发出VSYNC(垂直同步)信号通知UI进行渲染。当渲染成功也就是能达到60fps就能让画面看起来流程所以每次渲染的计算机操作都必须在16ms内完成。如果渲染超时这一帧画面渲染时间超过16ms垂直同步机制就会让显示器等到GPU完成栅格化渲染操作这样会让这一帧画面多停留16ms或者更多时间这样就会造成画面的卡顿现象。绘制优化 打造布局_gongjdde的博客-CSDN博客本次主题会讲到如下概念屏幕撕裂、垂直同步、硬件加速、Profile GPU Rendering(GPU显示模式)、Systrace、Hierarchy Viewer、Android Lint、调试GPU过度绘制、RelativeLayout与LinearLayout、布局复用include、去除冗余merge、ViewStub提高加载速度、adapterView优化、自定义视图和布局优化、过度绘...https://blog.csdn.net/gongjdde/article/details/90200078View渲染机制_say_from_wen的博客-CSDN博客_view渲染写在开头本文章学习了View的渲染机制了解它对于布局优化会有很大的帮助可以加深对过度渲染导致的UI卡顿的了解并提出更合适的解决方案。站在前人的肩膀上学习在此表示感谢。如何查看过度绘制在学习渲染机制前先了解下如何查看过度绘制其实手机上自带工具在开发者工具中如图它是以颜色来区分你屏幕上的某一点像素被渲染过几层的蓝色淡绿淡红深红。蓝色 意味着overdhttps://blog.csdn.net/say_from_wen/article/details/79093883六.请简单说一下View的绘制流程。View的整个绘制流程可以分为以下三个阶段measure: 判断是否需要重新计算View的大小需要的话则计算layout: 判断是否需要重新计算View的位置需要的话则计算draw: 判断是否需要重新绘制View需要的话则重绘制。①.view的测量此阶段的目的是计算出控件树中的各个控件要显示其内容的话需要多大尺寸。主要是有一个MeasureSpec参数高2位代表SpecMode低30位代表SpecSize。SpecMode有三种情况分别是EXACTLY: 对子View提出了一个确切的建议尺寸AT_MOST: 子View的大小不得超过SpecSizeUNSPECIFIED: 对子View的尺寸不作限制通常用于系统内部。view的MeasureSpec由其父布局的MeasureSpec和自身的LayoutParams决定的。②.view的布局这个阶段主要就是根据上一阶段得到的View的测量宽高来确定View的最终显示位置。③.View的绘制。根据google官方步骤。(1)绘制背景(drawBackground(canvas))(2)如有需要保存图层(canvas.save canvas.saveLayer)(3)绘制view(onDraw(canvas))(4)绘制子view(dispatchDraw(canvas))(5)如有需要绘制阴影效果(6)绘制装饰(ondrawScrollBars)(7)如有需要绘制焦点高亮显示。(drawDefaultFocusHighlight(canvas))https://gonglipeng.blog.csdn.net/article/details/128106660https://gonglipeng.blog.csdn.net/article/details/128106660android view的工作原理_gongjdde的博客-CSDN博客本章主要讲ViewRoot、DecorView、MeasureSpec、View的工作流程、自定义view1.ViewRoot和DecorView①ViewRoot的PerformTraversals方法开始最终调用view的measure、layout、draw方法。②decorview最终分为有titlebar和content两个布局我们平时设置的setcontentvie...https://blog.csdn.net/gongjdde/article/details/89278976Android View 的绘制流程 转发_gongjdde的博客-CSDN博客本文转自https://www.cnblogs.com/jycboy/p/6219915.html概述本篇文章会从源码基于Android 6.0角度分析Android中View的绘制流程侧重于对整体流程的分析对一些难以理解的点加以重点阐述目的是把View绘制的整个流程把握好而对于特定实现细节则可以日后再对相应源码进行研读。在进行实际的分析之前我们先来看下面这张图...https://blog.csdn.net/gongjdde/article/details/88941751六.谈一谈你对view的刷新机制的认识。子view需要刷新的时候就会调用invalidate()找到自己的父view并通知它刷新自己。直到传递到ViewRootImpl中走到 ViewRootImpl 中的scheduleTraversals()里来安排一次遍历绘制View 树的任务然后通过消息的同步机制最终触发performTraversals方法进行开始View树重绘流程(只绘制需要重绘的视图)。 由于没有添加measure和layout的标记位而添加了draw流程的标记位因此measure、layout流程不会执行而是直接从draw流程开始。invalidate()方法是在主线程中调用的如果需要在工作线程中调用可以使用postInvalidate()方法。七.requestLayout、invalidate与postInvalidate的区别。1.相同点都是子view找到父view一层一层往上调用最终走到 ViewRootImpl 中的 scheduleTraversals() 里来安排一次遍历绘制 View 树的任务然后通过消息的同步机制最终触发performTraversals()方法。2.requestLayout根据标记位肯定会调用到onMeasure()和onLayout()方法但是不一定会走到onDraw()方法。可能走到onDraw()方法的情况requestLayout调用onDraw之谜_litefish的专栏-CSDN博客_requestlayout调用示例3.invalidate根据标记为肯定会走到performDraw()流程进而走到onDraw流程但是不会走performMeasure()performLayout()流程进而不会走onMeasure()和onLayout()流程。4.invalidate()方法是在主线程中调用的如果需要在工作线程中调用可以使用postInvalidate()方法。六七相关的文章Android View 深度分析requestLayout、invalidate与postInvalidate_蓝天白云梦的csdn博客-CSDN博客_android requestlayout前言前几篇文章中笔者对View的三大工作流程进行了详细分析而这篇文章则详细讲述与三大工作流程密切相关的两个方法分别是requestLayout和invalidate如果对Viwe的三个工作流程不熟悉的读者可以先看看前几篇文章以便能更容易理解这篇文章的内容。https://blog.csdn.net/a553181867/article/details/51583060View的invalidate()方法的源码分析_neuHenry-CSDN博客_view的invalidate这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能丰富你的文章UML 图表FLowchart流程图导出与导入导出导入欢迎使用Ma...https://blog.csdn.net/u010347226/article/details/105195847View的requestLayout()方法的源码分析_neuHenry-CSDN博客首先来看一下requestLayout()方法是做什么的View#requestLayout() /** * Call this when something has changed which has invalidated the * layout of this view. This will schedule a layout pass of the view * tree. This should not be called while the viewhttps://blog.csdn.net/u010347226/article/details/106746783Android 屏幕(View)刷新机制(原理)_蒙的博客-CSDN博客_view的刷新机制前言在平时开发项目的时候我们都知道生成一个view加入到window中或者对显示的view调用其属性改变的方法亦或者启动在某个view上配置的动画就会让屏幕进行刷新达到自己想要的ui效果。但是咱们的代码是怎么触发屏幕刷新或者说系统是用怎样的机制去刷新屏幕改变的view属性的很多人还是不太清楚。当然最开始我也是没有系统的梳理过前段时间经过对一些文章博客的阅读和系统源码的梳理我才有了较为清晰的感...https://blog.csdn.net/mysimplelove/article/details/92635237八.描述下Activity、Window、View三者的关系与联系。一个Activity有一个Window对象由PhoneWindow来实现。而PhoneWindow对象持有一个DecorView对象它就是整个应用界面的根view了也就是顶层视图。DecorView包含布局内容就是用户看到的UI界面。PhoneWindow对其进行管理监听它的所有View事件。DecorView分成两部分分别是TitleView与ContentView。而平时Activity的布局文件xml就是设置在ContentView里。所以当执行setContentView()方法后ActivityThread会调用handleResumeActivity然后调用Activity的onResume()然后调用Activity的makeVisible()方法最终把DecorView添加到PhoneWindow中让其管理并显示出来。一篇文章看明白 Activity 与 Window 与 View 之间的关系_jeanboy-CSDN博客_activity windowAndroid - Activity 与 Window 与 View 之间的关系概述我们知道 Activity 启动后就可以看到我们写的 Layout 布局界面Activity 从 setContentView() 到显示中间做了什么呢下面我们就来分析下这个过程。如不了解 Activity 的启动过程请参阅Activity 启动过程本文主要对于以下问题进行分析Wi...https://blog.csdn.net/freekiteyu/article/details/79408969九.你是怎么优化自定义view的1.减少冗余的代码尤其是onDraw()里的代码尽量减少调用刷新方法的频率。2.避免在onDraw()里处理内存分配的逻辑不要在onDraw()里面创建对象3.因为每次执行requestLayout()方法都是非常耗时所以最好自定义ViewGroup来执行因为ViewGroup有onLayout()方法直接可以对子控件进行布局Android 性能优化七自定义view绘制优化_深南大盗的博客-CSDN博客_如何优化自定义viewAndroid 性能优化 (一)APK高效瘦身http://blog.csdn.net/whb20081815/article/details/70140063Android 性能优化 (二)数据库优化 秒变大神http://blog.csdn.net/whb20081815/article/details/70142033 Android 性能优化三布局优化 秒变大...https://blog.csdn.net/WHB20081815/article/details/74474736十.在自定义view时怎么知道View的大小其实就是对view的测量分别以View与ViewGroup的两个角度来回答1.如果测量的是View那么使用getDefaultSize()方法。getDefaultSize()方法第一个参数是最小宽度/高度第二个参数是widthMeasureSpec或者heightMeasureSpec最终getDefaultSize()返回的是MeasureSpec。2.如果测量的是ViewGroup那么需要先遍历它的所有子控件然后重写onMeasure()方法。通过for循环当子view状态可见则调用measureChild/measureChildWithMargins根据子view的LayoutParams参数和父布局的MeasureSpec参数通过getChildMeasureSpec方法确定子view的MeasureSpec参数最后结果传给child的measure()方法如果此子view是ViewGroup则重复上面的步骤如果不是则可以获取到子view的最终测量结果最后通过测量出来的所有子view的结果得到ViewGroup的测量结果。Android View 的绘制流程 转发_gongjdde的博客-CSDN博客本文转自https://www.cnblogs.com/jycboy/p/6219915.html概述本篇文章会从源码基于Android 6.0角度分析Android中View的绘制流程侧重于对整体流程的分析对一些难以理解的点加以重点阐述目的是把View绘制的整个流程把握好而对于特定实现细节则可以日后再对相应源码进行研读。在进行实际的分析之前我们先来看下面这张图...https://blog.csdn.net/gongjdde/article/details/88941751十一.如果创建自定义View那么如何提供获取View属性的接口思路本质上就是问自定义view过程中自定义属性的步骤1.在自定义View过程中当需要给View创建属性时先在values目录下创建attrs.xml文件然后定义相关属性。2.然后在布局文件中通过命名空间res-auto自动导包或者手动导包然后就可以在布局文件中使用自定义属性了。3.在自定义view的有两个参数的构造方法中通过attributes参数获取TypeArray属性集合然后通过属性集合获取自定义的属性值。十二.知道SurfaceView吗谈一谈你对它的认识思路是什么有什么用使用方法或步骤。1.SurfaceView的概述。一般的View控件的UI是在主线程中进行绘制的通过刷新来进行重绘60hz的设备上刷新时间为16ms。所以在刷新的过程中如果需要执行的逻辑处理过多会容易出现卡顿掉帧的现象而且也会造成主线程阻塞引起ANR问题。所以google就推出SurfaceView去解决这些问题。SurfaceView继承View所以拥有View的特性。SurfaceView有两个子类分别是GLSurfaceView和VideoView。它们有自己独立的、区别于普通View的绘图表面Surface通过在Surface上绘制图像然后将产生的视图数据交给SurfaceFlingerSurfaceFlinger就负责将这些视图数据进行合成最终发送到显示设备上从而显示到屏幕上。现在假设Activity窗口有DecorViewDecorView里有TextView、Button和SurfaceView。DecorView及其TextView、Button的UI都是在SurfaceFlinger中的同一个Layer上绘制的而SurfaceView的UI则在SurfaceFlinger的另一个Layer或LayerBuffer上绘制的。2.Surface的特点。①.具有独立的绘图表面所以它的UI绘制在独立的线程中进行不会造成主线程阻塞②.View主要用于主动更新而SurfaceView用于被动更新③.当自定义view需要频繁刷新或者刷新是需要处理比较复杂的逻辑时可以用SurfaceView④.SurfaceView在绘图时使用了双缓冲机制。3.SurfaceView的使用①.首先创建自定义SurfaceView并继承SurfaceView类然后分别实现SurfaceHolder.Callback和Runnable以及其他方法。②.获取SurfaceHolder这里的SurfaceHolder的作用就是用它来保存Surface对象的引用这样就可以操作Surface从而进行绘图的操作。③.接着通过SurfaceHolder的lockCanvas()方法获得Canvas对象从而在子线程中进行绘图工作。④.中间可以进行各种绘图操作比如实现一个用户随手指滑动的轨迹来进行绘图的功能。在ACTION_DOWN通过path.moveTo()确定起点然后在ACTION_MOVE通过path.lineTo()(或者贝塞尔曲线path.quadTo())绘制路径最后在获取的Canvas对象进行绘图操作。⑤.最后通过holder.unlockCanvasAndPost(canvas)方法对画布内容进行提交。SurfaceView实现手势绘制和视频播放_zh_qianwei的博客-CSDN博客_android surface绘制视频SurfaceView和View的主要区别View主要适用于主动更新SurfaceView主要适用于被动、频繁更新View在主线程中对画面进行刷SurfaceView通常会通过一个子线程进行页面刷新View在绘制是没有使用双缓冲机制而SurfaceView在底层实现机制中已经实现了双缓冲机制https://blog.csdn.net/zh_qianwei/article/details/49252107SurfaceView和普通view的区别及简单使用_lidongxiu0714-CSDN博客_surfaceview1 SurfaceView介绍SurfaceView第一印象它是一个view因为它继承了View有两个直接子类GLSurfaceView,VideoView。但根据SDK文档SurfaceView和普通的view又有较大区别。最显著的区别就是普通view和它的宿主窗口共享一个绘图表面SurfaceSurfaceView虽然也在View的树形结构中但是它有属于自己的绘图表面。...https://blog.csdn.net/u010126792/article/details/86249399十三.普通View和SurfaceView的区别?View适用主动更新SurfaceView 适用被动更新如频繁的刷新View在UI线程更新在非UI线程更新会报错当在主线程更新view时如果耗时过长也会出错, SurfaceView在子线程刷新不会阻塞主线程适用于界面频繁更新、对帧率要求较高的情况。SurfaceView可以控制刷新频率。SurfaceView底层利用双缓存机制绘图时不会出现闪烁问题。综合来说SurfaceView的创建和用法要比自定义view的复杂占用资源也比自定义view要多SurfaceView和普通view的区别及简单使用_lidongxiu0714-CSDN博客_surfaceview1 SurfaceView介绍SurfaceView第一印象它是一个view因为它继承了View有两个直接子类GLSurfaceView,VideoView。但根据SDK文档SurfaceView和普通的view又有较大区别。最显著的区别就是普通view和它的宿主窗口共享一个绘图表面SurfaceSurfaceView虽然也在View的树形结构中但是它有属于自己的绘图表面。...https://blog.csdn.net/u010126792/article/details/86249399
返回列表