Error: inflate() returned −3 GUNZIP ERROR − must RESET board to recover Answer: Your kernel p_w_picpath
,但许多人不但不清楚LayoutInflater的inflate()方法的细节,而且甚至在误用它。 LayoutInflater的两个参数的inflate()方法自动将attachToRoot设置为true。 为什么inflate()方法必须要传入根ViewGroup? 下面是一种没有ViewGroup作为root传入inflate()方法的情况。 根据构造方法,创建对应的View对象 LayoutInflater.inflate流程 public View inflate(@LayoutRes int resource, @Nullable ViewGroup
我们在根据layout文件得到View的时候都会使用LayoutInflater.from(mContext).inflate().下面我们来分析这个获取View流程。 我们知道inflate有如下函数: inflate(@LayoutRes int resource, @Nullable ViewGroup root); inflate(@LayoutRes int root, boolean attachToRoot); 其实点进去查看可以知道,其实都到了这个方法: inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean attachToRoot); 源码如下: /** * Inflate a new view hierarchy from the specified XML node LayoutInflater.inflate()源码流程分析就到这里了。因为在这里读的是流程,所有很多细节的东西还是希望大家自己去源码中看看。
getCount :决定listview的显示行数 6、设置适配器 listview优化: 1、用完全消失的布局对象去替代即将出现的那个布局对象 复用行布局对象 convertView View inflate = layoutInflater.inflate(R.layout.ssa, null); }else{ //用完全消失的布局对象去替代即将出现的那个布局对象 = (TextView) inflate.findViewById(R.id.textView1); holder.textView2 = (TextView) inflate.findViewById (R.id.textView2); //把holder放到inflate包里面去 inflate.setTag(holder); } //从inflate对象的包里面得到holder holder = (ViewHolder) inflate.getTag(); } ---- 注·:文章来自51CTO
虽然把View的初始可见View.GONE但是在Inflate布局的时候View仍然会被Inflate,也就是说仍然会创建对象,会被实例化,会被设置属性。也就是说,会耗费内存等资源。 可以为ViewStub指定一个布局,在Inflate布局的时候,只有 ViewStub会被初始化,然后当ViewStub被设置为可见的时候,或是调用了ViewStub.inflate()的时候,ViewStub ViewStub只能Inflate一次,之后ViewStub对象会被置为空。按句话说,某个被ViewStub指定的布局被Inflate后,就不会够再通过ViewStub来控制它了。 而ViewStub的属性在inflate()后会都传给相应的布 局。 操作只能进行一次,因为inflate的 时候是将其指向的布局文件解析inflate并替换掉当前ViewStub本身(由此体现出了ViewStub“占位符”性质),一旦替换后,此时原来的 布局文件中就没有
虽然把View的初始可见View.GONE但是在Inflate布局的时候View仍然会被Inflate,也就是说仍然会创建对象,会被实例化,会被设置属性。 可以为ViewStub指定一个布局,在Inflate布局的时候,只有ViewStub会被初始化,然后当ViewStub被设置为可见的时候, 或是调用了ViewStub.inflate()的时候,ViewStub 所向的布局就会被Inflate和实例化,然后ViewStub的布局属性都会传给它所指向的布局。 2.ViewStub只能用来Inflate一个布局文件,而不是某个具体的View,当然也可以把View写在某个布局文件中。 因为ViewStub只能Inflate一次,之后会被置空,所以无法指望后面接着使用ViewStub来控制布局。
这时就可以用inflater.inflate(R.layout.fragment_view, container, false)来加载视图。 inflate(...) 在得到了LayoutInflater的对象之后,我们就要使用它的inflate()方法了。 inflate()方法截图 可以看到inflate()有四个重载的方法。 我们先来看看前三个的源码: public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) { return inflate = null); } public View inflate(XmlPullParser parser, @Nullable ViewGroup root) { return inflate( 原来第四个inflate()方法才是“幕后黑手”。
/** 341 * Inflate a new view hierarchy from the specified xml resource. (int resource, ViewGroup root) { 352 return inflate(resource, root, root ! inflate(layout, null, false)同上一样,当父层为空,第三个值是否为真没有意义 inflate(layout, parent)子布局会被加入到父层并设置布局参数,具体大小由父层和子 View决定 inflate(layout, parent, false)同上一样,区别就是false返回的是子View本身。 inflate(layout, parent, true)同第三个方法一样,返回父层View
---- 目录 继承自 Activity 的 setContentView LayoutInflater.inflate 的源码分析 LayoutInflater.inflate 示例验证 继承自 AppCompatActivity 我们来看看 mLayoutInflater.inflate() 里面是怎么做的。 public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) { return inflate(resource, inflate(layoutId, null, true) 与 inflate(layoutId, null, false) 不能正确处理我们设置的宽和高是因为 layout_width,layout_height ---- LayoutInflater.inflate 示例验证 合并下 inflate 的测试方法,主要就是以下四个: inflate(layoutId, parent, false) inflate
*当ViewStub设置用户可见(setVisibility)时,或者当调用inflate()方法时,布局会就被初始化。 ViewStub会用初始化后的布局文件替换自己放入其父布局中(参考inflate中的replaceSelfWithView方法)。 * * 因此ViewStub会在view布局中存在一直到setVisibility或inflate被调用了。 (); * * * 当inflate()方法被调用后,ViewStub会被替换为初始化后的布局View,并且View会被返回。 when this StubbedView becomes visible or invisible * or when {@link #inflate()} is invoked.
To use, construct an instance of AsyncLayoutInflater on the UI thread and call inflate(int, ViewGroup This allows the UI thread to continue to be responsive & animate while the relatively heavy inflate is 这是从 AsyncLayoutInflater 说明文档截出来的一段话,大意是:AsyncLayoutInflater 是来帮助做异步加载 layout 的,inflate(int, ViewGroup 3、inflate @UiThread public void inflate(@LayoutRes int resid, @Nullable ViewGroup parent, 因为后续异步 inflate 需要一堆的参数(对应 InflateRequest 中的变量),会导致方法签名过长,而使用 InflateRequest 就避免了很多个参数的传递。
1.viewstub就是动态加载试图;也就是在我们的app启动绘制页面的时候,他不会绘制到view树中;当在代码中执行inflate操作后,她才会被添加到试图中。 } public void inflate(View view){ if (inflate == null) {//inflate只会进行一次,当第二次调用的时候,就会抛异常 ;也可以try catch进行处理 inflate = viewStub.inflate(); constraintLayout = findViewById 进入viewStub.inflate();的源码: public View inflate() { final ViewParent viewParent = getParent(); 我们用layout inspector来查看一下: inflate前:可以看到viewstub是灰色的 inflate后:可以看到viewstub直接被移除了,把引用布局直接放到view树里了。
ViewStub视图在首次调用setVisibility或者inflate方法之前,一直存在于视图树中 5. 只需要调用ViewStub的setVisibility或者inflate方法即可显示懒加载的视图 6. 也就是说,在调用inflate方法之前,ViewStub一直存在于视图树中,当调用inflate之后,ViewStub被加载的视图替换,到此,ViewStub的作用完成,之后ViewStub可能被内存回收 = null) { // 如果对待加载视图的软引用不为空,说明已经执行过inflate方法了 // 因为在inflate方法执行成功后有对其赋值 View inflate方法只能调用一次,不建议通过setVisibility加载视图 如果需要通过findViewById查找待加载视图中的节点,需要在inflate方法执行之后,否则会找不到 关于UI布局的优化
的方法 LayoutInflater源码分析 与setContentView相关 在PhoneWindow的generateLayout中调用了 View in = mLayoutInflater.inflate 方法相关 public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) { return inflate( = null); } public View inflate(XmlPullParser parser, @Nullable ViewGroup root) { return inflate = null); } public View inflate(@LayoutRes int resource, @Nullable ViewGroup root, boolean attachToRoot root, attachToRoot); } finally { parser.close(); } } 最后发现都需要调用 public View inflate
但是它的缺点就是,耗费资源,虽然把View的初始可见View.GONE但是在Inflate布局的时候View仍然会被Inflate,也就是说仍然会创建对象,会被实例化,会被设置属性。 使用时可以为ViewStub指定一个布局,在Inflate布局的时候,只有ViewStub会被初始化,然后当ViewStub被设置为可见的时或调用了ViewStub.inflate()的时候,ViewStub 下面我们从ViewStub源码来看下inflate()方法的实现原理: public View inflate() { final ViewParent viewParent = getParent 4、然后第23~28行,就是得到ViewStub的LayoutParams布局参数对象,如果存在就把它赋给被inflate的布局对象,然后把inflate的布局对象添加到父视图中。 5、最后返回inflate的布局对象。 好了,源码解析完毕!!!
虽然把View的初始可见View.GONE但是在Inflate布局的时候View仍然会被Inflate,也就是说仍然会创建对象,会被实例化,会被设置属性。也就是说,会耗费内存等资源。 可以为ViewStub指定一个布局,在Inflate布局的时候,只有ViewStub会被初始化,然后当ViewStub被设置为可见的时候,或是调用了ViewStub.inflate()的时候,ViewStub 所向的布局就会被Inflate和实例化,然后ViewStub的布局属性都会传给它所指向的布局。 ViewStub只能Inflate一次,之后ViewStub对象会被置为空。 而ViewStub的属性在inflate()后会都传给相应的布局。
Fragment is attached to the FragmentManager出现这个异常来自于在Fragment中动态添加一个布局,切换的时候崩溃写法如下:getLayoutInflater().inflate 解决办法:换一种写法View view = inflater.inflate(R.layout.fragment_dialog_enum, null);Button button = (Button) LayoutInflater.from(view.getContext()).inflate(R.layout.fragment_bottom_button, null);所以,在Activity中可以直接用 getLayoutInflater().inflate的方式,在Fragment中要用LayoutInflater.from(getActivity()).inflate。 源码: /** * Returns the cached LayoutInflater used to inflate Views of this Fragment.
mInflater.inflate(R.layout.textview_layout, parent, false), // mInflater.inflate(R.layout.textview_layout inflate(int resource, ViewGroup root) { return inflate(resource, root, root ! 接着看第10行inflate(parser, root, attachToRoot);,你会发现无论哪个inflate重载方法最后都调运了inflate(XmlPullParser parser, ViewGroup 3-4 LayoutInflater源码inflate(…)方法中调运的一些非public方法剖析 看下inflate方法中被调运的rInflate方法,源码如下: void rInflate( 但是使用merge标签还是有一些限制的,具体是:merge只能用在布局XML文件的根元素;使用merge来inflate一个布局时,必须指定一个ViewGroup作为其父元素,并且要设置inflate的
拿到 LayoutInflater 实例后,我们就可以调用它的 inflate 系列方法了,这几个方法是本篇文章的一个重点,如下: ? ,且第三个参数为 true,我们看下它两个参数的源码: public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) { return inflate(resource, root, root ! 把这个问题 2 也先记着 我们在修改一下 MainActivity 中的代码,如下: val itemMain = layoutInflater.inflate(R.layout.item_main, 嗯,现在达到了我们预期的效果 现在回到上面那两个问题,分析发现是 LayoutInflater inflate 方法传了不同的参数导致的,那这些参数到底有什么玄乎的地方呢?
下面我贴出来这两个方法的代码: public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) public View inflate ).inflate(R.layout.screen_simple, mParentView, true); // 第五种情况 LayoutInflater.from(mContext).inflate( 1.LayoutInflater.inflate public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) { return inflate(resource, root, root ! 2.LayoutInflater.inflate public View inflate(XmlPullParser parser, @Nullable ViewGroup root, boolean