布局及视图(四)

7、绝对布局(AbsoluteLayout)

绝对布局:是一个ViewGroup以绝对方式显示它的子视图(view)元素,即以坐标的方式来定位在屏幕上位置。

这种布局方式很好理解,在布局文件或编程地设置View的坐标,从而绝对地定位。如下所示布局文件:

<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android" 

   android:id="@+id/AbsoluteLayout01" 

   android:layout_width="fill_parent" 

   android:layout_height="fill_parent" 

   >

   <TextView android:id="@+id/txtIntro"

     android:text="绝对布局"

     android:layout_width="fill_parent"

     android:layout_height="wrap_content"

     android:layout_x="20dip"<!-- have an eye on ! -->

     android:layout_y="20dip"><!-- have an eye on ! -->

   </TextView>

</AbsoluteLayout>

 

简单吧,这里不在深入了!

8、标签布局(Tab Layout)

标签布局:是一个ViewGroup以标签的方式显示它的子视图(view)元素,就像在Firefox中的一个窗口中显示多个网页一样。

为了狂创建一个标签UI(tabbed UI),需要使用到TabHostTabWidgetTabHost必须是布局的根节点,它包含为了显示标签的TabWidget和显示标签内容的FrameLayout

可以有两种方式实现标签内容:使用标签在同一个活动中交换视图、使用标签在完全隔离的活动之间改变。根据你的需要,选择不同的方式,但是如果每个标签提供不同的用户活动,为每个标签选择隔离的活动,因此你可以更好地以分离的组管理应用程序,而不是一个巨大的应用程序和布局。下面还有一个例子来创建一个标签UI,每个标签使用隔离的活动。

1)、在项目中建立三个隔离的Activity类:ArtistisActivity、AlbumActivity、SongActivity。它们每个表示一个分隔的标签。每个通过TextView显示简单的一个消息,例如:

public class ArtistsActivity extends Activity {

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);



        TextView textview = new TextView(this);

        textview.setText("This is the Artists tab");

        setContentView(textview);

    }

}

 

其它两个类也类似。

2)、设置每个标签的图标,每个图标应该有两个版本:一个是选中时的,一个是未选中时的。通常的设计建议是,选中的图标应该是深色(灰色),未选中的图标是浅色(白色)。

现在创建一个state-list drawable指定哪个图标表示标签的状态:将图片放到res/drawable目录下并创建一个新的XML文件命名为ic_tab_artists.xml,内容如下:

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- When selected, use grey -->

    <item android:drawable="@drawable/ic_tab_artists_grey"

          android:state_selected="true" />

    <!-- When not selected, use white-->

    <item android:drawable="@drawable/ic_tab_artists_white" />

</selector>

 

3)、res/layour/main.xml的内容置为如下:

<?xml version="1.0" encoding="utf-8"?>

<TabHost xmlns:android="http://schemas.android.com/apk/res/android"

    android:id="@android:id/tabhost"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent">

    <LinearLayout

        android:orientation="vertical"

        android:layout_width="fill_parent"

        android:layout_height="fill_parent"

        android:padding="5dp">

        <TabWidget

            android:id="@android:id/tabs"

            android:layout_width="fill_parent"

            android:layout_height="wrap_content" />

        <FrameLayout

            android:id="@android:id/tabcontent"

            android:layout_width="fill_parent"

            android:layout_height="fill_parent"

            android:padding="5dp" />

    </LinearLayout>

</TabHost>

 

这个布局将显示标签和提供上面创建的活动之间的导航。TabHost要求包含一个TabWidget和一个FrameLayoutTabWidgetFrameLayoutTabHost以线性垂直地显示。

4)、HelloWorld.java文件源码如下:

package skynet.com.cnblogs.www;



import android.widget.TabHost;

import android.app.TabActivity;

import android.content.Intent;

import android.content.res.Resources;

import android.os.Bundle;



public class HelloWorld extends TabActivity{

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);



        Resources res = getResources(); // Resource object to get Drawables

        TabHost tabHost = getTabHost();  // The activity TabHost

        TabHost.TabSpec spec;  // Resusable TabSpec for each tab

        Intent intent;  // Reusable Intent for each tab



        // Create an Intent to launch an Activity for the tab (to be reused)

        intent = new Intent().setClass(this, ArtistsActivity.class);



        // Initialize a TabSpec for each tab and add it to the TabHost

        spec = tabHost.newTabSpec("artists").setIndicator("Artists",

                          res.getDrawable(R.drawable.ic_tab_artists))

                      .setContent(intent);

        tabHost.addTab(spec);



        // Do the same for the other tabs

        intent = new Intent().setClass(this, AlbumsActivity.class);

        spec = tabHost.newTabSpec("albums").setIndicator("Albums",

                          res.getDrawable(R.drawable.ic_tab_artists))

                      .setContent(intent);

        tabHost.addTab(spec);



        intent = new Intent().setClass(this, SongsActivity.class);

        spec = tabHost.newTabSpec("songs").setIndicator("Songs",

                          res.getDrawable(R.drawable.ic_tab_artists))

                      .setContent(intent);

        tabHost.addTab(spec);



        tabHost.setCurrentTab(2);

    }

}

 

 

 

设置每个标签的文字和图标,并分配每个标签一个活动(这里为了方便三个标签都有相同的图标)。TabHost的引用第一次通过getTabHost()获取。然后,为每个标签,创建TabHost.TabSpec定义标签的属性。newTabSpec(String)方法创建一个新的TabHost.TabSpec以给定的字符串标识标签。调用TabHost.TabSpec, setIndicator(CharSequence, Drawable)为每个标签设置文字和图标,调用setContent(Intent)指定Intent去打开合适的活动。每个TabHost.TabSpec通过调用addTab(TabHost.TabSpec)添加到TabHost。

最后,setCurrentTab(int)设置打开默认显示的标签,通过索引标签的位置。

5)、打开Android的清单文件AndroidManifest.xml,添加NoTitleBar主题到HelloWorld的<activity>标记。这将移除默认应用程序的标题和顶端布局,给标签腾出位置。<activity>标记应该像这样:

        <activity android:name=".HelloWorld"

                  android:label="@string/app_name"

                  android:theme="@android:style/Theme.NoTitleBar">

 

你运行这个程序能够得到什么结果呢?请自行检查。不过我在这里告诉你很有可能会运行不了,报“java.lang.NullPointerException”错!我想运行这个例子的很多人都会有这个问题,不信你试试!

PS:其实这也算是Android的一个bug,而且这个bug在2.2中还没有解决,这个问题全球N多人都碰到了,并在http://code.google.com/p/android/issues中挂号了,相关问题的编号有不止一个。

接着往下看……

如果你看了我这篇文章,你一定会是个幸运儿!经过我艰苦的调试+找资料,我找到了解决方法:

在清单文件AndroidManifest.xml,添加下面三个Activity:

<activity android:name=".AlbumsActivity"  android:label="@string/app_name"></activity>
<activity android:name=".ArtistsActivity" android:label="@string/app_name"></activity>
<activity android:name=".SongsActivity"  android:label="@string/app_name"></activity>

现在运行可以看到如下结果:

tablayout图9、标签布局

你可能感兴趣的:(视图)