Android LayoutInflater的用法详解

2023-10-22 13:50

本文主要是介绍Android LayoutInflater的用法详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

相信我们在开发过程中肯定接触过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. Throws
342     * {@link InflateException} if there is an error.
343     *
344     * @param resource ID for an XML layout resource to load (e.g.,
345     *        <code>R.layout.main_page</code>)
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 inflated
349     *         XML file.
350     */
351    public View inflate(int resource, ViewGroup root) {
352        return inflate(resource, root, root != null);
353    }
354
355    /**
356     * Inflate a new view hierarchy from the specified xml node. Throws
357     * {@link InflateException} if there is an error. *
358     * <p>
359     * <em><strong>Important</strong></em>&nbsp;&nbsp;&nbsp;For performance
360     * reasons, view inflation relies heavily on pre-processing of XML files
361     * that is done at build time. Therefore, it is not currently possible to
362     * use LayoutInflater with an XmlPullParser over a plain XML file at runtime.
363     *
364     * @param parser XML dom node containing the description of the view
365     *        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 inflated
369     *         XML file.
370     */
371    public View inflate(XmlPullParser parser, ViewGroup root) {
372        return inflate(parser, root, root != null);
373    }
374
375    /**
376     * Inflate a new view hierarchy from the specified xml resource. Throws
377     * {@link InflateException} if there is an error.
378     *
379     * @param resource ID for an XML layout resource to load (e.g.,
380     *        <code>R.layout.main_page</code>)
381     * @param root Optional view to be the parent of the generated hierarchy (if
382     *        <em>attachToRoot</em> is true), or else simply an object that
383     *        provides a set of LayoutParams values for root of the returned
384     *        hierarchy (if <em>attachToRoot</em> is false.)
385     * @param attachToRoot Whether the inflated hierarchy should be attached to
386     *        the root parameter? If false, root is only used to create the
387     *        correct subclass of LayoutParams for the root view in the XML.
388     * @return The root View of the inflated hierarchy. If root was supplied and
389     *         attachToRoot is true, this is root; otherwise it is the root of
390     *         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. Throws
404     * {@link InflateException} if there is an error.
405     * <p>
406     * <em><strong>Important</strong></em>&nbsp;&nbsp;&nbsp;For performance
407     * reasons, view inflation relies heavily on pre-processing of XML files
408     * that is done at build time. Therefore, it is not currently possible to
409     * use LayoutInflater with an XmlPullParser over a plain XML file at runtime.
410     *
411     * @param parser XML dom node containing the description of the view
412     *        hierarchy.
413     * @param root Optional view to be the parent of the generated hierarchy (if
414     *        <em>attachToRoot</em> is true), or else simply an object that
415     *        provides a set of LayoutParams values for root of the returned
416     *        hierarchy (if <em>attachToRoot</em> is false.)
417     * @param attachToRoot Whether the inflated hierarchy should be attached to
418     *        the root parameter? If false, root is only used to create the
419     *        correct subclass of LayoutParams for the root view in the XML.
420     * @return The root View of the inflated hierarchy. If root was supplied and
421     *         attachToRoot is true, this is root; otherwise it is the root of
422     *         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;
430
431            try {
432                // Look for the root node.
433                int type;
434                while ((type = parser.next()) != XmlPullParser.START_TAG &&
435                        type != XmlPullParser.END_DOCUMENT) {
436                    // Empty
437                }
438
439                if (type != XmlPullParser.START_TAG) {
440                    throw new InflateException(parser.getPositionDescription()
441                            + ": No start tag found!");
442                }
443
444                final String name = parser.getName();
445
446                if (DEBUG) {
447                    System.out.println("**************************");
448                    System.out.println("Creating root view: "
449                            + name);
450                    System.out.println("**************************");
451                }
452
453                if (TAG_MERGE.equals(name)) {
454                    if (root == null || !attachToRoot) {
455                        throw new InflateException("<merge /> can be used only with a valid "
456                                + "ViewGroup root and attachToRoot=true");
457                    }
458
459                    rInflate(parser, root, attrs, false);
460                } else {
461                    // Temp is the root view that was found in the xml
462                    View temp;
463                    if (TAG_1995.equals(name)) {
464                        temp = new BlinkLayout(mContext, attrs);
465                    } else {
466                        temp = createViewFromTag(root, name, attrs);
467                    }
468
469                    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);//  子布局不贴上也会被设置LayoutParams
478                        if (!attachToRoot) {
479                            // Set the layout params for temp if we are not
480                            // attaching. (If we are, we use addView, below)
481                            temp.setLayoutParams(params);
482                        }
483                    }
484
485                    if (DEBUG) {
486                        System.out.println("-----> start inflating children");
487                    }
488                    // Inflate all children under temp
489                    rInflate(parser, temp, attrs, true);
490                    if (DEBUG) {
491                        System.out.println("-----> done inflating children");
492                    }
493
494                    // 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                    }
499
500                    // Decide whether to return the root that was passed in or the
501                    // top view found in xml.// 父布局为空或者没有贴上,result就是View本身
502                    if (root == null || !attachToRoot) {
503                        result = temp;
504                    }
505                }
506
507            } 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          // 最后返回 result
523            return result;
524        }
525    }

由上源码我们可以得出:
inflate(layout, null)返回的是View本身,addView后View本身所设置的布局参数无效,由父层和子View决定大小。
inflate(layout, null, false)同上一样,当父层为空,第三个值是否为真没有意义。
inflate(layout, parent)子布局会被add到父层并为该View设置布局参数,具体大小由父层和子View决定。
inflate(layout, parent, false)同上一样,区别就是false父层不会addView。
inflate(layout, parent, true)同第三个方法一样,父层View会addView并为其设置参数。

这篇关于Android LayoutInflater的用法详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/261845

相关文章

#error用法

/* *检查编译此源文件的编译器是不是C++编译器 *如果使用的是C语言编译器则执行#error命令 *如果使用的是 C++ 编译器则跳过#error命令 */ #ifndef __cplusplus #error 亲,您当前使用的不是C++编译器噢! #endif #include <stdio.h> int main() {

十四、观察者模式与访问者模式详解

21.观察者模式 21.1.课程目标 1、 掌握观察者模式和访问者模式的应用场景。 2、 掌握观察者模式在具体业务场景中的应用。 3、 了解访问者模式的双分派。 4、 观察者模式和访问者模式的优、缺点。 21.2.内容定位 1、 有 Swing开发经验的人群更容易理解观察者模式。 2、 访问者模式被称为最复杂的设计模式。 21.3.观察者模式 观 察 者 模 式 ( Obser

【操作系统】信号Signal超详解|捕捉函数

🔥博客主页: 我要成为C++领域大神🎥系列专栏:【C++核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞👍收藏⭐评论✍️ 本博客致力于知识分享,与更多的人进行学习交流 ​ 如何触发信号 信号是Linux下的经典技术,一般操作系统利用信号杀死违规进程,典型进程干预手段,信号除了杀死进程外也可以挂起进程 kill -l 查看系统支持的信号

Jitter Injection详解

一、定义与作用 Jitter Injection,即抖动注入,是一种在通信系统中人为地添加抖动的技术。该技术通过在发送端对数据包进行延迟和抖动调整,以实现对整个通信系统的时延和抖动的控制。其主要作用包括: 改善传输质量:通过调整数据包的时延和抖动,可以有效地降低误码率,提高数据传输的可靠性。均衡网络负载:通过对不同的数据流进行不同程度的抖动注入,可以实现网络资源的合理分配,提高整体传输效率。增

Eclipse+ADT与Android Studio开发的区别

下文的EA指Eclipse+ADT,AS就是指Android Studio。 就编写界面布局来说AS可以边开发边预览(所见即所得,以及多个屏幕预览),这个优势比较大。AS运行时占的内存比EA的要小。AS创建项目时要创建gradle项目框架,so,创建项目时AS比较慢。android studio基于gradle构建项目,你无法同时集中管理和维护多个项目的源码,而eclipse ADT可以同时打开

android 免费短信验证功能

没有太复杂的使用的话,功能实现比较简单粗暴。 在www.mob.com网站中可以申请使用免费短信验证功能。 步骤: 1.注册登录。 2.选择“短信验证码SDK” 3.下载对应的sdk包,我这是选studio的。 4.从头像那进入后台并创建短信验证应用,获取到key跟secret 5.根据技术文档操作(initSDK方法写在setContentView上面) 6.关键:在有用到的Mo

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

Android我的二维码扫描功能发展史(完整)

最近在研究下二维码扫描功能,跟据从网上查阅的资料到自己勉强已实现扫描功能来一一介绍我的二维码扫描功能实现的发展历程: 首页通过网络搜索发现做android二维码扫描功能看去都是基于google的ZXing项目开发。 2、搜索怎么使用ZXing实现自己的二维码扫描:从网上下载ZXing-2.2.zip以及core-2.2-source.jar文件,分别解压两个文件。然后把.jar解压出来的整个c

android 带与不带logo的二维码生成

该代码基于ZXing项目,这个网上能下载得到。 定义的控件以及属性: public static final int SCAN_CODE = 1;private ImageView iv;private EditText et;private Button qr_btn,add_logo;private Bitmap logo,bitmap,bmp; //logo图标private st

Android多线程下载见解

通过for循环开启N个线程,这是多线程,但每次循环都new一个线程肯定很耗内存的。那可以改用线程池来。 就以我个人对多线程下载的理解是开启一个线程后: 1.通过HttpUrlConnection对象获取要下载文件的总长度 2.通过RandomAccessFile流对象在本地创建一个跟远程文件长度一样大小的空文件。 3.通过文件总长度/线程个数=得到每个线程大概要下载的量(线程块大小)。