热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

安卓addView源码分析

 Android把视图显示到屏幕上,从代码角度最终都是调用ViewGroup.addView方法,可以分为两类,一是初始化时添加视图,二是动态添

 Android把视图显示到屏幕上,从代码角度最终都是调用ViewGroup.addView方法,可以分为两类,一是初始化时添加视图,二是动态添加视图。

1. 从源码角度分析添加视图的流程,以下列出其中4个addView方法

public void addView(View child) {addView(child, -1);}public void addView(View child, int index) {LayoutParams params = child.getLayoutParams();if (params == null) {params = generateDefaultLayoutParams();if (params == null) {throw new IllegalArgumentException("generateDefaultLayoutParams() cannot return null");}}addView(child, index, params);}public void addView(View child, int width, int height) {final LayoutParams params = generateDefaultLayoutParams();params.width = width;params.height = height;addView(child, -1, params);}public void addView(View child, LayoutParams params) {addView(child, -1, params);}

2. 以上4个addView方法其最终都会调用以下方法,实现具体操作

/*** Adds a child view with the specified layout parameters.** @param child the child view to add* @param index the position at which to add the child* @param params the layout parameters to set on the child*/public void addView(View child, int index, LayoutParams params) {if (DBG ) {System. out.println(this + " addView");}// addViewInner() will call child.requestLayout() when setting the new LayoutParams// therefore, we call requestLayout() on ourselves before, so that the child's request// will be blocked at our level// 为什么调用invalidate还调用requestLayout?requestLayout();invalidate();// 为什么先requestLayout, invalidate之后才向ViewGroup中添加View?addViewInner(child, index, params, false);}

3. 调用ViewGroup.addViewInner

private void addViewInner(View child, int index, LayoutParams params,boolean preventRequestLayout) {// 此View是否已经添加if (child.getParent() !&#61; null) {throw new IllegalStateException("The specified child already has a parent. " &#43;"You must call removeView() on the child&#39;s parent first.");}if (!checkLayoutParams(params)) {params &#61; generateLayoutParams(params);}if (preventRequestLayout) {child.mLayoutParams &#61; params;} else {// 前面注释提到的&#xff0c;请求requestLayoutchild.setLayoutParams(params);}// 如果传入-1&#xff0c;直接添加到最后if (index <0) {index &#61; mChildrenCount;}// 添加到ViewGroupaddInArray(child, index);// tell our childrenif (preventRequestLayout) {child.assignParent( this);} else {// 指定添加view的父视图child.mParent &#61; this;}if (child.hasFocus()) {requestChildFocus(child, child.findFocus());}AttachInfo ai &#61; mAttachInfo;if (ai !&#61; null) {boolean lastKeepOn &#61; ai.mKeepScreenOn;ai.mKeepScreenOn &#61; false;// AttachInfo 与 View建立联系child.dispatchAttachedToWindow(mAttachInfo, (mViewFlags&VISIBILITY_MASK));if (ai.mKeepScreenOn) {needGlobalAttributesUpdate( true);}ai.mKeepScreenOn &#61; lastKeepOn;}// 可以通过此监听器获得是否有新View被添加if (mOnHierarchyChangeListener !&#61; null) {mOnHierarchyChangeListener .onChildViewAdded(this, child);}if ((child.mViewFlags & DUPLICATE_PARENT_STATE) &#61;&#61; DUPLICATE_PARENT_STATE) {mGroupFlags |&#61; FLAG_NOTIFY_CHILDREN_ON_DRAWABLE_STATE_CHANGE ;}}

疑问&#xff1a;

1. 为什么调用invalidate还调用requestLayout?
2. 为什么先requestLayout, invalidate之后才向ViewGroup中添加View?


推荐阅读
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 带添加按钮的GridView,item的删除事件
    先上图片效果;gridView无数据时显示添加按钮,有数据时,第一格显示添加按钮,后面显示数据:布局文件:addr_manage.xml<?xmlve ... [详细]
  • Android获取app应用程序大小的方法
    Android获取app应用程序大小的方法-Android对这种方法进行了封装,我们没有权限去调用这个方法,所以我们只能通过AIDL,然后利用Java的反射机制去调用系统级的方法。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文讲述了如何通过代码在Android中更改Recycler视图项的背景颜色。通过在onBindViewHolder方法中设置条件判断,可以实现根据条件改变背景颜色的效果。同时,还介绍了如何修改底部边框颜色以及提供了RecyclerView Fragment layout.xml和项目布局文件的示例代码。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 本文介绍了django中视图函数的使用方法,包括如何接收Web请求并返回Web响应,以及如何处理GET请求和POST请求。同时还介绍了urls.py和views.py文件的配置方式。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • 本文介绍了一款名为TimeSelector的Android日期时间选择器,采用了Material Design风格,可以在Android Studio中通过gradle添加依赖来使用,也可以在Eclipse中下载源码使用。文章详细介绍了TimeSelector的构造方法和参数说明,以及如何使用回调函数来处理选取时间后的操作。同时还提供了示例代码和可选的起始时间和结束时间设置。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • Go GUIlxn/walk 学习3.菜单栏和工具栏的具体实现
    本文介绍了使用Go语言的GUI库lxn/walk实现菜单栏和工具栏的具体方法,包括消息窗口的产生、文件放置动作响应和提示框的应用。部分代码来自上一篇博客和lxn/walk官方示例。文章提供了学习GUI开发的实际案例和代码示例。 ... [详细]
  • 今日份分享:Flutter自定义之旋转木马
    今日份分享:Flutter自定义之旋转木马-先上图,带你回到童年时光:效果分析子布局按照圆形顺序放置且平分角度子布局旋转、支持手势滑动旋转、快速滑动抬手继续旋转、自动旋转支持X轴旋 ... [详细]
author-avatar
H丨uAn9-伟安
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有