- CompoundButton 源码分析
- LinearLayout 源码分析
- SearchView 源码解析
- LruCache 源码解析
- ViewDragHelper 源码解析
- BottomSheets 源码解析
- Media Player 源码分析
- NavigationView 源码解析
- Service 源码解析
- Binder 源码分析
- Android 应用 Preference 相关及源码浅析 SharePreferences 篇
- ScrollView 源码解析
- Handler 源码解析
- NestedScrollView 源码解析
- SQLiteOpenHelper/SQLiteDatabase/Cursor 源码解析
- Bundle 源码解析
- LocalBroadcastManager 源码解析
- Toast 源码解析
- TextInputLayout
- LayoutInflater 和 LayoutInflaterCompat 源码解析
- TextView 源码解析
- NestedScrolling 事件机制源码解析
- ViewGroup 源码解析
- StaticLayout 源码分析
- AtomicFile 源码解析
- AtomicFile 源码解析
- Spannable 源码分析
- Notification 之 Android 5.0 实现原理
- CoordinatorLayout 源码分析
- Scroller 源码解析
- SwipeRefreshLayout 源码分析
- FloatingActionButton 源码解析
- AsyncTask 源码分析
- TabLayout 源码解析
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
5.4 rInflateChildren 和 rInflate 方法解析
rInflate 方法主要是遍历传入的 Parent 的子节点,实例化 Parent 的所有子 View。当遍历的时候发现当前 View 还有子 View 则递归调用此方法继续实例化当前 View 的子 View。
这里面主要的操作有:
- parseRequestFocus(),处理请求焦点。
- parseInclude(),处理 include 标签。
- 实例化 1995 或一般 View 并添加到当前 View 的父 View 上。
源码分析:
/**
* 循环方法用来深入 xml 的层级并且实例化内部的 View(非根节点 View),这个方法通过调用 rInflate,并使用 Parent 的 Context 作为
* 实例化 View 的 Context。
*/
final void rInflateChildren(XmlPullParser parser, View parent, AttributeSet attrs,
boolean finishInflate) throws XmlPullParserException, IOException {
rInflate(parser, parent, parent.getContext(), attrs, finishInflate);
}
/**
* 循环方法用来深入 xml 的层级并且实例化 view 以及 View 的子 View,
* 最后调用 onFinishInflate() 方法
*/
void rInflate(XmlPullParser parser, View parent,Context context, final AttributeSet attrs,
boolean finishInflate) throws XmlPullParserException, IOException {
// 获取当前 xml 解析的深度
final int depth = parser.getDepth();
int type;
// 循环遍历 xml 节点
while (((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if (type != XmlPullParser.START_TAG) {
continue;
}
// 获取节点的名称
final String name = parser.getName();
// 请求焦点
if (TAG_REQUEST_FOCUS.equals(name)) {
parseRequestFocus(parser, parent);
} else if (TAG_TAG.equals(name)) {
// 解析<tag>元素,并且设置键控标签在它包含的 View 上。最终调用的是 View 的 view.setTag(key, value);方法
parseViewTag(parser, parent, attrs);
} else if (TAG_INCLUDE.equals(name)) {
//处理 include 标签
if (parser.getDepth() == 0) {
// 最外层使用 include 标签抛出异常。
throw new InflateException("<include /> cannot be the root element");
}
// 解析 include 标签引入的布局
parseInclude(parser, context, parent, attrs);
} else if (TAG_MERGE.equals(name)) {
// 如果是 merge 标签则抛出异常(因为此方法实例化的是 xml 根节点的子 View,所以非根节点不能使用 merge 标签。)
throw new InflateException("<merge /> must be the root element");
} else {
// 一般性的 View
final View view = createViewFromTag(parent, name, context, attrs);
final ViewGroup viewGroup = (ViewGroup) parent;
// 获取父 View 的 LayoutParams,并在把 View 添加到父 View 的时候带过去
//(这里解释了,为什么自己手动 new 一个 View,添加到父 View 上的时候需要 new 父 View 的 LayoutParams 参数而不是自己的 LayoutParams 参数。)
final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);
// 递归遍历实例化
rInflateChildren(parser, view, attrs, true);
viewGroup.addView(view, params);
}
}
// 如果父 View 下的所有 View 都完成填充,则调用父 View 的 onFinishInflate() 方法。
if (finishInflate) parent.onFinishInflate();
}绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论