View.inflate()和LayoutInflater.inflate()的区别
2018-03-01 11:42
253 查看
标签:【Android】UI
我要用Viewpager实现画廊效果,也就是一个屏幕显示多页
我将Viewpager所在的布局都加上了 android:clipChildren=”false”属性
给page的布局,我直接在根布局使用Imageview,无父布局约束
我使用View.inflate()加载布局
效果
思考:
之所以出现这种效果,是因为加载page布局时,没有相关父布局的LayoutParams控制它,当它加载到Viewpager中后,又因为Viewpager的android:clipChildren=”false”,所以,page的内容显示到了viewpager外
解决:
View.inflate(this,R.layout.item_banner,vp);
第三个参数设置成了vp,是希望能够约束page布局(后来想想也没用,vp已经设置了clipChildren)
结果:
我没有百度到,为什么这样会造成OOM,希望了解的能够给我留言,谢谢!
有效的两种解决办法:
1. 给page的布局外层套一个父布局
2. 对图片进行裁切处理,或直接用glide
效果:
具体实现在另一篇文章Viewpager
这个方法可以在Activity和Fragment中使用,不过在Fragment中使用时,要传入一个bundle参数
getSystemService();
这个为Context的方法,只要有上下文就能调用
LayoutInflater.from();
这个是LayoutInflater的静态方法,传入上下文即可
1. [b]inflate(int resource,ViewGroup root,boolean attachToRoot)[/b]
resource:布局资源
root:生成View对象的父控件。为null,则返回的view就是布局资源的根布局;否则,需要参照第三个参数
attachToRoot:是否将布局资源加载到root上,以root作为最终返回view的根布局。 false,root不为null,则提供root的LayoutParams约束resource生成的view;true,root不为null,以root作为最终返回view的根布局
2. [b]inflate(int resource,ViewGroup root)[/b]
resource:布局资源
root:生成View对象的父控件。为null,则返回的view就是布局资源的根布局;否则,返回的view以传入的root为根布局
该方法,实际还是调用了上一个方法
参数含义:
context:上下文
resource:布局资源
root:生成View对象的父控件。为null,则以布局资源的根布局为返回view的根布局,否则将view加载到root中,以root作为根布局返回
一、背景
昨天在写一个关于Viewpager的Demo时,碰到了一个OOM的问题,场景是这样的:我要用Viewpager实现画廊效果,也就是一个屏幕显示多页
我将Viewpager所在的布局都加上了 android:clipChildren=”false”属性
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:clipChildren="false" tools:context="com.strivestay.viewpagerdemo.FourthActivity"> <include layout="@layout/layout_toolbar"/> <android.support.v4.view.ViewPager android:id="@+id/vp" android:layout_width="match_parent" android:layout_height="180dp" android:layout_marginTop="100dp" android:layout_marginLeft="30dp" android:layout_marginRight="30dp" android:clipChildren="false"> </android.support.v4.view.ViewPager> </LinearLayout>
给page的布局,我直接在根布局使用Imageview,无父布局约束
<ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/iv_banner" android:layout_width="match_parent" android:layout_height="180dp" android:background="#009999" android:scaleType="centerCrop"/>
我使用View.inflate()加载布局
for (int i = 0; i < 4; i++) { View view = View.inflate(this,R.layout.item_banner,null); ImageView iv = (ImageView) view.findViewById(R.id.iv_banner); int resourceId = getResources().getIdentifier("img" + (i + 1), "drawable", getPackageName()); // Glide.with(this).load(resourceId).into(iv); iv.setImageResource(resourceId); list.add(view); }
效果
思考:
之所以出现这种效果,是因为加载page布局时,没有相关父布局的LayoutParams控制它,当它加载到Viewpager中后,又因为Viewpager的android:clipChildren=”false”,所以,page的内容显示到了viewpager外
解决:
View.inflate(this,R.layout.item_banner,vp);
第三个参数设置成了vp,是希望能够约束page布局(后来想想也没用,vp已经设置了clipChildren)
结果:
java.lang.OutOfMemoryError: Failed to allocate a 33341646 byte allocation with 16777216 free bytes and 18MB until OOM
我没有百度到,为什么这样会造成OOM,希望了解的能够给我留言,谢谢!
有效的两种解决办法:
1. 给page的布局外层套一个父布局
``` <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <ImageView android:id="@+id/iv_banner" android:layout_width="match_parent" android:layout_height="180dp" android:background="#009999" android:scaleType="centerCrop"/> </LinearLayout> ```
2. 对图片进行裁切处理,或直接用glide
Glide.with(this).load(resourceId).into(iv);
效果:
具体实现在另一篇文章Viewpager
二、进入正题
由于上面的问题,我想仔细了解学习下View.inflate()和LayoutInflater.inflate()的区别,学习如下:1. LayoutInflater.inflate()
该方法适用于所有布局填充的的场景,但使用前需要先实例化LayoutInflater对象1. 获取LayoutInflater实例
getLayoutInflater();这个方法可以在Activity和Fragment中使用,不过在Fragment中使用时,要传入一个bundle参数
// Activity中使用 LayoutInflater layoutInflater = getLayoutInflater(); // Fragment中使用 LayoutInflater layoutInflater = getLayoutInflater(savedInstanceState);
getSystemService();
这个为Context的方法,只要有上下文就能调用
LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
LayoutInflater.from();
这个是LayoutInflater的静态方法,传入上下文即可
LayoutInflater inflater = LayoutInflater.from(this);
2. LayoutInflater.inflate()的重载
常用的是下面两种:1. [b]inflate(int resource,ViewGroup root,boolean attachToRoot)[/b]
resource:布局资源
root:生成View对象的父控件。为null,则返回的view就是布局资源的根布局;否则,需要参照第三个参数
attachToRoot:是否将布局资源加载到root上,以root作为最终返回view的根布局。 false,root不为null,则提供root的LayoutParams约束resource生成的view;true,root不为null,以root作为最终返回view的根布局
2. [b]inflate(int resource,ViewGroup root)[/b]
resource:布局资源
root:生成View对象的父控件。为null,则返回的view就是布局资源的根布局;否则,返回的view以传入的root为根布局
该方法,实际还是调用了上一个方法
public View inflate(@LayoutRes int resource, @Nullable ViewGroup root) { return inflate(resource, root, root != null); }
2. View.inflate()
这个是View类的静态方法,可直接调用,实际上还是使用了LayoutInflater,所以,它没有直接使用LayoutInflater.inflate()强大public static View inflate(Context context, @LayoutRes int resource, ViewGroup root) { LayoutInflater factory = LayoutInflater.from(context); return factory.inflate(resource, root); }
参数含义:
context:上下文
resource:布局资源
root:生成View对象的父控件。为null,则以布局资源的根布局为返回view的根布局,否则将view加载到root中,以root作为根布局返回
3. 总结
View.inflate()是封装了LayoutInflater的inflate()方法,由于是静态方法,比较简便;但LayoutInflater相当于比View多了一个三个参数的inflate()方法,功能更强大相关文章推荐
- View.inflate和LayoutInflater的inflate方法区别
- View.inflate和LayoutInflater的inflate方法区别
- [Android]inflate方法与 findViewById 方法区别 | LayoutInflater的inflate函数用法详解
- (转)View.inflate和LayoutInflater的inflate方法区别
- Android中setContentView、addContentView、inflate、LayoutInflater和findViewById()区别
- [Android]inflate方法与 findViewById 方法区别 | LayoutInflater的inflate函数用法详解
- View.inflate() 和 LayoutInflater.from(context).inflate()区别
- View.inflate()与LayoutInflater.inflate()的区别?
- View inflate 方法与 LayoutInflater inflate 方法的区别详解
- [Android]inflate方法与 findViewById 方法区别 | LayoutInflater的inflate函数用法详解
- android程序 在View view = LayoutInflater.from(getContext()).inflate(resourceId, nul
- 源码分析初级《篇一》 为何建议使用LayoutInflater.from而不用View.inflate
- LayoutInflater方法Inflate三种重载的区别
- LayoutInflater.inflate方法加载View
- 关于LayoutInflate和View-infalte的参数意义以及区别总结
- 关于LayoutInflater.from().inflate()方法不能加载自定义view的解决办法
- Android LayoutInflater.inflate(int resource, ViewGroup root, boolean attachToRoot)的参数理解
- LayoutInflater.inflate(int resource, ViewGroup root, boolean attachToRoot)方法解析
- LayoutInflater.inflate()方法的ViewGroup参数问题
- LayoutInflater.inflate()调用后View的构造方法和onFinishInflate()方法执行的顺序