欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android 開發(fā)之旅:詳解view的幾種布局方式及實(shí)踐

 更新時(shí)間:2016年12月06日 15:53:48   作者:吳秦(Tyler)  
這篇文章主要介紹了Android 開發(fā)之旅:詳解view的幾種布局方式及實(shí)踐,具有一定的參考價(jià)值,有需要的可以了解一下。

引言

我們對(duì)Android應(yīng)用程序運(yùn)行原理及布局文件可謂有了比較深刻的認(rèn)識(shí)和理解,并且用“Hello World!”程序來實(shí)踐證明了。在繼續(xù)深入Android開發(fā)之旅之前,有必要解決前兩篇中沒有介紹的遺留問題:View的幾種布局顯示方法,以后就不會(huì)在針對(duì)布局方面做過多的介紹。View的布局顯示方式有下面幾種:線性布局(Linear Layout)、相對(duì)布局(Relative Layout)、表格布局(Table Layout)、網(wǎng)格視圖(Grid View)、標(biāo)簽布局(Tab Layout)、列表視圖(List View)、絕對(duì)布局(AbsoluteLayout)。本文雖然是介紹View的布局方式,但不僅僅是這樣,其中涉及了很多小的知識(shí)點(diǎn),絕對(duì)能給你帶來Android大餐!

本文的主要內(nèi)容就是分別介紹以上視圖的七種布局顯示方式效果及實(shí)現(xiàn),大綱如下:

1、View布局概述

2、線性布局(Linear Layout) 

    2.1、Tips:android:layout_weight="1"

3、相對(duì)布局(Relative Layout)

4、表格布局(Table Layout)

5、列表視圖(List View) 

    5.1、一個(gè)小的改進(jìn)  

    5.2、補(bǔ)充說明

6、網(wǎng)格視圖(Grid View)

7 、絕對(duì)布局()

8、標(biāo)簽布局(Tab Layout)

1、view的布局顯示概述

通過前面的學(xué)習(xí)我們知道:在一個(gè)Android應(yīng)用程序中,用戶界面通過View和ViewGroup對(duì)象構(gòu)建。Android中有很多種View和ViewGroup,他們都繼承自View類。View對(duì)象是Android平臺(tái)上表示用戶界面的基本單元。

View的布局顯示方式直接影響用戶界面,View的布局方式是指一組View元素如何布局,準(zhǔn)確的說是一個(gè)ViewGroup中包含的一些View怎么樣布局。ViewGroup類是布局(layout)和視圖容器(View container)的基類,此類也定義了ViewGroup.LayoutParams類,它作為布局參數(shù)的基類,此類告訴父視圖其中的子視圖想如何顯示。例如,XML布局文件中名為layout_something的屬性(參加上篇的4.2節(jié))。我們要介紹的View的布局方式的類,都是直接或間接繼承自ViewGroup類,如下圖所示:

圖1、繼承自ViewGroup的一些布局類

其實(shí),所有的布局方式都可以歸類為ViewGroup的5個(gè)類別,即ViewGroup的5個(gè)直接子類。其它的一些布局都擴(kuò)展自這5個(gè)類。下面分小節(jié)分別介紹View的七種布局顯示方式。

2、線性布局(Linear Layout)

線性布局:是一個(gè)ViewGroup以線性方向顯示它的子視圖(view)元素,即垂直地或水平地。之前我們的Hello World!程序中view的布局方式就是線性布局的,一定不陌生!如下所示res/layour/main.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       android:layout_width="fill_parent" 
       android:layout_height="fill_parent" 
       android:orientation="horizontal"><!-- have an eye on ! --> 
  <Button android:id="@+id/button1" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content"      
      android:text="Hello, I am a Button1" 
      android:layout_weight="1" 
      /> 
  <Button android:id="@+id/button2" 
  android:layout_width="wrap_content" 
  android:layout_height="wrap_content" 
  android:text="Hello, I am a Button2" 
  android:layout_weight="1" 
  /> 
  <Button android:id="@+id/button3" 
  android:layout_width="wrap_content" 
  android:layout_height="wrap_content" 
  android:text="Hello, I am a Button3" 
  android:layout_weight="1" 
  /> 
  <Button android:id="@+id/button4" 
  android:layout_width="wrap_content" 
  android:layout_height="wrap_content" 
  android:text="Hello, I am a Button4" 
  android:layout_weight="1" 
  /> 
  <Button android:id="@+id/button5" 
  android:layout_width="wrap_content" 
  android:layout_height="wrap_content" 
  android:text="Hello, I am a Button5" 
  android:layout_weight="1" 
  /> 
</LinearLayout> 

從上面可以看出根LinearLayout視圖組(ViewGroup)包含5個(gè)Button,它的子元素是以線性方式(horizontal,水平的)布局,運(yùn)行效果如下圖所示:

圖2、線性布局(水平或者說是橫向)

如果你在android:orientation="horizontal"設(shè)置為vertical,則是是垂直或者說是縱向的,如下圖所示:

 圖3、線性布局(垂直或者說是縱向)

2.1、Tips:android:layout_weight="1"

 這個(gè)屬性很關(guān)鍵,如果你沒有顯示設(shè)置它,它默認(rèn)為0。把上面布局文件(水平顯示的那個(gè))中的這個(gè)屬性都去掉,運(yùn)行會(huì)得出如下結(jié)果:

圖4、layout_weight屬性

沒有了這個(gè)屬性,我們本來定義的5個(gè)Button運(yùn)行后卻只顯示了2個(gè)Button,為什么呢??

"weight"顧名思義是權(quán)重的意思,layout_weight 用于給一個(gè)線性布局中的諸多視圖的重要程度賦值。所有的視圖都有一個(gè)layout_weight值,默認(rèn)為零,意思是需要顯示多大的視圖就占據(jù)多大的屏幕空間。這就不難解釋為什么會(huì)造成上面的情況了:Button1~Button5都設(shè)置了layout_height和layout_width屬性為wrap_content即包住文字內(nèi)容,他們都沒有設(shè)置layout_weight 屬性,即默認(rèn)為0.,這樣Button1和Button2根據(jù)需要的內(nèi)容占據(jù)了整個(gè)屏幕,別的就顯示不了啦!

若賦一個(gè)高于零的值,則將父視圖中的可用空間分割,分割大小具體取決于每一個(gè)視圖的layout_weight值以及該值在當(dāng)前屏幕布局的整體layout_weight值和在其它視圖屏幕布局的layout_weight值中所占的比率而定。舉個(gè)例子:比如說我們?cè)?水平方向上有一個(gè)文本標(biāo)簽和兩個(gè)文本編輯元素。該文本標(biāo)簽并無(wú)指定layout_weight值,所以它將占據(jù)需要提供的最少空間。如果兩個(gè)文本編輯元素每一個(gè)的layout_weight值都設(shè)置為1,則兩者平分在父視圖布局剩余的寬度(因?yàn)槲覀兟暶鬟@兩者的重要度相等)。如果兩個(gè)文本編輯元素其中第一個(gè)的layout_weight值設(shè)置為1,而第二個(gè)的設(shè)置為2,則剩余空間的三分之二分給第一個(gè),三分之一分給第二個(gè)(數(shù)值越小,重要度越高)。 

3、相對(duì)布局(Relative Layout)

相對(duì)布局:是一個(gè)ViewGroup以相對(duì)位置顯示它的子視圖(view)元素,一個(gè)視圖可以指定相對(duì)于它的兄弟視圖的位置(例如在給定視圖的左邊或者下面)或相對(duì)于RelativeLayout的特定區(qū)域的位置(例如底部對(duì)齊,或中間偏左)。

相對(duì)布局是設(shè)計(jì)用戶界面的有力工具,因?yàn)樗饲短滓晥D組。如果你發(fā)現(xiàn)你使用了多個(gè)嵌套的LinearLayout視圖組后,你可以考慮使用一個(gè)RelativeLayout視圖組了??聪旅娴膔es/layour/main.xml:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent"> 
  <TextView 
    android:id="@+id/label" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:text="Type here:"/> 
  <EditText 
    android:id="@+id/entry" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:background="@android:drawable/editbox_background" 
    android:layout_below="@id/label"/><!-- have an eye on ! --> 
  <Button 
    android:id="@+id/ok" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_below="@id/entry" <!-- have an eye on ! --> 
    android:layout_alignParentRight="true" <!-- have an eye on ! --> 
    android:layout_marginLeft="10dip" 
    android:text="OK" /> 
  <Button 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_toLeftOf="@id/ok" <!-- have an eye on ! --> 
    android:layout_alignTop="@id/ok" <!-- have an eye on ! --> 
    android:text="Cancel" /> 
</RelativeLayout> 

從上面的布局文件我們知道,RelativeLayout視圖組包含一個(gè)TextView、一個(gè)EditView、兩個(gè)Button,注意標(biāo)記了<!-- have an eye on ! -->(請(qǐng)注意運(yùn)行代碼的時(shí)候,請(qǐng)把這些注釋去掉,否則會(huì)運(yùn)行出錯(cuò),上面加上是為了更加醒目!)的屬性,在使用相對(duì)布局方式中就是使用這些類似的屬性來定位視圖到你想要的位置,它們的值是你參照的視圖的id。這些屬性的意思很簡(jiǎn)單,就是英文單詞的直譯,就不多做介紹了。運(yùn)行之后,得如下結(jié)果:

圖5、相對(duì)布局

4、 表格布局(Table Layout)

表格布局:是一個(gè)ViewGroup以表格顯示它的子視圖(view)元素,即行和列標(biāo)識(shí)一個(gè)視圖的位置。其實(shí)Android的表格布局跟HTML中的表格布局非常類似,TableRow 就像HTML表格的<tr>標(biāo)記。

用表格布局需要知道以下幾點(diǎn):

  • android:shrinkColumns,對(duì)應(yīng)的方法:setShrinkAllColumns(boolean),作用:設(shè)置表格的列是否收縮(列編號(hào)從0開始,下同),多列用逗號(hào)隔開(下同),如android:shrinkColumns="0,1,2",即表格的第1、2、3列的內(nèi)容是收縮的以適合屏幕,不會(huì)擠出屏幕。
  • android:collapseColumns,對(duì)應(yīng)的方法:setColumnCollapsed(int,boolean),作用:設(shè)置表格的列是否隱藏
  • android:stretchColumns,對(duì)應(yīng)的方法:setStretchAllColumns(boolean),作用:設(shè)置表格的列是否拉伸

看下面的res/layour/main.xml:

<?xml version="1.0" encoding="utf-8"?> 
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" 
       android:layout_width="fill_parent" 
       android:layout_height="fill_parent" 
       android:shrinkColumns="0,1,2"><!-- have an eye on ! --> 
  <TableRow><!-- row1 --> 
  <Button android:id="@+id/button1" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content"      
      android:text="Hello, I am a Button1" 
      android:layout_column="0" 
      /> 
    <Button android:id="@+id/button2" 
   android:layout_width="wrap_content" 
   android:layout_height="wrap_content" 
   android:text="Hello, I am a Button2" 
   android:layout_column="1" 
   /> 
   </TableRow> 
  <TableRow><!-- row2 --> 
  <Button android:id="@+id/button3" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content"      
      android:text="Hello, I am a Button3" 
      android:layout_column="1" 
      /> 
<Button android:id="@+id/button4" 
   android:layout_width="wrap_content" 
   android:layout_height="wrap_content" 
   android:text="Hello, I am a Button4" 
   android:layout_column="1" 
   /> 
</TableRow> 
<TableRow>  
   <Button android:id="@+id/button5" 
   android:layout_width="wrap_content" 
   android:layout_height="wrap_content" 
   android:text="Hello, I am a Button5" 
   android:layout_column="2" 
   /> 
</TableRow> 
</TableLayout> 

運(yùn)行之后可以得出下面的結(jié)果:

圖6、表格布局

5、列表視圖(List View)

列表布局:是一個(gè)ViewGroup以列表顯示它的子視圖(view)元素,列表是可滾動(dòng)的列表。列表元素通過ListAdapter自動(dòng)插入到列表。

ListAdapter:擴(kuò)展自Adapter,它是ListView和數(shù)據(jù)列表之間的橋梁。ListView可以顯示任何包裝在ListAdapter中的數(shù)據(jù)。該類提供兩個(gè)公有類型的抽象方法:

1.public abstract boolean  areAllItemsEnabled () :表示ListAdapter中的所有元素是否可激活的?如果返回真,即所有的元素是可選擇的即可點(diǎn)擊的。

2.public abstract boolean  isEnabled (int position) :判斷指定位置的元素是否可激活的?

下面通過一個(gè)例子來,創(chuàng)建一個(gè)可滾動(dòng)的列表,并從一個(gè)字符串?dāng)?shù)組讀取列表元素。當(dāng)一個(gè)元素被選擇時(shí),顯示該元素在列表中的位置的消息。

1)、首先,將res/layour/main.xml的內(nèi)容置為如下:

<?xml version="1.0" encoding="utf-8"?> 
<TextView xmlns:android="http://schemas.android.com/apk/res/android" 
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent" 
  android:padding="10dp" 
  android:textSize="16sp" > 
</TextView>

這樣就定義了元素在列表中的布局。

2)、src/skynet.com.cnblogs.www/HelloWorld.java文件的代碼如下:

package skynet.com.cnblogs.www;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public class HelloWorld extends ListActivity {
  //注意這里Helloworld類不是擴(kuò)展自Acitvity,而是擴(kuò)展自ListAcitivty
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setListAdapter(new ArrayAdapter<String>(this, R.layout.main, COUNTRIES));

    ListView lv = getListView();
    lv.setTextFilterEnabled(true);

    lv.setOnItemClickListener(new OnItemClickListener() {
     public void onItemClick(AdapterView<?> parent, View view,
       int position, long id) {
      // When clicked, show a toast with the TextView text
      Toast.makeText(getApplicationContext(), ((TextView) view).getText(),
        Toast.LENGTH_SHORT).show();
     }
    });
  }
  static final String[] COUNTRIES = new String[] {
   "1", "2", "3", "4", "5",
   "6", "7", "8", "9", "10",
   "11", "12", "13", "14", "15",
   "16", "17", "18", "19", "20",
   "21", "22", "23", "24"
  };
}

Note:onCreate()函數(shù)中并不像往常一樣通過setContentView()為活動(dòng)(Activity)加載布局文件,替代的是通過setListAdapter(ListAdapter)自動(dòng)添加一個(gè)ListView填充整個(gè)屏幕的ListActivity。在此文件中這個(gè)方法以一個(gè)ArrayAdapter為參數(shù):setListAdapter(new ArrayAdapter<String>(this, R.layout.main, COUNTRIES)),這個(gè)ArrayAdapter管理填入ListView中的列表元素。ArrayAdapter的構(gòu)造函數(shù)的參數(shù)為:this(表示應(yīng)用程序的上下文context)、表示ListViewde布局文件(這里是R.layout.main)、插入ListView的List對(duì)象對(duì)數(shù)組(這里是COUNTRES)。

setOnItemClickListener(OnItemClickListener)定義了每個(gè)元素的點(diǎn)擊(on-click)的監(jiān)聽器,當(dāng)ListView中的元素被點(diǎn)擊時(shí),onItemClick()方法被調(diào)用,在這里是即一個(gè)Toast消息——每個(gè)元素的位置將顯示。

3)、運(yùn)行應(yīng)用程序得如下結(jié)果(點(diǎn)擊1之后,在下面顯示了1):

圖7、列表布局

NOTE:如果你改了HelloWorld extends ListActivity 而不是Activity之后,運(yùn)行程序是提示:“Conversion to Dalvik format failed with error 1”??梢赃@么解決:解決辦法是 Project > Clean... > Clean project selected below > Ok

5.1、一個(gè)小的改進(jìn)

上面我們是把要填充到ListView中的元素硬編碼到HelloWorld.java文件中,這樣就缺乏靈活性!也不符合推薦的應(yīng)用程序的界面與控制它行為的代碼更好地分離的準(zhǔn)則!

其實(shí)我們可以把要填充到ListView的元素寫到res/values/strings.xml文件中的<string-array>元素中,然后再源碼中動(dòng)態(tài)地讀取。這樣strings.xml的內(nèi)容類似下面:

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string-array name="countries_array">
    <item>1</item>
    <item>2</item>
    <item>3</item>
    <item>4</item>
    <item>5</item>
    <item>6</item>
    <item>7</item>
  </string-array>
</resources>

然而HelloWorld.java文件中的onCreate()函數(shù),則這樣動(dòng)態(tài)訪問這個(gè)數(shù)組及填充到ListVies:

String[] countries = getResources().getStringArray(R.array.countries_array); 
setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, countries)); 

5.2、補(bǔ)充說明

首先總結(jié)一下列表布局的關(guān)鍵部分:

  • 布局文件中定義ListView
  • Adapter用來將數(shù)據(jù)填充到ListView
  • 要填充到ListView的數(shù)據(jù),這些數(shù)據(jù)可以字符串、圖片、控件等等

其中Adapter是ListView和數(shù)據(jù)源之間的橋梁,根據(jù)數(shù)據(jù)源的不同Adapter可以分為三類:

  • String[]: ArrayAdapter
  • List<Map<String,?>>: SimpleAdapter
  • 數(shù)據(jù)庫(kù)Cursor: SimpleCursorAdapter

使用ArrayAdapter(數(shù)組適配器)顧名思義,需要把數(shù)據(jù)放入一個(gè)數(shù)組以便顯示,上面的例子就是這樣的;SimpleAdapter能定義各種各樣的布局出來,可以放上ImageView(圖片),還可以放上Button(按鈕),CheckBox(復(fù)選框)等等;SimpleCursorAdapter是和數(shù)據(jù)庫(kù)有關(guān)的東西。篇幅有限后面兩種就不舉例實(shí)踐了。

6、網(wǎng)格視圖(Grid View)

網(wǎng)格布局:是一個(gè)ViewGroup以網(wǎng)格顯示它的子視圖(view)元素,即二維的、滾動(dòng)的網(wǎng)格。網(wǎng)格元素通過ListAdapter自動(dòng)插入到網(wǎng)格。ListAdapter跟上面的列表布局是一樣的,這里就不重復(fù)累述了。

下面也通過一個(gè)例子來,創(chuàng)建一個(gè)顯示圖片縮略圖的網(wǎng)格。當(dāng)一個(gè)元素被選擇時(shí),顯示該元素在列表中的位置的消息。

1)、首先,將上面實(shí)踐截取的圖片放入res/drawable/

2)、res/layour/main.xml的內(nèi)容置為如下:這個(gè)GridView填滿整個(gè)屏幕,而且它的屬性都很好理解,按英文單詞的意思就對(duì)了。

<?xml version="1.0" encoding="utf-8"?>
<GridView xmlns:android="http://schemas.android.com/apk/res/android" 
  android:id="@+id/gridview"
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent"
  android:columnWidth="90dp"
  android:numColumns="auto_fit"
  android:verticalSpacing="10dp"
  android:horizontalSpacing="10dp"
  android:stretchMode="columnWidth"
  android:gravity="center"
/>

3)、然后,HelloWorld.java文件中onCreate()函數(shù)如下:

 public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    GridView gridview = (GridView) findViewById(R.id.gridview);
    gridview.setAdapter(new ImageAdapter(this));

    gridview.setOnItemClickListener(new OnItemClickListener() {
      public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
        Toast.makeText(HelloWorld.this, " " + position, Toast.LENGTH_SHORT).show();
      }
    });
  } 

onCreate()函數(shù)跟通常一樣,首先調(diào)用超類的onCreate()函數(shù)函數(shù),然后通過setContentView()為活動(dòng)(Activity)加載布局文件。緊接著是,通過GridView的id獲取布局文件中的gridview,然后調(diào)用它的setListAdapter(ListAdapter)函數(shù)填充它,它的參數(shù)是一個(gè)我們自定義的ImageAdapter。后面的工作跟列表布局中一樣,為監(jiān)聽網(wǎng)格中的元素被點(diǎn)擊的事件而做的工作。

4)、實(shí)現(xiàn)我們自定義ImageAdapter,新添加一個(gè)類文件,它的代碼如下:

package skynet.com.cnblogs.www;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;

public class ImageAdapter extends BaseAdapter {
  private Context mContext;

  public ImageAdapter(Context c) {
    mContext = c;
  }

  public int getCount() {
    return mThumbIds.length;
  }

  public Object getItem(int position) {
    return null;
  }

  public long getItemId(int position) {
    return 0;
  }

  // create a new ImageView for each item referenced by the Adapter
  public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imageView;
    if (convertView == null) { // if it's not recycled, initialize some attributes
      imageView = new ImageView(mContext);
      imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
      imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
      imageView.setPadding(8, 8, 8, 8);
    } else {
      imageView = (ImageView) convertView;
    }

    imageView.setImageResource(mThumbIds[position]);
    return imageView;
  }

  // references to our images
  private Integer[] mThumbIds = {
      R.drawable.linearlayout1, R.drawable.linearlayout2,
      R.drawable.linearlayout3, R.drawable.listview,
      R.drawable.relativelayout, R.drawable.tablelayout
  };
}

ImageAdapter類擴(kuò)展自BaseAdapter,所以首先得實(shí)現(xiàn)它所要求必須實(shí)現(xiàn)的方法。構(gòu)造函數(shù)和getcount()函數(shù)很好理解,而getItem(int)應(yīng)該返回實(shí)際對(duì)象在適配器中的特定位置,但是這里我們不需要。類似地,getItemId(int)應(yīng)該返回元素的行號(hào),但是這里也不需要。

這里重點(diǎn)要介紹的是getView()方法,它為每個(gè)要添加到ImageAdapter的圖片都創(chuàng)建了一個(gè)新的View。當(dāng)調(diào)用這個(gè)方法時(shí),一個(gè)View是循環(huán)再用的,因此要確認(rèn)對(duì)象是否為空。如果是空的話,一個(gè)ImageView就被實(shí)例化且配置想要的顯示屬性:

  • setLayoutParams(ViewGroup.LayoutParams):設(shè)置View的高度和寬度,這確保不管drawable中圖片的大小,每個(gè)圖片都被重新設(shè)置大小且剪裁以適應(yīng)這些尺寸。
  • setScaleType(ImageView.ScaleType):聲明圖片應(yīng)該向中心剪裁(如果需要的話)。
  • setPadding(int, int, int, int):定義補(bǔ)距,如果圖片有不同的橫縱比,小的補(bǔ)距將導(dǎo)致更多的剪裁以適合設(shè)置的ImageView的高度和寬度。

如果View傳到getView()不是空的,則本地的ImageView初始化時(shí)將循環(huán)再用View對(duì)象。在getView()方法末尾,position整數(shù)傳入setImageResource()方法以從mThumbIds數(shù)組中選擇圖片。

運(yùn)行程序會(huì)得到如下結(jié)果(點(diǎn)擊第一張圖片之后):

圖8、網(wǎng)格布局

7、絕對(duì)布局(AbsoluteLayout)

絕對(duì)布局:是一個(gè)ViewGroup以絕對(duì)方式顯示它的子視圖(view)元素,即以坐標(biāo)的方式來定位在屏幕上位置。

這種布局方式很好理解,在布局文件或編程地設(shè)置View的坐標(biāo),從而絕對(duì)地定位。如下所示布局文件:

<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="絕對(duì)布局"
   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>

 簡(jiǎn)單吧,這里不在深入了!

8、標(biāo)簽布局(Tab Layout)

標(biāo)簽布局:是一個(gè)ViewGroup以標(biāo)簽的方式顯示它的子視圖(view)元素,就像在Firefox中的一個(gè)窗口中顯示多個(gè)網(wǎng)頁(yè)一樣。

為了狂創(chuàng)建一個(gè)標(biāo)簽UI(tabbed UI),需要使用到TabHost和TabWidget。TabHost必須是布局的根節(jié)點(diǎn),它包含為了顯示標(biāo)簽的TabWidget和顯示標(biāo)簽內(nèi)容的FrameLayout。

可以有兩種方式實(shí)現(xiàn)標(biāo)簽內(nèi)容:使用標(biāo)簽在同一個(gè)活動(dòng)中交換視圖、使用標(biāo)簽在完全隔離的活動(dòng)之間改變。根據(jù)你的需要,選擇不同的方式,但是如果每個(gè)標(biāo)簽提供不同的用戶活動(dòng),為每個(gè)標(biāo)簽選擇隔離的活動(dòng),因此你可以更好地以分離的組管理應(yīng)用程序,而不是一個(gè)巨大的應(yīng)用程序和布局。下面還有一個(gè)例子來創(chuàng)建一個(gè)標(biāo)簽UI,每個(gè)標(biāo)簽使用隔離的活動(dòng)。

1)、在項(xiàng)目中建立三個(gè)隔離的Activity類:ArtistisActivity、AlbumActivity、SongActivity。它們每個(gè)表示一個(gè)分隔的標(biāo)簽。每個(gè)通過TextView顯示簡(jiǎn)單的一個(gè)消息,例如:

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);
  }
}

其它兩個(gè)類也類似。

2)、設(shè)置每個(gè)標(biāo)簽的圖標(biāo),每個(gè)圖標(biāo)應(yīng)該有兩個(gè)版本:一個(gè)是選中時(shí)的,一個(gè)是未選中時(shí)的。通常的設(shè)計(jì)建議是,選中的圖標(biāo)應(yīng)該是深色(灰色),未選中的圖標(biāo)是淺色(白色)。

現(xiàn)在創(chuàng)建一個(gè)state-list drawable指定哪個(gè)圖標(biāo)表示標(biāo)簽的狀態(tài):將圖片放到res/drawable目錄下并創(chuàng)建一個(gè)新的XML文件命名為ic_tab_artists.xml,內(nèi)容如下:

<?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的內(nèi)容置為如下:

<?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>

這個(gè)布局將顯示標(biāo)簽和提供上面創(chuàng)建的活動(dòng)之間的導(dǎo)航。TabHost要求包含一個(gè)TabWidget和一個(gè)FrameLayout。TabWidget和FrameLayoutTabHost以線性垂直地顯示。

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);
  }
}

設(shè)置每個(gè)標(biāo)簽的文字和圖標(biāo),并分配每個(gè)標(biāo)簽一個(gè)活動(dòng)(這里為了方便三個(gè)標(biāo)簽都有相同的圖標(biāo))。TabHost的引用第一次通過getTabHost()獲取。然后,為每個(gè)標(biāo)簽,創(chuàng)建TabHost.TabSpec定義標(biāo)簽的屬性。newTabSpec(String)方法創(chuàng)建一個(gè)新的TabHost.TabSpec以給定的字符串標(biāo)識(shí)標(biāo)簽。調(diào)用TabHost.TabSpec, setIndicator(CharSequence, Drawable)為每個(gè)標(biāo)簽設(shè)置文字和圖標(biāo),調(diào)用setContent(Intent)指定Intent去打開合適的活動(dòng)。每個(gè)TabHost.TabSpec通過調(diào)用addTab(TabHost.TabSpec)添加到TabHost。

最后,setCurrentTab(int)設(shè)置打開默認(rèn)顯示的標(biāo)簽,通過索引標(biāo)簽的位置。

5)、打開Android的清單文件AndroidManifest.xml,添加NoTitleBar主題到HelloWorld的<activity>標(biāo)記。這將移除默認(rèn)應(yīng)用程序的標(biāo)題和頂端布局,給標(biāo)簽騰出位置。<activity>標(biāo)記應(yīng)該像這樣:

    <activity android:name=".HelloWorld"
         android:label="@string/app_name"
         android:theme="@android:style/Theme.NoTitleBar">

你運(yùn)行這個(gè)程序能夠得到什么結(jié)果呢?請(qǐng)自行檢查。不過我在這里告訴你很有可能會(huì)運(yùn)行不了,報(bào)“java.lang.NullPointerException”錯(cuò)!我想運(yùn)行這個(gè)例子的很多人都會(huì)有這個(gè)問題,不信你試試!

PS:其實(shí)這也算是Android的一個(gè)bug,而且這個(gè)bug在2.2中還沒有解決,這個(gè)問題全球N多人都碰到了,并在http://code.google.com/p/android/issues中掛號(hào)了,相關(guān)問題的編號(hào)有不止一個(gè)。

接著往下看……

如果你看了我這篇文章,你一定會(huì)是個(gè)幸運(yùn)兒!經(jīng)過我艱苦的調(diào)試+找資料,我找到了解決方法:

在清單文件AndroidManifest.xml,添加下面三個(gè)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> 

現(xiàn)在運(yùn)行可以看到如下結(jié)果:

圖9、標(biāo)簽布局

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android 屏幕切換監(jiān)聽的實(shí)例代碼

    Android 屏幕切換監(jiān)聽的實(shí)例代碼

    我試著在屏幕切換時(shí),使View顯示在不同的位置,在網(wǎng)上搜索了一些資料,自己做了一段時(shí)間,終于完成了功能,今天小編給大家分享android 屏幕切換監(jiān)聽的實(shí)例代碼,需要的的朋友參考下吧
    2017-01-01
  • Android中okhttp3使用詳解

    Android中okhttp3使用詳解

    這篇文章主要介紹了Android中okhttp3使用詳解,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-09-09
  • Android布局之表格布局TableLayout詳解

    Android布局之表格布局TableLayout詳解

    這篇文章主要為大家詳細(xì)介紹了Android布局之表格布局TableLayout,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • Android中使用socket通信實(shí)現(xiàn)消息推送的方法詳解

    Android中使用socket通信實(shí)現(xiàn)消息推送的方法詳解

    這篇文章主要介紹了Android中使用socket通信實(shí)現(xiàn)消息推送的方法,文中舉了一個(gè)消息發(fā)送端和一個(gè)消息接收端以及服務(wù)器端的例子來說明原理并且展示了客戶端的實(shí)現(xiàn),需要的朋友可以參考下
    2016-04-04
  • Android中EditText和AutoCompleteTextView設(shè)置文字選中顏色方法

    Android中EditText和AutoCompleteTextView設(shè)置文字選中顏色方法

    這篇文章主要介紹了Android中EditText和AutoCompleteTextView設(shè)置文字選中顏色方法,本文給出了效果圖和實(shí)現(xiàn)代碼,需要的朋友可以參考下
    2015-01-01
  • Android Activity的4種啟動(dòng)模式圖文介紹

    Android Activity的4種啟動(dòng)模式圖文介紹

    這篇文章主要給大家介紹了關(guān)于Android Activity的4種啟動(dòng)模式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Android 獲取IP地址的實(shí)現(xiàn)方法

    Android 獲取IP地址的實(shí)現(xiàn)方法

    這篇文章主要介紹了Android 獲取IP地址的實(shí)現(xiàn)方法的相關(guān)資料,這里提供了具體實(shí)現(xiàn)的方法及代碼,使用WIFI 和GPRS的思路,需要的朋友可以參考下
    2016-11-11
  • 控制Android LED燈顏色的代碼實(shí)例

    控制Android LED燈顏色的代碼實(shí)例

    控制Android LED燈顏色的代碼實(shí)例,需要的朋友可以參考一下
    2013-05-05
  • Android開發(fā)實(shí)現(xiàn)的簡(jiǎn)單五子棋游戲示例

    Android開發(fā)實(shí)現(xiàn)的簡(jiǎn)單五子棋游戲示例

    這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)的簡(jiǎn)單五子棋游戲,結(jié)合實(shí)例形式分析了Android實(shí)現(xiàn)五子棋游戲功能的布局、游戲功能等具體實(shí)現(xiàn)步驟與相關(guān)算法實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-12-12
  • Android TabHost如何實(shí)現(xiàn)頂部選項(xiàng)卡

    Android TabHost如何實(shí)現(xiàn)頂部選項(xiàng)卡

    這篇文章主要介紹了Android TabHost如何實(shí)現(xiàn)頂部選項(xiàng)卡,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09

最新評(píng)論