Android Manager之LayoutInflater(布局服务)
1.引言
说到布局,大家第一时间 可能想起的是写完一个布局的xml,然后调用Activity的setContentView()加载布局,然后把他显示 到屏幕上。其实这个底层走的还是这个LayoutInflater,用的Android内置的Pull解析器来解析 布局。一般在Android动态加载布局或者添加控件用得较多。
2.LayoutInflater
2.1.LayoutInflater简介
一个用于加载布局的系统服务,就是实例化与Layout XML文件对应的View对象,不能直接使用, 需要通过getLayoutInflater( )方法或getSystemService( )方法来获得与当前Context绑定的 LayoutInflater实例。
2.2.LayoutInflater详解
2.2.1.获取LayoutInflater实例
LayoutInflater inflater1 = LayoutInflater.from(this);
LayoutInflater inflater2 = getLayoutInflater();
LayoutInflater inflater3 = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
后面两个其实底层走的都是第一种方法。
2.2.2.LayoutInflater的inflate方法加载布局xml
public View inflate (int resource, ViewGroup root, boolean attachToRoot)
参数1:要加载的布局对应的资源id。
参数2:为该布局的外部再嵌套一层父布局,如果不需要的话,写null就可以了。
参数3:是否为加载的布局文件的最外层套一层root布局,不设置该参数的话, 如果root不为null的话,则默认为true 如果root为null的话,attachToRoot就没有作用了。root不为null,attachToRoot为true的话,会在加载的布局文件最外层嵌套一层root布局; 为false的话,则root失去作用。 简单理解就是:是否为加载的布局添加一个root的外层容器。
一般用第一个重载的方法即可。
3.LayoutInflater使用Demo
3.1.
<?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="match_parent"
android:id="@+id/activity_layoutinflater_linearlayout"
android:orientation="vertical">
<TextView
android:id="@+id/activity_layoutinflater_textview"
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@color/colorAccent"
android:layout_gravity="center"
android:gravity="center"
android:textColor="#FFFFFF"
android:text="动态引入其他布局"/>
</LinearLayout>
3.2.
public class LayoutInflaterActivity extends Activity {
private LinearLayout linearLayout;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_layoutinflater);
linearLayout= (LinearLayout) findViewById(R.id.activity_layoutinflater_linearlayout);
textView= (TextView) findViewById(R.id.activity_layoutinflater_textview);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//1.获取LayoutInflater对象
LayoutInflater inflater=LayoutInflater.from(LayoutInflaterActivity.this);
//2.加载要动态加入的布局并获取加入的inflaterview
View inflaterview=inflater.inflate(R.layout.inflaterlayout,null);
//3.使用inflaterview获取findViewById动态加入的每个View
TextView textView= (TextView) inflaterview.findViewById(R.id.layoutinflater_textview);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(LayoutInflaterActivity.this,"点击了:我是动态添加的TextView!",Toast.LENGTH_LONG).show();
}
});
ImageView imageView= (ImageView) inflaterview.findViewById(R.id.layoutinflater_imageview);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(LayoutInflaterActivity.this,"点击了:我是动态添加的ImageView!",Toast.LENGTH_LONG).show();
}
});
Button button= (Button) inflaterview.findViewById(R.id.layoutinflater_button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(LayoutInflaterActivity.this,"点击了:我是动态添加的Button!",Toast.LENGTH_LONG).show();
}
});
//将动态加入的inflaterview加入到父布局中
linearLayout.addView(inflaterview);
}
});
}
}
3.3.
<?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="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/layoutinflater_textview"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:background="@color/colorPrimary"
android:gravity="center"
android:text="我是动态引入的TextView"
android:textColor="#FFFFFF" />
<ImageView
android:id="@+id/layoutinflater_imageview"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginTop="20dp"
android:background="@mipmap/ic_launcher"
android:scaleType="centerCrop" />
<Button
android:id="@+id/layoutinflater_button"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginTop="20dp"
android:text="我是动态引入的Button"
android:textColor="#FFFFFF" />
</LinearLayout>
3.4.效果图
4.LayoutParams
4.1.简介
LayoutParams继承于Android.View.ViewGroup.LayoutParams相当于一个Layout的信息包,它封装了Layout的位置、高、宽等信息。假设在屏幕上一块区域是由一个Layout占领的,如果将一个View添加到一个Layout中,最好告诉Layout用户期望的布局方式,也就是将一个认可的layoutParams传递进去。
通俗地讲LayoutParams类是用于child view(子视图)向parent view(父视图)传达自己的意愿的一个东西(孩子想变成什么样向其父亲说明)。举个栗子,子视图和父视图分别可以简单理解成一个LinearLayout 和该LinearLayout里边的一个 TextView 的关系, TextView 就算LinearLayout的子视图 child view。需要注意的是LayoutParams只是ViewGroup的一个内部类这里边这个也就是ViewGroup里边这个LayoutParams类是base class基类实际上每个不同的ViewGroup都有自己的LayoutParams子类。比如AbsListView.LayoutParams, AbsoluteLayout.LayoutParams, Gallery.LayoutParams, ViewGroup.MarginLayoutParams, WindowManager.LayoutParams等。
ViewGroup.LayoutParams类只能简单的设置高height以及宽width两个基本的属性,宽和高都可以设置成三种值:
1,一个确定的值;
2,MATCH_PARENT;
3,WRAP_CONTENT。
ViewGroup.MarginLayoutParams类是ViewGroup.LayoutParams的子类,顾名思义,它只能设置child View的margin属性信息。
1、利用setMargins(left,top,right,bottom);
2、利用MarginLayoutParams对象params方法单独设置.topMargin
常用子类的简单使用:LinearLayout.LayoutParams 和 RelativeLayout.LayoutParams
4.2.LinearLayout.LayoutParams详解以及使用
4.2.1.布局
<?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="match_parent"
android:id="@+id/activity_layoutinflater_linearlayout"
android:orientation="vertical">
<TextView
android:id="@+id/activity_layoutinflater_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:textColor="#FFFFFF" />
</LinearLayout>
4.2.2.代码
textView= (TextView) findViewById(R.id.activity_layoutinflater_textview);
textView.setText("默认—TextView");
4.2.3.结果
4.2.4.LinearLayout.LayoutParams 设置 代码
LinearLayout.LayoutParams layoutParams=new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);
layoutParams.leftMargin=30;
layoutParams.rightMargin=30;
layoutParams.topMargin=30;
layoutParams.bottomMargin=30;
layoutParams.gravity= Gravity.CENTER_HORIZONTAL;
textView.setLayoutParams(layoutParams);
textView.setPadding(20,20,20,20);
textView.setTextSize(14);
textView.setText("设置—TextView");
4.2.5.结果
4.3.RelativeLayout.LayoutParams详解及使用
4.3.1.布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/activity_layoutinflater_linearlayout">
<TextView
android:id="@+id/activity_layoutinflater_textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorAccent"
android:textColor="#FFFFFF" />
</RelativeLayout>
4.3.2.代码
textView= (TextView) findViewById(R.id.activity_layoutinflater_textview);
textView.setText("默认—TextView");
4.3.3.结果
4.3.4.RelativeLayout.LayoutParams 设置 代码
RelativeLayout.LayoutParams layoutParams=new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
layoutParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
layoutParams.leftMargin = 20;
layoutParams.rightMargin=20;
layoutParams.topMargin=20;
layoutParams.bottomMargin=20;
textView.setLayoutParams(layoutParams);
textView.setTextSize(14);
textView.setPadding(20,20,20,20);
textView.setText("设置—TextView");
4.3.5.结果
附1:
LayoutInflater官方文档:http://androiddoc.qiniudn.com/reference/android/view/LayoutInflater.html
附2:inflate()方法源码
附1: