- 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.5 parseInclude 方法解析
/**
* 解析 include 标签
*/
private void parseInclude(XmlPullParser parser, Context context, View parent,
AttributeSet attrs) throws XmlPullParserException, IOException {
int type;
// 如果 include 标签的父 View 是 ViewGroup,则继续,否则抛出异常。
if (parent instanceof ViewGroup) {
// 使用主题包装。如果 include 中的 View 有自己的 attr 属性,则忽略。
final TypedArray ta = context.obtainStyledAttributes(attrs, ATTRS_THEME);
final int themeResId = ta.getResourceId(0, 0);
final boolean hasThemeOverride = themeResId != 0;
if (hasThemeOverride) {
context = new ContextThemeWrapper(context, themeResId);
}
ta.recycle();
// 获取 Layout 标签指向布局资源 id
int layout = attrs.getAttributeResourceValue(null, ATTR_LAYOUT, 0);
if (layout == 0) {
// 获取 Layout 的 value 值
final String value = attrs.getAttributeValue(null, ATTR_LAYOUT);
if (value == null || value.length() <= 0) {
throw new InflateException("You must specify a layout in the"
+ " include tag: <include layout=\"@layout/layoutID\" />");
}
// 尝试解析"?attr/name"成 id 资源
layout = context.getResources().getIdentifier(value.substring(1), null, null);
}
// include 的布局可能引用了主题属性
if (mTempValue == null) {
mTempValue = new TypedValue();
}
// 尝试从主题中获取布局资源 id,如果有的话。
if (layout != 0 && context.getTheme().resolveAttribute(layout, mTempValue, true)) {
layout = mTempValue.resourceId;
}
// 如果还是无法找到布局 id,抛出异常。
if (layout == 0) {
final String value = attrs.getAttributeValue(null, ATTR_LAYOUT);
throw new InflateException("You must specify a valid layout "
+ "reference. The layout ID " + value + " is not valid.");
} else {
// 获取 include 标签中布局的解析器
final XmlResourceParser childParser = context.getResources().getLayout(layout);
try {
final AttributeSet childAttrs = Xml.asAttributeSet(childParser);
// 查找根节点
while ((type = childParser.next()) != XmlPullParser.START_TAG &&
type != XmlPullParser.END_DOCUMENT) {
// Empty.
}
// 如果找不到根节点,抛出异常。
if (type != XmlPullParser.START_TAG) {
throw new InflateException(childParser.getPositionDescription() +
": No start tag found!");
}
// 获取标签名
final String childName = childParser.getName();
// 实例化 merge 标签
if (TAG_MERGE.equals(childName)) {
// <merge>标签不支持 android:theme,所以不需要其他处理
rInflate(childParser, parent, context, childAttrs, false);
} else {
// 创建 View 实例化对象
final View view = createViewFromTag(parent, childName,
context, childAttrs, hasThemeOverride);
final ViewGroup group = (ViewGroup) parent;
// 获取 View 的 id 和可见性
final TypedArray a = context.obtainStyledAttributes(
attrs, R.styleable.Include);
final int id = a.getResourceId(R.styleable.Include_id, View.NO_ID);
final int visibility = a.getInt(R.styleable.Include_visibility, -1);
a.recycle();
// 尝试加载<include />标签中的布局参数,如果父 View 无法生成布局参数(比如 include 标签下没有宽高参数是要抛出运行时异常的)
// 捕获运行时异常,然后用引用的 Layout 的 attrs 来创建布局参数
ViewGroup.LayoutParams params = null;
try {
// 使用 include 标签的 attrs 来生成布局参数
params = group.generateLayoutParams(attrs);
} catch (RuntimeException e) {
// Ignore, just fail over to child attrs.
}
if (params == null) {
// 如果 include 标签的 attrs 没有正确的生成布局参数,则使用 Layout 布局的 attrs 来生成布局参数
params = group.generateLayoutParams(childAttrs);
}
view.setLayoutParams(params);
// 实例化所有子 View
rInflateChildren(childParser, view, childAttrs, true);
if (id != View.NO_ID) {
view.setId(id);
}
switch (visibility) {
case 0:
view.setVisibility(View.VISIBLE);
break;
case 1:
view.setVisibility(View.INVISIBLE);
break;
case 2:
view.setVisibility(View.GONE);
break;
}
// 把布局实例化的 View 添加到父 View 上。
group.addView(view);
}
} finally {
childParser.close();
}
}
} else {
throw new InflateException("<include /> can only be used inside of a ViewGroup");
}
LayoutInflater.consumeChildElements(parser);
}绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论