Android LayoutInflater的用法详解
发布日期:2021-09-04 18:45:12 浏览次数:2 分类:技术文章

本文共 10418 字,大约阅读时间需要 34 分钟。

相信我们在开发过程中肯定接触过LayoutInflater,比如ListView的适配器里的getView方法里通过LayoutInflater.from(Context).inflater来加载xml布局,在Fragment里的onCreateView里面也是一样,加载布局一共三种方法。

1,在Activity里面调用getLayoutInflater()
2, 通过LayoutInflater.from(context).inflater()
3, context.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
以上的三种方式从实现上都是一样的,Activity里面的getLayoutInflater()实际上调用的是PhoneWindow的实现,而PhoneWindow里源码的处理是LayoutInflater.from(context).inflater(),往下查找最终调用context.getSystemService。
context.getSystemService是Android里一个比较重要的api,是Activity的一个方法,根据传入的Name来取得对应的Object,然后转换成相应的服务对象。以下是系统相应的服务。
传入的Name返回的对象说明
WINDOW_SERVICE WindowManager 管理打开的窗口程序
LAYOUT_INFLATER_SERVICE LayoutInflater 取得xml里定义的view
ACTIVITY_SERVICE ActivityManager 管理应用程序的系统状态
POWER_SERVICE PowerManger 电源的服务
ALARM_SERVICE AlarmManager 闹钟的服务
NOTIFICATION_SERVICE NotificationManager 状态栏的服务
KEYGUARD_SERVICE KeyguardManager 键盘锁的服务
LOCATION_SERVICE LocationManager 位置的服务,如GPS
SEARCH_SERVICE SearchManager 搜索的服务
VEBRATOR_SERVICE Vebrator 手机震动的服务
CONNECTIVITY_SERVICE Connectivity 网络连接的服务
WIFI_SERVICE WifiManager Wi-Fi服务
TELEPHONY_SERVICE TeleponyManager 电话服务

但是LayoutInflater.from(context).inflater()的方法这么多,那它们到底是什么样的用法呢?

/**341     * Inflate a new view hierarchy from the specified xml resource. Throws342     * {@link InflateException} if there is an error.343     *344     * @param resource ID for an XML layout resource to load (e.g.,345     *        R.layout.main_page)346     * @param root Optional view to be the parent of the generated hierarchy.347     * @return The root View of the inflated hierarchy. If root was supplied,348     *         this is the root View; otherwise it is the root of the inflated349     *         XML file.350     */351    public View inflate(int resource, ViewGroup root) {352        return inflate(resource, root, root != null);353    }354355    /**356     * Inflate a new view hierarchy from the specified xml node. Throws357     * {@link InflateException} if there is an error. *358     * 

359 * Important   For performance360 * reasons, view inflation relies heavily on pre-processing of XML files361 * that is done at build time. Therefore, it is not currently possible to362 * use LayoutInflater with an XmlPullParser over a plain XML file at runtime.363 *364 * @param parser XML dom node containing the description of the view365 * hierarchy.366 * @param root Optional view to be the parent of the generated hierarchy.367 * @return The root View of the inflated hierarchy. If root was supplied,368 * this is the root View; otherwise it is the root of the inflated369 * XML file.370 */371 public View inflate(XmlPullParser parser, ViewGroup root) {372 return inflate(parser, root, root != null);373 }374375 /**376 * Inflate a new view hierarchy from the specified xml resource. Throws377 * {@link InflateException} if there is an error.378 *379 * @param resource ID for an XML layout resource to load (e.g.,380 * R.layout.main_page)381 * @param root Optional view to be the parent of the generated hierarchy (if382 * attachToRoot is true), or else simply an object that383 * provides a set of LayoutParams values for root of the returned384 * hierarchy (if attachToRoot is false.)385 * @param attachToRoot Whether the inflated hierarchy should be attached to386 * the root parameter? If false, root is only used to create the387 * correct subclass of LayoutParams for the root view in the XML.388 * @return The root View of the inflated hierarchy. If root was supplied and389 * attachToRoot is true, this is root; otherwise it is the root of390 * the inflated XML file.391 */392 public View inflate(int resource, ViewGroup root, boolean attachToRoot) {393 if (DEBUG) System.out.println("INFLATING from resource: " + resource);394 XmlResourceParser parser = getContext().getResources().getLayout(resource);395 try {396 return inflate(parser, root, attachToRoot);397 } finally {398 parser.close();399 }400 }

上面的方法非常清晰,直接看下inflate(parser, root, attachToRoot);

/**403     * Inflate a new view hierarchy from the specified XML node. Throws404     * {@link InflateException} if there is an error.405     * 

406 * Important   For performance407 * reasons, view inflation relies heavily on pre-processing of XML files408 * that is done at build time. Therefore, it is not currently possible to409 * use LayoutInflater with an XmlPullParser over a plain XML file at runtime.410 *411 * @param parser XML dom node containing the description of the view412 * hierarchy.413 * @param root Optional view to be the parent of the generated hierarchy (if414 * attachToRoot is true), or else simply an object that415 * provides a set of LayoutParams values for root of the returned416 * hierarchy (if attachToRoot is false.)417 * @param attachToRoot Whether the inflated hierarchy should be attached to418 * the root parameter? If false, root is only used to create the419 * correct subclass of LayoutParams for the root view in the XML.420 * @return The root View of the inflated hierarchy. If root was supplied and421 * attachToRoot is true, this is root; otherwise it is the root of422 * the inflated XML file.423 */424 public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) {425 synchronized (mConstructorArgs) {426 final AttributeSet attrs = Xml.asAttributeSet(parser);427 Context lastContext = (Context)mConstructorArgs[0];428 mConstructorArgs[0] = mContext;429 View result = root;430431 try {432 // Look for the root node.433 int type;434 while ((type = parser.next()) != XmlPullParser.START_TAG &&435 type != XmlPullParser.END_DOCUMENT) {436 // Empty437 }438439 if (type != XmlPullParser.START_TAG) {440 throw new InflateException(parser.getPositionDescription()441 + ": No start tag found!");442 }443444 final String name = parser.getName();445446 if (DEBUG) {447 System.out.println("**************************");448 System.out.println("Creating root view: "449 + name);450 System.out.println("**************************");451 }452453 if (TAG_MERGE.equals(name)) {454 if (root == null || !attachToRoot) {455 throw new InflateException("

can be used only with a valid "456 + "ViewGroup root and attachToRoot=true");457 }458459 rInflate(parser, root, attrs, false);460 } else {461 // Temp is the root view that was found in the xml462 View temp;463 if (TAG_1995.equals(name)) {464 temp = new BlinkLayout(mContext, attrs);465 } else {466 temp = createViewFromTag(root, name, attrs);467 }468469 ViewGroup.LayoutParams params = null;470 // 当父层不为空时471 if (root != null) {472 if (DEBUG) {473 System.out.println("Creating params from root: " +474 root);475 }476 // Create layout params that match root, if supplied // 获取父层的参数并赋值477 params = root.generateLayoutParams(attrs); // 子布局不贴上也会被设置LayoutParams478 if (!attachToRoot) {479 // Set the layout params for temp if we are not480 // attaching. (If we are, we use addView, below)481 temp.setLayoutParams(params);482 }483 }484485 if (DEBUG) {486 System.out.println("-----> start inflating children");487 }488 // Inflate all children under temp489 rInflate(parser, temp, attrs, true);490 if (DEBUG) {491 System.out.println("-----> done inflating children");492 }493494 // We are supposed to attach all the views we found (int temp)495 // to root. Do that now. // 父布局不为空并且贴上会被add到父层496 if (root != null && attachToRoot) {497 root.addView(temp, params);498 }499500 // Decide whether to return the root that was passed in or the501 // top view found in xml. // 父布局为空或者没有贴上,result就是View本身502 if (root == null || !attachToRoot) {503 result = temp;504 }505 }506507 } catch (XmlPullParserException e) {508 InflateException ex = new InflateException(e.getMessage());509 ex.initCause(e);510 throw ex;511 } catch (IOException e) {512 InflateException ex = new InflateException(513 parser.getPositionDescription()514 + ": " + e.getMessage());515 ex.initCause(e);516 throw ex;517 } finally {518 // Don't retain static reference on context.519 mConstructorArgs[0] = lastContext;520 mConstructorArgs[1] = null;521 }522 // 最后返回 result523 return result;524 }525 }

由上源码我们可以得出:

inflate(layout, null)返回的是View本身,且View本身所设置的布局参数无效,由父层和子View决定大小。
inflate(layout, null, false)同上一样,当父层为空,第三个值是否为真没有意义
inflate(layout, parent)子布局会被加入到父层并设置布局参数,具体大小由父层和子View决定
inflate(layout, parent, false)同上一样,区别就是false返回的是子View本身。
inflate(layout, parent, true)同第三个方法一样,返回父层View

转载地址:https://blog.csdn.net/weixin_34221112/article/details/89661251 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:移动端小图标模糊问题
下一篇:潜水侠获零度资本千万级天使轮融资,打造围绕水下智能的水下生态链

发表评论

最新留言

路过按个爪印,很不错,赞一个!
[***.219.124.196]2024年04月14日 07时24分27秒