这几天看了一些优化布局的材料,感觉,使用 include merge ViewStub会很好的增强代码的可读性,和观赏性,很大程度的优化了我们自己的布局,下面我写一些自己学到的东西,大家一起学习!
1.首先是include,
在官网上,
The <include />
does exactly what its name suggests; it includes another XML layout. Using this tag is straightforward as shown in the following example, taken straight from the source code of the Home application that currently ships with Android:
<com.android.launcher.Workspace android:id="@+id/workspace" android:layout_width="fill_parent" android:layout_height="fill_parent" launcher:defaultScreen="1"> <include android:id="@+id/cell1" layout="@layout/workspace_screen" /> <include android:id="@+id/cell2" layout="@layout/workspace_screen" /> <include android:id="@+id/cell3" layout="@layout/workspace_screen" /> </com.android.launcher.Workspace>
恩
include里面包含一些其他的布局文件xml,这只需要以上面的形式写出就可以方便的调用,同时,像例子中的那样可以重复利用一个xml代码,要注意几点:
1.The above example shows that you can use android:id
to specify the id of the root view of the included layout; it will also override the id of the included layout if one is defined.如果在workspace_screen布局里面已经有id,而include里面又重新定义了这个id,则会覆盖原来的id
2.This means that anyandroid:layout_*
attribute can be used with the<include />
tag.可以使用layout_*的任何属性2.merge的用法:<merge/>标签在UI的结构优化中起着非常重要的作用,它可以删减多余的层级,优化UI。merge多用于替换FrameLayout或者当一个布局包含另一个时,merge标签消除视图层次结构中多余的视图组。例如你的主布局文件是垂直布局,引入了一个垂直布局的include,这是如果include布局使用的LinearLayout就没意义了,That's where the
<merge />
tag comes in handy. When the LayoutInflater encounters this tag, it skips it and adds the<merge />
children to the<merge />
parent. Confused? Let's rewrite our previous XML layout by replacing theFrameLayout
with<merge />
:<merge xmlns:android="http://schemas.android.com/apk/res/android"> <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:scaleType="center" android:src="@drawable/golden_gate" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="20dip" android:layout_gravity="center_horizontal|bottom" android:padding="12dip" android:background="#AA000000" android:textColor="#ffffffff" android:text="Golden Gate" /> </merge><merge xmlns:android="http://schemas.android.com/apk/res/android" xmlns:okCancelBar="http://schemas.android.com/apk/res/com.example.android.merge"> <ImageView android:layout_width="fill_parent" android:layout_height="fill_parent" android:scaleType="center" android:src="@drawable/golden_gate" /> <com.example.android.merge.OkCancelBar android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" android:paddingTop="8dip" android:gravity="center_horizontal" android:background="#AA000000" okCancelBar:okLabel="Save" okCancelBar:cancelLabel="Don't save" /> </merge>This new layout produces the following result on a device:
![]()
The source code of
OkCancelBar
is very simple because the two buttons are defined in an external XML file, loaded using aLayoutInflate
. As you can see in the following snippet, the XML layoutR.layout.okcancelbar
is inflated with theOkCancelBar
as the parent:自定义view,
public class OkCancelBar extends LinearLayout { public OkCancelBar(Context context, AttributeSet attrs) { super(context, attrs); setOrientation(HORIZONTAL); setGravity(Gravity.CENTER); setWeightSum(1.0f); LayoutInflater.from(context).inflate(R.layout.okcancelbar, this, true); TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.OkCancelBar, 0, 0); String text = array.getString(R.styleable.OkCancelBar_okLabel); if (text == null) text = "Ok"; ((Button) findViewById(R.id.okcancelbar_ok)).setText(text); text = array.getString(R.styleable.OkCancelBar_cancelLabel); if (text == null) text = "Cancel"; ((Button) findViewById(R.id.okcancelbar_cancel)).setText(text); array.recycle(); } }The two buttons are defined in the following XML layout. As you can see, we use the
<merge />
tag to add the two buttons directly to theOkCancelBar
. Each button is included from the same external XML layout file to make them easier to maintain; we simply override their id:这两个按钮如下所示,在OkCancelBar里面我们添加了两个按钮,对同一个xml我们重新利用include定义了id
<merge xmlns:android="http://schemas.android.com/apk/res/android"> <include layout="@layout/okcancelbar_button" android:id="@+id/okcancelbar_ok" /> <include layout="@layout/okcancelbar_button" android:id="@+id/okcancelbar_cancel" /> </merge>The
<merge />
tag is extremely useful and can do wonders in your code. However, it suffers from a couple of limitation:
<merge />
can only be used as the root tag of an XML layout- When inflating a layout starting with a
<merge />
, you must specify a parentViewGroup
and you must setattachToRoot
totrue
(see the documentation of the inflate() method)
merge标签只能用于xml;当Inflate以merge开头时,必须指定一个父ViewGroup也必须设定attachToRoot为true
3.ViewStub:
To use a
ViewStub
all you need is to specify anandroid:id
attribute, to later inflate the stub, and anandroid:layout
attribute, to reference what layout file to include and inflate. A stub lets you use a third attribute,android:inflatedId
, which can be used to override the id of the root of the included file. Finally, the layout parameters specified on the stub will be applied to the roof of the included layout. Here is an example:<ViewStub android:id="@+id/stub_import" android:inflatedId="@+id/panel_import" android:layout="@layout/progress_overlay" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_gravity="bottom" />When you are ready to inflate the stub, simply invoke the inflate() method. You can also simply change the visibility of the stub to VISIBLE or INVISIBLE and the stub will inflate. Note however that the
inflate()
method has the benefit of returning the rootView
of the inflate layout:当你想加载布局时,,可以在下面选用一种方法:
((ViewStub) findViewById(R.id.stub_import)).setVisibility(View.VISIBLE); // or View importPanel = ((ViewStub) findViewById(R.id.stub_import)).inflate();
上面的很多内容来自对谷歌官网的一些摘抄,加入了个人的理解,希望对大家有帮助-_-