从源代码角度分析ViewStub 疑问与原理
res/layout/main.xml
<LinearLayout >
<ViewStub
android:id="@+id/viewstub"
android:layout_width="100dip"
android:layout_marginTop="100dip"
android:layout_height="wrap_content"
android:layout="@layout/sub_layout"
/> </LinearLayout> res/layout/sub_layout.xml
<TextView
android:layout_width="50dip"
android:layout_marginTop="50dip"
android:layout_height="wrap_content"
android:text="ViewStub中包括的TextVeiw"/>
@Override
@android.view.RemotableViewMethod
public void setVisibility(int visibility) {
if (mInflatedViewRef != null) {
View view = mInflatedViewRef.get();
if (view != null) {
view.setVisibility(visibility);
} else {
throw new IllegalStateException("setVisibility called on un-referenced view");
}
} else {
super.setVisibility(visibility);
if (visibility == VISIBLE || visibility == INVISIBLE) {
inflate();
}
}
}
public final class ViewStub extends View {
......
public View inflate() {
final ViewParent viewParent = getParent(); // 1 为什么能够直接获取父视图?
// ViewStub的父视图必须是ViewGroup的子类
if (viewParent != null && viewParent instanceof ViewGroup) {
if (mLayoutResource != 0) { // ViewStub必须设置android:layout属性
final ViewGroup parent = (ViewGroup) viewParent;
final LayoutInflater factory;
if (mInflater != null) {
factory = mInflater;
} else {
factory = LayoutInflater.from(mContext);
}
// 2 inflate被载入视图
final View view = factory.inflate(mLayoutResource, parent,
false);
if (mInflatedId != NO_ID) {
view.setId(mInflatedId);
}
// 从父视图中获取当前ViewStub在父视图中的位置
final int index = parent.indexOfChild(this);
// 当前ViewStub也是个View只不过用来占位。所以先把占位的ViewStub视图删除
parent.removeViewInLayout(this);
// 3 此处获取的是ViewStub上面设置的參数
final ViewGroup.LayoutParams layoutParams = getLayoutParams();
if (layoutParams != null) {
parent.addView(view, index, layoutParams);
} else {
parent.addView(view, index);
}
// 目的是在复写的setVisibility方法中使用
// 由于ViewStub.setVisibility操作的是被载入视图并不是当前ViewStub视图
mInflatedViewRef = new WeakReference<View>(view);
// 调用监听
if (mInflateListener != null) {
mInflateListener.onInflate(this, view);
}
// 返回被载入视图,假设不须要当前能够忽略此返回对象
return view;
} else {
throw new IllegalArgumentException("ViewStub must have a valid layoutResource");
}
} else {
throw new IllegalStateException("ViewStub must have a non-null ViewGroup viewParent");
}
}
......
}
public class View {
public final ViewParent getParent() {
return mParent;
}
void assignParent(ViewParent parent) {
if (mParent == null) {
mParent = parent;
} else if (parent == null) {
mParent = null;
} else {
throw new RuntimeException("view " + this + " being added, but"
+ " it already has a parent");
}
}
}
public class ViewGroup {
public void addView(View child, int index, LayoutParams params) {
......
addViewInner(child, index, params, false);
}
private void addViewInner(View child, int index, LayoutParams params,
boolean preventRequestLayout) {
......
// tell our children
if (preventRequestLayout) {
child.assignParent(this);
} else {
child.mParent = this;
}
......
}
}
public final class ViewStub extends View {
public ViewStub(Context context) {
initialize(context);
}
private void initialize(Context context) {
mContext = context;
setVisibility(GONE); // 初始化时把自己设置为隐藏
setWillNotDraw(true);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(0, 0); // 全部子视图都设置为宽高为0
}
@Override
public void draw(Canvas canvas) { // 不正确自身与子视图进行绘制
}
@Override
protected void dispatchDraw(Canvas canvas) {
}
}
从源代码角度分析ViewStub 疑问与原理的更多相关文章
- Android的Message Pool是个什么鬼,Message Pool会否引起OOM——源代码角度分析
引言 Android中,我们在线程之间通信传递通常採用Android的消息机制,而这机制传递的正是Message. 通常.我们使用Message.obtain()和Handler.obtainMess ...
- 从信息论的角度分析DNN的工作原理
在前面的文章里,使用神经网络的任意函数拟合性结合了一点黎曼几何的坐标系变化的知识,解释了神经网络是怎样根据输入x,计算出每个分类下的能量Ei(x)的,再之后使用能量模型推算出了概率,从而展示了理论上可 ...
- 反编译字节码角度分析synchronized关键字的原理
1.synchronized介绍 synchronized是java关键字.JVM规范中,synchronized关键字用于在线程并发执行时,保证同一时刻,只有一个线程可以执行某个代码块或方法:同时还 ...
- 从虚拟机指令执行的角度分析JAVA中多态的实现原理
从虚拟机指令执行的角度分析JAVA中多态的实现原理 前几天突然被一个"家伙"问了几个问题,其中一个是:JAVA中的多态的实现原理是什么? 我一想,这肯定不是从语法的角度来阐释多态吧 ...
- 深入浅出!从语义角度分析隐藏在Unity协程背后的原理
Unity的协程使用起来比较方便,但是由于其封装和隐藏了太多细节,使其看起来比较神秘.比如协程是否是真正的异步执行?协程与线程到底是什么关系?本文将从语义角度来分析隐藏在协程背后的原理,并使用C++来 ...
- FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-TU
===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...
- go语言调度器源代码情景分析之二:CPU寄存器
本文是<go调度器源代码情景分析>系列 第一章 预备知识的第1小节. 寄存器是CPU内部的存储单元,用于存放从内存读取而来的数据(包括指令)和CPU运算的中间结果,之所以要使用寄存器来临时 ...
- Linux内核源代码情景分析系列
http://blog.sina.com.cn/s/blog_6b94d5680101vfqv.html Linux内核源代码情景分析---第五章 文件系统 5.1 概述 构成一个操作系统最重要的就 ...
- FFmpeg的HEVC解码器源代码简单分析:CTU解码(CTU Decode)部分-PU
===================================================== HEVC源代码分析文章列表: [解码 -libavcodec HEVC 解码器] FFmpe ...
随机推荐
- Android SurfaceView实战 带你玩转flabby bird (上)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/42965779 ,本文出自:[张鸿洋的博客] 1.概述 哈,记得以前写过Andro ...
- 高性能IO模型浅析(彩图解释)good
服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型. (2)同步非阻塞IO(Non-blocking IO):默认创建的s ...
- 【译】在ASP.NET中创建PDF-iTextSharp起步
原文 [译]在ASP.NET中创建PDF-iTextSharp起步 .Net framework 中自身并不包含可以和pdf打交道的方法.所以,当你需要你的ASP.Net Web应用程序中包含创建或与 ...
- api 跳转规则
api 配置: <Context docBase="zjzc-web-api" path="/api" reloadable="false&qu ...
- 基于visual Studio2013解决C语言竞赛题之0613递归求积
题目
- 基于MapReduce的HBase开发
在伪分布式模式和全分布式模式下 HBase 是架构在 HDFS 上的,因此完全可以将MapReduce 编程框架和 HBase 结合起来使用.也就是说,将 HBase 作为底层“存储结构”, MapR ...
- Denny Zhang:一辈子做一个自由职业者
程序猿訪谈录供稿 Denny是一个旅居美国的自由职业者,这是一份让人羡慕的职业,选择这个职业意味着他已经实现某种程度上的经济自由,能够最大限度的做自己喜欢的事情,对他来说,选择自由职业作为自己终生的事 ...
- 基于visual Studio2013解决C语言竞赛题之1024求和
题目 解决代码及点评 /* 已知有N个无规律的正整数,请编程序求出其中的素数并打印出能被5整除的数之积. */ #include <stdio.h> # ...
- Amazon RDS的通用型存储(SSD)
在今年的6月份,我们曾介绍过为Amazon EC2实例提供的基于SSD的弹性块级存储. 在公布几个月过后,这样的被称为通用型存储(SSD)的新型选择方式在创建新的EBS卷中已经占到了90%,我们从客户 ...
- QNX简介<转载>
QNX QNX是由QNX软件系统有限公司开发的实时操作系统. http://blog.csdn.net/happyhell/article/details/7087199 基本特征 * QNX是一个 ...