View 与 ViewGroup
Android中的所有可视化组件都是从View派生出来的,这些可视化组件通常被称为控件或者小组件,ViewGroup类是对View类的扩展,它用来包含多个视图,ViewGroup主要用于管理子视图布局和创建可重用的复合组件。
布局
LinearLayout
按照垂直方向或者水平方向对齐每个视图
RelativeLayout
相对于指定控件位置的设定项
FrameLayout
所有添加到这个布局中的视图都以类似堆栈的方式显示。第一个添加的控件被放在最底层,最后一个添加到框架布局中的视图显示在最顶层,上一层的控件会覆盖下一层的控件。布局中所有的控件都会默认出现在视图的左上角
如下所示:
AbsoluteLayout
只有两个属性,不大常用
android:layout_x android:layout_y
|
TableLayout
TableLayout布局由许多的TableRow组成,列是由行中的控件数目决定的。
TableLayout布局不会显示行、列 、单元格的边框线。下面是TableLayout的几个重要属性:
android:stretchColumns=“0,2“ //结果如下所示,第一列和第三列的控件将会尽量扩充
未指定android:shrinkColumns属性的时候(将按键3挤出了界面)
指定android:shrinkColumns=“1”属性的时候(相当于自动换行)
指定android:collapseColumns属性的时候会隐藏指定列
android:layout_column=“2“ //子组件从第2列开始
android:layout_span=“2“ //子组件横跨2列
TabLayout
为了使用Tab,必须使用TabHost和TabWidget,TabHost必须是布局文件中的根节点,它包含了tabWidget显示tabs,以及FrameLayout来显示tab的内容。
主布局
<TabHost xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id ="@android:id/tabhost" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TabWidget android:id ="@android:id/tabs" android:layout_width="fill_parent" android:layout_height="wrap_content" > </TabWidget> <FrameLayout android:id ="@android:id/tabcontent" android:layout_width="fill_parent" android:layout_height="fill_parent" > </FrameLayout> </LinearLayout> </TabHost>
|
Activity1布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/android1" /> </LinearLayout>
|
Activity2布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/android2" /> </LinearLayout>
|
Activity3布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" > <ImageView android:layout_width="match_parent" android:layout_height="match_parent" android:src="@drawable/android3" /> </LinearLayout>
|
public class MainActivity extends TabActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); TabHost tabhost = this.getTabHost(); Intent intent = new Intent(); intent.setClass(this,activity1.class); tabhost.addTab(tabhost.newTabSpec("Tab1").setIndicator("tab1",getResources().getDrawable(R.drawable.android1)).setContent(intent)); intent = new Intent(); intent.setClass(this,activity2.class); tabhost.addTab(tabhost.newTabSpec("Tab2").setIndicator("tab2",getResources().getDrawable(R.drawable.android2)).setContent(intent)); intent = new Intent(); intent.setClass(this,activity3.class); tabhost.addTab(tabhost.newTabSpec("Tab3").setIndicator("tab3",getResources().getDrawable(R.drawable.android3)).setContent(intent)); tabhost.setCurrentTab(1); } }
|
GridLayout
GridLayout是Android 4.0 SDK中新引进的布局:
GridLayout布局使用虚细线将布局划分为行、列和单元格。
- 它与LinearLayout布局一样,也分为水平和垂直两种方式,默认是水平布局,一个控件挨着一个控件从左到右依次排列,通过指定android:columnCount设置列数的属性后,控件会自动换行进行排列。
- 若要指定某控件显示在固定的行或列,只需设置该子控件的android:layout_row和android:layout_column属性即可.
- 如果需要设置某控件跨越多行或多列,只需将该子控件的android:layout_rowSpan或者layout_columnSpan属性设置为数值,再设置其layout_gravity属性为fill即可,前一个设置表明该控件跨越的行数或列数,后一个设置表明该控件填满所跨越的整行或整列。
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:columnCount="4"> <TextView android:gravity="center" android:layout_width="wrap_content" android:layout_height="90dp" android:layout_columnSpan="4" android:layout_gravity="fill" android:hint="请用键盘输入运算" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="C" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="/" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="*" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="DEL" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="7" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="8" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="9" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="-" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="4" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="5" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="6" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="+" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="1" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="2" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="3" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_rowSpan="2" android:layout_gravity="fill_vertical" android:text="=" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="0" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="." /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="+/-" /> </GridLayout>
|
布局的优化
使用merge标签:
当包含有merge标签的布局被添加到另一个布局的时候,该布局的merge节点会被删除,而该布局的子View将会被直接添加到新的父布局。
使用include标签:
Include 标签是用来把一个布局的内容插入到另一个布局中。通过标签可以将一个非常庞大的布局文件分解成若干个较小的布局文件,而且这些小的布局文件也可以被多次引用,从而达到一个重用的目的。
<include android:id=“@+id/my_actionbar” layout=“@layout/actionbar”/>
|
结合使用merge和include标签能够创建灵活的,可复用的布局定义,而不会创建深度嵌套的布局结构.
View Stub
使用提高了复用性,但是带来了另一个问题,就是布局文件中的控件并不一定在程序启动时全都用到,有一些控件只在特定的情况下才会被使用到。填充每个额外的View都需要耗费时间和资源,View的数量越多消耗的时间和资源就越可观,要想在复杂的布局内填充的View的数量最少,可以使用View Stub。
ViewStub是一个不可见的,轻量级的View。它没有尺寸,也不会绘制以及以某种形式参与到布局中来。只有显式地调用inflate方法或者setVisibility(View.VISIBLE)的时候,这个View Stub才会填充。下面是View Stub的一个例子,按下”点击显示Stab View”按键后”按键1”,“按键2”会显示出来,局部代码见备注:
ViewStub的布局参数会随着加载的视图一同被添加到ViewStub父容器。我们也可以通过使用inflatedId属性来定义或重命名要加载的视图对象的Id值。
public class MainActivity extends Activity implements OnClickListener {
private Button btn = null; private ViewStub viewStub = null;
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn = (Button) findViewById(R.id.btn); btn.setOnClickListener(this); viewStub = (ViewStub) findViewById(R.id.viewStub); } public void onClick(View v) { if (viewStub != null) { View anotherlayoutView = viewStub.inflate(); anotherlayoutView.findViewById(R.id.btn1).setOnClickListener( new OnClickListener() { public void onClick(View v) { Log.i("MainActivity", "按键1按下:" + v.getId());
} }); anotherlayoutView.findViewById(R.id.btn2).setOnClickListener( new OnClickListener() { public void onClick(View v) { Log.i("MainActivity", "按键2按下:" + v.getId());
} }); viewStub = (ViewStub) findViewById(R.id.viewStub); View view = findViewById(R.id.inflateViewStub); Log.i("MainActivity", "" + view.toString()); } } }
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.testviewstub.MainActivity" >
<Button android:id="@+id/btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="点击显示Stab View" />
<ViewStub android:id="@+id/viewStub" android:layout_width="fill_parent" android:layout_height="wrap_content" android:inflatedId="@+id/inflateViewStub" android:layout="@layout/anotherlayout" /> </LinearLayout>
|
在上面的例子中通过”viewStub” 可以找到被定义的ViewStub对象。加载布局资源文件”anotherlayout”后, ViewStub对象从其父容器中移除。可以通过id”inflateViewStub”找到由布局资源”anotherlayout”创建的View。这个视图对象最后被指定为宽120dip,高40dip:
LayoutInflater
LayoutInflater的作用:
LayoutInflater作用是将layout的xml布局文件实例化为View类对象。
在一个Activity里如果直接用findViewById()的话,对应的是setConentView()的那个layout里的组件.如果当前Activity里如果用到别的layout,比如对话框上的layout,你还要设置对话框上的layout里的组件(像图片ImageView,文字TextView)上的内容,就必须用inflate()先将对话框上的layout找出来,然后再用这个layout对象去找到它上面的组件,如:
Viewview = View.inflate(this,R.layout.dialog_layout,null); TextViewdialogTV = (TextView)view.findViewById(R.id.dialog_tv); dialogTV.setText(“你好");
|
获取LayoutInflater的三种方法:
LayoutInflater inflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View layout = inflater.inflate(R.layout.main, null);
|
LayoutInflater inflater = LayoutInflater.from(context); View layout = inflater.inflate(R.layout.main, null);
|
LayoutInflater inflater = getLayoutInflater(); View layout = inflater.inflate(R.layout.main, null);
|
Inflate 方法介绍
public View inflate(int Resourece,ViewGroup root)
|
作用:从指定的XML资源文件中填充一个新的视图层次结构
Resourece:View的layout的ID
root: 生成的层次结构的根视图return 填充的层次结构的根视图。如果参数root提供了,那么root就是根视图;否则填充的XML文件的根就是根视图。
inflate只会把Layout形成一个以view类实现成的对象,有需要时再用setContentView(view)显示出来