在Android中LayoutInflater的用途是什么?
当前回答
LayoutInflator做什么?
当我第一次开始Android编程时,我真的对LayoutInflater和findViewById感到困惑。有时我们用一种,有时用另一种。
LayoutInflater用于从您的xml布局之一创建一个新的视图(或布局)对象。 findViewById只是给你一个已经创建的视图的引用。你可能认为你还没有创建任何视图,但无论何时你在onCreate中调用setContentView,活动的布局及其子视图在幕后被膨胀(创建)。
如果视图已经存在,那么使用findViewById。如果不是,那么使用LayoutInflater创建它。
例子
这是我做的一个小项目,显示LayoutInflater和findViewById在行动。在没有特殊代码的情况下,布局如下所示。
蓝色的正方形是一个自定义布局插入到主布局包含(见这里更多)。它是自动膨胀的,因为它是内容视图的一部分。如您所见,代码没有什么特别之处。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
现在让我们膨胀(创建)自定义布局的另一个副本并将其添加进来。
LayoutInflater inflater = getLayoutInflater();
View myLayout = inflater.inflate(R.layout.my_layout, mainLayout, false);
为了膨胀新的视图布局,我所做的只是告诉膨胀器我的xml文件的名称(my_layout),我想要添加它的父布局(mainLayout),以及我实际上还不想添加它(false)。(我也可以设置父为空,但然后我的自定义布局的根视图的布局参数将被忽略。)
这里是它的背景。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// inflate the main layout for the activity
setContentView(R.layout.activity_main);
// get a reference to the already created main layout
LinearLayout mainLayout = (LinearLayout) findViewById(R.id.activity_main_layout);
// inflate (create) another copy of our custom layout
LayoutInflater inflater = getLayoutInflater();
View myLayout = inflater.inflate(R.layout.my_layout, mainLayout, false);
// make changes to our custom layout and its subviews
myLayout.setBackgroundColor(ContextCompat.getColor(this, R.color.colorAccent));
TextView textView = (TextView) myLayout.findViewById(R.id.textView);
textView.setText("New Layout");
// add our custom layout to the main layout
mainLayout.addView(myLayout);
}
}
注意findViewById是如何仅在布局已经膨胀之后使用的。
附加的代码
下面是上面示例的xml。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main_layout"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<!-- Here is the inserted layout -->
<include layout="@layout/my_layout"/>
</LinearLayout>
my_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@color/colorPrimary">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:padding="5dp"
android:textColor="@android:color/white"
android:text="My Layout"/>
</RelativeLayout>
你什么时候需要LayoutInflater
大多数人最常使用它的时候是在RecyclerView中。(关于列表或网格,请参阅这些RecyclerView示例。)您必须为列表或网格中的每一个可见项目扩展一个新的布局。 如果您想以编程方式添加一个复杂的布局(就像我们在示例中所做的那样),您也可以使用布局膨胀器。您可以在代码中完成这一切,但是先用xml定义它,然后再对它进行膨胀要容易得多。
其他回答
LayoutInflater是Android的一个基本组件。您必须一直使用它来将xml文件转换为视图层次结构。
下面是另一个与前一个类似的示例,但扩展了它以进一步演示它可以提供的膨胀参数和动态行为。
假设你的ListView行布局可以有可变数量的textview。因此,首先膨胀基本项视图(就像前面的例子一样),然后在运行时动态循环添加textview。使用android:layout_weight额外对齐一切完美。
以下是布局资源:
list_layout.xml
<?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="horizontal" >
<TextView
android:id="@+id/field1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"/>
<TextView
android:id="@+id/field2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
/>
</LinearLayout>
schedule_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
重写BaseAdapter类扩展中的getView方法
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = activity.getLayoutInflater();
View lst_item_view = inflater.inflate(R.layout.list_layout, null);
TextView t1 = (TextView) lst_item_view.findViewById(R.id.field1);
TextView t2 = (TextView) lst_item_view.findViewById(R.id.field2);
t1.setText("some value");
t2.setText("another value");
// dinamically add TextViews for each item in ArrayList list_schedule
for(int i = 0; i < list_schedule.size(); i++){
View schedule_view = inflater.inflate(R.layout.schedule_layout, (ViewGroup) lst_item_view, false);
((TextView)schedule_view).setText(list_schedule.get(i));
((ViewGroup) lst_item_view).addView(schedule_view);
}
return lst_item_view;
}
注意不同的膨胀方法调用:
inflater.inflate(R.layout.list_layout, null); // no parent
inflater.inflate(R.layout.schedule_layout, (ViewGroup) lst_item_view, false); // with parent preserving LayoutParams
Layout inflater是一个读取xml外观描述并将其转换为基于java的View对象的类。
LayoutInflater是一个用于实例化布局XML文件到其相应的视图对象的类,可以在Java程序中使用。 简单来说,在android中有两种方法来创建UI。一种是静态的,另一种是动态的或程序化的。 假设我们有一个简单的布局main.xml,它有一个textview和一个edittext,如下所示。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/layout1"
>
<TextView
android:id="@+id/namelabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Enter your name"
android:textAppearance="?android:attr/textAppearanceLarge" >
</TextView>
<EditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginTop="14dp"
android:ems="10">
</EditText>
</LinearLayout>
我们可以用静态的方式显示这个布局
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
创建视图的动态方式意味着在main.xml中没有提到视图,但我们希望在运行时显示视图。例如,我们在布局文件夹中有另一个XML文件footer.xml
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/TextView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="Add your record"
android:textSize="24sp" >
</TextView>
我们希望在主UI的运行时显示此文本框。这里我们将膨胀text。xml。看看:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
TextView t = (TextView)inflater.inflate(R.layout.footer,null);
lLayout = (LinearLayout)findViewById(R.id.layout1);
lLayout.addView(t);
这里我使用了getSystemService (String)来检索一个LayoutInflater实例。我可以使用getLayoutInflator()太膨胀,而不是使用getSystemService(字符串)如下所示:
LayoutInflator inflater = getLayoutInflater();
TextView t = (TextView) inflater.inflate(R.layout.footer, null);
lLayout.addView(t);
LayoutInflater类用于将布局XML文件的内容实例化到相应的View对象中。
换句话说,它接受一个XML文件作为输入,并从中构建View对象。
推荐文章
- 在XML中“图像上缺少contentDescription属性”
- 在Android SQLite中处理日期的最佳方法
- 读取Android APK的包名
- Android-Facebook应用程序的键散列
- 登出时,清除活动历史堆栈,防止“返回”按钮打开已登录的活动
- 如何改变标题的活动在安卓?
- 如何隐藏动作栏之前的活动被创建,然后再显示它?
- 是否有一种方法以编程方式滚动滚动视图到特定的编辑文本?
- 在Android中将字符串转换为Uri
- 如何在NestedScrollView内使用RecyclerView ?
- 移动到另一个EditText时,软键盘下一步点击Android
- Android应用中的GridView VS GridLayout
- Activity和FragmentActivity的区别
- 右对齐文本在android TextView
- 权限拒绝:start前台需要android.permission.FOREGROUND_SERVICE