菜单

Android零基础入门第63节:过时但仍值得学习的选项卡TabHost

2020年1月15日 - 金沙国际唯一官网
Android零基础入门第63节:过时但仍值得学习的选项卡TabHost

为了创建一个选项卡的UI,你需要使用一个TabHost和一个TabWidget,TabHost必须是布局文件的根节点,它包含了为了显示选项卡的TabWidget和一个用于显示选项内容的FrameLayout

 

由于前几天参加一个学习培训活动,几乎每天都要从早晨7点到晚上一两点,没有什么时间来分享,实在抱歉中间断更了几天。从今天开始恢复分享,更多精彩敬请期待。

你可以用一或两种方法实现你的选项卡内容:在用一个Activity中用选项卡来在视图之间切换,或者用用选项卡来改变所有的分离的Activity。你根据你的需求来使用你想在程序中的方法,但是如果每个选项卡提供一个独特的用户Activity,那么为每个选项卡实现独立的Activity是有意义的,所有你最好在你的离散群里管理应用程序,要好过使用大量的应用程序和布局文件。

第2章 Hello,Views

本章我们会选取几个类似“Hello World”的例子,并快速布局用来演示一些Views。

本章需要有一定的知识积累,开始之前你应该完成“Hello
World”并且知道如何创建运行一个工程,了解一个工程的基本结构。以下是一些内容的预览

2.1布局

Linear Layout(水平布局)

Relative Layout(相对布局)

Table Layout(表格布局)

     

Grid View(网格View)

Tab Layout(选项卡布局)

List View(列表View)

     

表格2-1

2.2 Widgets和其他Views

Date Picker(日期选择器)

Time Picker(时间选择器)

Form Stuff(表单元素)

     

Spinner(下拉列表)

Auto Complete(自动完成)

Gallery(画廊)

     

Google Map View(谷歌地图)

Web View(浏览器View)

 

   

 

表格2-2

更多的View,大家可以参考android.widget.*包中的内容,下面我们开始单独讲解上面的例子。

2.1.1 Linear Layout

LinearLayout继承自ViewGroup,而ViewGroup继承自View。这种水平布局有横向和纵向的两种模式。我们应该小心的使
用LinearLayout,如果有很多个LinearLayout的嵌套,我们可以考虑使用RelativeLayout来代替它。下面我们新建一个
HelloLinearLayout项目,然后修改main.xml如“代码清单2-1”所示:

图片 1

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

  <LinearLayout
      android:orientation="horizontal"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:layout_weight="1">
      <TextView
          android:text="red"
          android:gravity="center_horizontal"
          android:background="#aa0000"
          android:layout_width="wrap_content"
          android:layout_height="fill_parent"
          android:layout_weight="1"/>
      <TextView
          android:text="green"
          android:gravity="center_horizontal"
          android:background="#00aa00"
          android:layout_width="wrap_content"
          android:layout_height="fill_parent"
          android:layout_weight="1"/>
      <TextView
          android:text="blue"
          android:gravity="center_horizontal"
          android:background="#0000aa"
          android:layout_width="wrap_content"
          android:layout_height="fill_parent"
          android:layout_weight="1"/>
      <TextView
          android:text="yellow"
          android:gravity="center_horizontal"
          android:background="#aaaa00"
          android:layout_width="wrap_content"
          android:layout_height="fill_parent"
          android:layout_weight="1"/>
  </LinearLayout>

  <LinearLayout
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1">
    <TextView
        android:text="row one"
        android:textSize="15pt"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>
    <TextView
        android:text="row two"
        android:textSize="15pt"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>
    <TextView
        android:text="row three"
        android:textSize="15pt"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>
    <TextView
        android:text="row four"
        android:textSize="15pt"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"/>
  </LinearLayout>

</LinearLayout>

图片 2

 

代码清单2-1

注意“代码清单2-1”中有两个需要注意的地方,一个是android:orientation这个属性用来描述当前
LinearLayout是垂直还是水平,默认不填的话是水平布局,你可以使用“vertical”和“horizontal”来设置。还有一个是XX,
这个属性表示权重,我们理解为比例,例如如果A的weight为3,B的weight为1,那么A占整个大小的3/4,B占1/4。“代码清单2-1”这
里都是平均分布的,都选的1。然后代码中无需修改任何内容。运行后的效果就如表格2-1中的一样。

2.1.2 Relative Layout

一个RelativeLayout是一个非常强大的工具用来做用户界面,因为它可以消除嵌套ViewGroups。如果你发现自己使用多个嵌套的
LinearLayout组,您就可以考虑使用一个RelativeLayout来替换它。下面我们新建一个HelloRelativeLayout项
目,然后修改main.xml如“代码清单2-2”所示:

图片 3

<?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"/>
    <Button
        android:id="@+id/ok"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/entry"
        android:layout_alignParentRight="true"
        android:layout_marginLeft="10dip"
        android:text="OK" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toLeftOf="@id/ok"
        android:layout_alignTop="@id/ok"
        android:text="Cancel" />
</RelativeLayout>

图片 4

 

代码清单2-2

这里我们看到一些属性如

android:layout_below,android:layout_toLeftOf,android:layout_alignParentRight。
看字面意思应该就很容易明白,并且使用这些属性的时候都需要传一个ID,因为相对布局你需要指定一个与之相对应的对象,它会根据这个对象来调整自己的位
置。大家可以多试一下其他的属性,就能明白使用方法了。运行后的效果就如表格2-1中的一样。

2.1.3 Table Layout

TableLayout是基于行和列的布局模式,我们新建一个HelloTableLayout项目,然后修改main.xml如“代码清单2-3”所示:

图片 5

<?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:stretchColumns="1">

    <TableRow>
        <TextView
            android:layout_column="1"
            android:text="Open..."
            android:padding="3dip" />
        <TextView
            android:text="Ctrl-O"
            android:gravity="right"
            android:padding="3dip" />
    </TableRow>

    <TableRow>
        <TextView
            android:layout_column="1"
            android:text="Save..."
            android:padding="3dip" />
        <TextView
            android:text="Ctrl-S"
            android:gravity="right"
            android:padding="3dip" />
    </TableRow>

    <TableRow>
        <TextView
            android:layout_column="1"
            android:text="Save As..."
            android:padding="3dip" />
        <TextView
            android:text="Ctrl-Shift-S"
            android:gravity="right"
            android:padding="3dip" />
    </TableRow>

    <View
        android:layout_height="2dip"
        android:background="#FF909090" />

    <TableRow>
        <TextView
            android:text="X"
            android:padding="3dip" />
        <TextView
            android:text="Import..."
            android:padding="3dip" />
    </TableRow>

    <TableRow>
        <TextView
            android:text="X"
            android:padding="3dip" />
        <TextView
            android:text="Export..."
            android:padding="3dip" />
        <TextView
            android:text="Ctrl-E"
            android:gravity="right"
            android:padding="3dip" />
    </TableRow>

    <View
        android:layout_height="2dip"
        android:background="#FF909090" />

    <TableRow>
        <TextView
            android:layout_column="1"
            android:text="Quit"
            android:padding="3dip" />
    </TableRow>

</TableLayout>

图片 6

代码清单2-3

TableLayout类似于Html的表格结构,你可以认为TableLayout像Html<table>元素,TableRow像Html<tr>元素,但列数你可以自定义。运行后的效果就如表格2-1中的一样。

2.1.4 Grid View

GridView是一个显示二维的并能滚动的ViewGroup。每一个GridView的item使用ListAdapter被自动插入到布局
中。本小节将创建一个图像的网格,当其中一个item被选中时会使用toast弹出一个消息用来显示图像的位置。我们按照以下步骤完成这个项目。

  1. 创建一个HelloGridView的项目

2.
找一些图片资源,或者使用本例中的图片(光盘资源的此项目中有图片资源,在res/drawable-mdpi/目录下)

  1. 修改main.xml如“代码清单2-4”所示:

图片 7

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

/>

图片 8

代码清单2-4

这个GridView将填充全屏,属性的含义就如字面意思一样

  1. 打开我们的主类 HelloGridView.java,然就修改代码如“代码清单2-5”所示:

图片 9

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(HelloGridView.this, "" + position, Toast.LENGTH_SHORT).show();

        }

    });

}

图片 10

 

代码清单2-5

当你导入相应的包后这里还是会报错,没有找到ImageAdapter,没关系先放着,等下我们会创建这个类。“代码清单2-5”中首先,我们通过
findViewById来在代码中获取XML中的GridView对象,然后使用setAdapter给gridview设置一个适配器,最后由于我们
需要监听点击事件,所以需要给gridview设置一个监听器,当然你点击一个item时会弹出一个toast,Toast是Android
API中一个很好用的类,他能短暂的弹出一些我们想知道的提示信息。

5.创建ImageAdapter类,让它继承与BaseAdapter,如“代码清单”2-6所示:

图片 11

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

    // 创建一个ImageView当成一个item被Gird引用
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) {  // 如果convertView不为空(即没有被回收),初始化一些属性
            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;
    }

    // 引用图片
    private Integer[] mThumbIds = {
            R.drawable.sample_2, R.drawable.sample_3,
            R.drawable.sample_4, R.drawable.sample_5,
            R.drawable.sample_6, R.drawable.sample_7,
            R.drawable.sample_0, R.drawable.sample_1,
            R.drawable.sample_2, R.drawable.sample_3,
            R.drawable.sample_4, R.drawable.sample_5,
            R.drawable.sample_6, R.drawable.sample_7,
            R.drawable.sample_0, R.drawable.sample_1,
            R.drawable.sample_2, R.drawable.sample_3,
            R.drawable.sample_4, R.drawable.sample_5,
            R.drawable.sample_6, R.drawable.sample_7
    };
}

图片 12

 

代码清单2-6

首先我们继承自BaseAdapter,就获得了BaseAdapter中的一些方法,然后我们写一个构造函数来传一个context,和一些简单
的统计方法getItemId(),getItem()这里先预留接口,暂时用不上。我们主要看看getView()方法,只要你继承自
BaseAdapter就必须实现此方法,这个方法为每一个图像创建一个新的View,把它添加到ImageAdapter中,然后给ImageView
设置一些属性。

  1. 执行这个项目,最后运行后的效果就如表格2-1中的一样。

2.1.5 Tab Layout

要创建这种选项卡式的布局,你需要使用TabHost和TabWidget这两个类。TabHost必须是布局的根节点,其中包含一个
TabWidget用来显示标签和一个FrameLayout用来显示内容。关于切换标签显示的内容可以用两种方式表示:一种是使用同一个
Activity但切换或改变View,另一种则是直接切换Activity。读者想使用哪种方式完全取决于个人的需求,但笔者建议使用不同的
Activity,这样为了扩展大规模的应用和布局,能更好的管理。本小节使用多个Activity来创建Tab
Layout。步骤如下:

  1. 创建一个HelloTabLayout的项目
  2. 在项目中分别创建三个的Activity:ArtistsActivity,AlbumsActivity,SongsActivity。每个Actvity代表一个单独的标签。然后加入一个TextView用来显示一些简单的信息。如“代码清单2-7”所示:

图片 13

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

}

图片 14

代码清单2-7

这里TextView我们使用代码布局。并且每个Acitivty都一样只是”This is the
Artists
tab”需要根据不同的Activity稍微调整下。当然别忘了,我们需要在AndroidManifest.xml中为每个Acitivity添加标
签。如“代码清单2-8”所示:

图片 15

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

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

    package="com.example.tablayout" android:versionCode="1"

    android:versionName="1.0">

    <uses-sdk android:minSdkVersion="8" />



    <application android:icon="@drawable/icon" android:label="@string/app_name">

        <activity android:name=".HelloTabLayout" android:label="@string/app_name">

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

       <activity android:name=".AlbumsActivity" android:theme="@android:style/Theme.NoTitleBar" />

       <activity android:name=".ArtistsActivity" android:theme="@android:style/Theme.NoTitleBar" />

       <activity android:name=".SongsActivity" android:theme="@android:style/Theme.NoTitleBar" />

    </application>

</manifest>

图片 16

代码清单2-8

  1. 我们需要为每一个选项卡设计Icons。第一大篇的“第6章.用户界面基础指导”中有Icon设计指南的详细描述。这里为了简单快速,我们在光盘资源中使用了比较简单的图片。

图片 17(未选中)图片 18(选中)

现在我们需要创建一个state-list
drawable(后面的Android框架学习中会详细讲述),用来映射一下选中和未选中状态下需要显示的图片。把我们的图片放入
res/drawable-mdpi/下,然后创建一个res/drawable/目录,在这个文件夹下创建
ic_tab_artists.xml,ic_tab_albums.xml,ic_tab_songs.xml
这3个XML文件,都加入同样的代码,如“代码清单2-9”所示:

图片 19

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

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

    <!-- 选中时使用灰白 -->

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

          android:state_selected="true" />

    <!-- 未选中时使用白色 -->

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

</selector>

图片 20

 

代码清单2-9

  1. 修改res/layout/main.xml文件如“代码清单2-10”所示:

图片 21

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

图片 22

 

代码清单2-10

  1. 打开我们的主Acitivty:HelloTabLayout.java让它继承自TabActivity而不是Activity(注意
    Android3.0以上请使用Fragment,它已经完全取代了TabActivity)。然后修改我们的HelloTabLayout.java中
    的onCreate()方法,如“代码清单2-11”所示:

图片 23

public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    Resources res = getResources(); // 获得Drawables资源对象

    TabHost tabHost = getTabHost();  // 把我们的主Activity当成TabHost

    TabHost.TabSpec spec;  // 为每一个tab指定可复用的TabSpec 

    Intent intent;  // 为每一个tab指定可复用的Intent

    // 创建一个Intent,用来为每一个tab启动一个Activity(这里的Intent只需要一个对象即可)

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

    // 为每一个tab初始化一个TabSpec然后添加到TabHost中

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

                      res.getDrawable(R.drawable.ic_tab_artists))

                  .setContent(intent);

    tabHost.addTab(spec);



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

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

                      res.getDrawable(R.drawable.ic_tab_albums))

                  .setContent(intent);

    tabHost.addTab(spec);



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

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

                      res.getDrawable(R.drawable.ic_tab_songs))

                  .setContent(intent);

    tabHost.addTab(spec);

    tabHost.setCurrentTab(2);

}

图片 24

 

代码清单2-11

为每一个选项卡设置自己的文字和图标和Activity,首先我们通过getTabHost()获得TabHos的引用,然后创建
TabHost.TabSpec为每个标签设置属性,最后使用setCurrentTab()来指定打开程序后默认显示的标签位置,我们这里没有使用
TabWidget对象,因为当一个标签被添加到TabHost时,它会自动加入到TabHost下的TabWidget中。

  1. 执行我们的程序,最后运行后的效果就如表格2-1中的一样。

2.1.6 List View

List
View也是一个ViewGroup,它用来创建一个可滚动的列表,里面的每一个元素都是一个item。并且和GridView类似它需要一个
ListAdapter这样的适配器。本节我们会创建一个ListView,里面显示的是一些国家的名字,这些名字保存在一个String数组中,当一个
item被选中时,会弹出一个Toast消息先显示一个这个item在list中的位置信息。创建步骤如下:

  1. 创建一个HelloListView的项目

2.
在res/layout/下,创建一个list_item.xml的文件,代码如“代码清单2-12”所示:

图片 25

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

图片 26

 

代码清单2-12

这个xml文件定义了ListView中每一个item的布局

3.
打开我们的主Activity文件“HelloListView.java”然后修改这个类,让它继承自ListActivity而不是Activity,然后修改其中的onCreate()方法如“代码清单2-13”所示:

图片 27

static final String[] COUNTRIES = new String[] {

    "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",

    "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",

    "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan",

    "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium",

    "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia",

    "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil", "British Indian Ocean Territory",

    "British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burundi",

    "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde",

    "Cayman Islands", "Central African Republic", "Chad", "Chile", "China",

    "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",

    "Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic",

    "Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic",

    "East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea",

    "Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland",

    "Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia",

    "French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar",

    "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau",

    "Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary",

    "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Jamaica",

    "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Laos",

    "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg",

    "Macau", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands",

    "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova",

    "Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia",

    "Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand",

    "Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "North Korea", "Northern Marianas",

    "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru",

    "Philippines", "Pitcairn Islands", "Poland", "Portugal", "Puerto Rico", "Qatar",

    "Reunion", "Romania", "Russia", "Rwanda", "Sqo Tome and Principe", "Saint Helena",

    "Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon",

    "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Saudi Arabia", "Senegal",

    "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands",

    "Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "South Korea",

    "Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden",

    "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "The Bahamas",

    "The Gambia", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey",

    "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Virgin Islands", "Uganda",

    "Ukraine", "United Arab Emirates", "United Kingdom",

    "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan",

    "Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Wallis and Futuna", "Western Sahara",

    "Yemen", "Yugoslavia", "Zambia", "Zimbabwe"

  };
@Override
public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

  setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, COUNTRIES));

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

  lv.setOnItemClickListener(new OnItemClickListener() {
    public void onItemClick(AdapterView<?> parent, View view,
        int position, long id) {
      // 当点击时,Toast显示文本信息 
      Toast.makeText(getApplicationContext(), ((TextView) view).getText(),
          Toast.LENGTH_SHORT).show();
    }
  });
}

图片 28

 

代码清单2-13

注意我们这里没有使用setContentView()来载入一个布局,取而代之的是使用setListAdapter(),因为在
ListActivity中,只需要使用setListAdapter()即可自动添加ListView在屏幕中。然后在
setListAdapter()中我们new了一个ArrayAdapter,这是Android已经写好的一个类,我们可以直接使用,传入一个
Context和一个item布局的xml文件,最后在传入一个字符数组COUNTEIES。
setTextFilterEnabled(boolean)这个方法表示在ListView中过滤文本,当用户开始打字时,这个listView会被过
滤。后面我们设置了一个监听,当你点击ListView中的某个item时的响应代码就是此处。这里我们是试用Toast弹出一个显示信息。如果你用模拟
器的话,可以在键盘上输入过滤字符,如图2-1所示:

4.运行程序,如果你用模拟器的话,可以在键盘上输入过滤字符,运行后的截图就如表格1中的一样,它会自动定位到匹配的item字段:

下面我们开始换一种字符串的处理方式,这种把字符串写到代码中的硬编码方式,我们要放弃它,更好的方法是在strings.xml中引用<string-array>节点。例如“代码清单2-14”所示:

图片 29

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="countries_array">
        <item>Bahrain</item>
        <item>Bangladesh</item>
        <item>Barbados</item>
        <item>Belarus</item>
        <item>Belgium</item>
        <item>Belize</item>
        <item>Benin</item>
    </string-array>
</resources>

图片 30

代码清单2-14

修改我们调用的地方,如“代码清单2-15”所示:

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

 

 

代码清单2-15

剩下的内容略过,在书籍中会详述!

今天来了解一个过时的组件,了解的目的不是学会用起来开发,而是了解这种界面的设计和其特点,后期可以用其他方式来替代。

在这个例子中,你可以创建一个为每个单独的Activity创建选项卡来创建一个选项卡UI

图片 31

1、开始一个新的工程,叫做HelloTabWidget

一、TabHost概述

TabHost是一种非常实用的组件,TabHost可以很方便地在窗口上放置多个标签页,每个标签页相当于获得了一个与外部容器相同大小的组件摆放区域。通过这种方式,就可以在一个容器里放置更多组件。

TabHost是整个Tab的容器,包含TabWidget和FrameLayout两个部分,TabWidget是每个Tab的标签,FrameLayout是Tab内容。与TabHost结合使用的有如下2个组件。

TabWidget:代表选项卡的标题条。

TabSpec:代表选项卡的一个Tab页面。

TabHost仅仅是一个简单的容器,它提供了如下两个方法来创建、添加标签页。

newTabSpec(String tag):创建选项卡。

addTab(TabHost.TabSpec tabSpec):添加选项卡。

实现TabHost有两种方式:

1、直接让一个Activity程序继承TabActivity类。

2、定义XML布局文件利用findViewById()方法取得TagHost组件,通过setup()方法实例化并进行配置。

2、第一,创建三个独立的Activity程序在你的工程中:ArtistsActivity,AlbumsActivity,和SongsActivity,他们每个代表一个单独的选项卡,现在用TextView来没每个程序显示一个简单的信息,比如:

二、继承TabActivity实现

通过继承TabActivity类,使用TabHost的一般步骤如下。

在界面布局文件中定义TabHost组件,并为该组件定义该选项卡的内容。

Activity 应该继承 TabActivity。

调用 TabActivity 的 getTabHost()方法获取 TabHost 对象。

通过TabHost对象的方法来创建、添加选项卡。

除此之外,TabHost还提供了一些方法来获取当前选项卡。如果程序需要监控TabHost里当前标签页的改变,则可以为它设置
TabHost.OnTabChangeListener 监听器。

接下来通过一个简单的示例程序来学习TabHost的使用。

继续使用WidgetSample工程的advancedviewsample模块,在main/res/layout/目录下创建tabhosttab_layout.xml文件,在其中填充如下代码片段:

图片 32

请注意上面的布局文件中代码,从上面的布局文件可以发现,TabHost容器内部需要组合两个组件:TabWidget和FrameLayout,其中TabWidget用于定义选项卡的标题条,
FrameLayout则用于层叠组合多个选项页面。不仅如此,上面的布局文件中这三个组件的
ID也有要求。

TabHost 的 ID 应该为@android:id/tabhost。

TabWidget 的 ID 应该为@android:id/tabs。

FrameLayout 的 ID 应该为@android:id/tabcontent。

上面这三个ID并不是开发者自己定义的,而是引用了 Android系统已有的ID。

接下来主程序即可加载该布局资源,并将布局文件中的三个Tab页面添加到该TabHost
容器中。新建TabHostTabActivity.java文件,加载上面新建的布局文件,具体代码如下:

图片 33

上面程序中的代码就是为TabHost创建并添加Tab页面的代码。上面的程序一共添加了三个标签页,用了两种方式来实现。

修改启动的Activity,运行程序,可以看到下图所示界面效果。

图片 34

点击标签,可以切换显示的内容。

上面的程序调用了 TabHost.TabSpec对象的 setContent(int
viewld)方法来设置标签页内容。

除此之外,还可调用setContent(Intent
intent)方法来设置标签页内容,Intent还可用于启动其他Activity——这意味着TabHost.TabSpec可直接装载另一个Activity。

package org.hualang.tabwidget;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class AlbumsActivity extends Activity {
        public void onCreate(Bundle savedInstanceState)
        {
                super.onCreate(savedInstanceState);
                 TextView textview = new TextView(this);
                 textview.setText("This is the Albums tab");        
                setContentView(textview);
        }
}

package org.hualang.tabwidget;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class SongsActivity extends Activity {
        public void onCreate(Bundle savedInstanceState)
        {
                super.onCreate(savedInstanceState);
                 TextView textview = new TextView(this);
                 textview.setText("This is the Songs tab"); 
                setContentView(textview);
        }

}

package org.hualang.tabwidget;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class ArtistsActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
                 TextView textview = new TextView(this);
                 textview.setText("This is the Artists tab"); 
        setContentView(textview);
    }
}

三、继承Activity实现

与继承TabActivity实现TabHost大体步骤差不多,唯一的区别就是没有TabActivity系统封装,必须由开发者自己获取TabHost组件而已。

在上面的示例基础上进行修改,创建tabhost_layout.xml文件,在其中填充如下代码片段:

图片 35

从上述代码可以发现,除了TabHost
的id可以自定义外,TabWidget和FrameLayout仍然必须为系统的ID。

界面交互代码稍微有所不同,新建TabHostActivity.java文件,加载上面新建的布局文件,具体代码如下:

图片 36

会发现除了查找我们自定义的TabHost组件外,还多了一条语句setup()来加载TabHost,否则程序会报错。

运行修改后的程序,最终效果同继承TabActivity一样。

有木有发现这个界面很不美观,所以在实际开发中经常会借用RadioButton来定制TabHost。

其实TabHost组件在安卓4.0之后已经被废弃了,建议使用Fragment组件来代替它。由于其设计违反了Activity单一窗口原则,它可以同时加载多个Activity,然后再它们之间进行来回切换;另外有个很致命的问题就是当点击别的选项时,按下Back后退键,它会使整个应用程序都退出,而不是切换到前一个选项卡,虽然可以在主程序里覆写OnKeyDown这个方法,但这样就会导致每一次按下Back后退键都只能回到第一个选项菜单。


今天就先到这里,如果有问题欢迎留言一起探讨,也欢迎加入Android零基础入门技术讨论微信群,共同成长!

此文章版权为微信公众号分享达人秀(ShareExpert)——鑫鱻所有,若需转载请联系作者授权,特此声明!

往期总结分享:

Android零基础入门第1节:Android的前世今生

Android零基础入门第2节:Android
系统架构和应用组件那些事

Android零基础入门第3节:带你一起来聊一聊Android开发环境

Android零基础入门第4节:正确安装和配置JDK,
高富帅养成第一招

Android零基础入门第5节:善用ADT Bundle,
轻松邂逅女神

Android零基础入门第6节:配置优化SDK Manager,
正式约会女神

Android零基础入门第7节:搞定Android模拟器,开启甜蜜之旅

Android零基础入门第8节:HelloWorld,我的第一趟旅程出发点

Android零基础入门第9节:Android应用实战,不懂代码也可以开发

Android零基础入门第10节:开发IDE大升级,终于迎来了Android
Studio

Android零基础入门第11节:简单几步带你飞,运行Android
Studio工程

Android零基础入门第12节:熟悉Android
Studio界面,开始装逼卖萌

Android零基础入门第13节:Android
Studio个性化配置,打造开发利器

Android零基础入门第14节:使用高速Genymotion,跨入火箭时代

Android零基础入门第15节:掌握Android
Studio项目结构,扬帆起航

Android零基础入门第16节:Android用户界面开发概述

Android零基础入门第17节:文本框TextView

Android零基础入门第18节:输入框EditText

Android零基础入门第19节:按钮Button

Android零基础入门第20节:复选框CheckBox和单选按钮RadioButton

Android零基础入门第21节:开关组件ToggleButton和Switch

Android零基础入门第22节:图像视图ImageView

Android零基础入门第23节:图像按钮ImageButton和缩放按钮ZoomButton

Android零基础入门第24节:自定义View简单使用,打造属于你的控件

Android零基础入门第25节:简单且最常用的LinearLayout线性布局

Android零基础入门第26节:两种对齐方式,layout_gravity和gravity大不同

Android零基础入门第27节:正确使用padding和margin

Android零基础入门第28节:轻松掌握RelativeLayout相对布局

Android零基础入门第29节:善用TableLayout表格布局

Android零基础入门第30节:两分钟掌握FrameLayout帧布局

Android零基础入门第31节:少用的AbsoluteLayout绝对布局

Android零基础入门第32节:新推出的GridLayout网格布局

Android零基础入门第33节:Android事件处理概述

Android零基础入门第34节:Android中基于监听的事件处理

Android零基础入门第35节:Android中基于回调的事件处理

Android零基础入门第36节:Android系统事件的处理

Android零基础入门第37节:初识ListView

Android零基础入门第38节:初识Adapter

Android零基础入门第39节:ListActivity和自定义列表项

Android零基础入门第40节:自定义ArrayAdapter

Android零基础入门第41节:使用SimpleAdapter

Android零基础入门第42节:自定义BaseAdapter

Android零基础入门第43节:ListView优化和列表首尾使用

Android零基础入门第44节:ListView数据动态更新

Android零基础入门第45节:网格视图GridView

Android零基础入门第46节:列表选项框Spinner

Android零基础入门第47节:自动完成文本框AutoCompleteTextView

Android零基础入门第48节:可折叠列表ExpandableListView

Android零基础入门第49节:AdapterViewFlipper图片轮播

Android零基础入门第50节:StackView卡片堆叠

Android零基础入门第51节:进度条ProgressBar

Android零基础入门第52节:自定义ProgressBar炫酷进度条

Android零基础入门第53节:拖动条SeekBar和星级评分条RatingBar

Android零基础入门第54节:视图切换组件ViewSwitcher

Android零基础入门第55节:ImageSwitcher和TextSwitcher

Android零基础入门第56节:翻转视图ViewFlipper

Android零基础入门第57节:DatePicker和TimePicker选择器

Android零基础入门第58节:数值选择器NumberPicker

Android零基础入门第59节:常用三大Clock时钟组件

Android零基础入门第60节:日历视图CalendarView和定时器Chronometer

Android零基础入门第61节:滚动视图ScrollView

Android零基础入门第62节:搜索框组件SearchView

图片 37

图片 38

注意这个例子中不需要布局文件,只需要创建一个TextView,并且为文本赋值即可。重复创建三个类似的Activity,并且要在AndroidManifest.xml文件中注册,否则报错

3、你需要为每个选项卡设置一个icon,每个icon,你可以有两个版本,一个是当选项卡被选中的时候,另一个是当选项卡未被选中的时候。一般设计来说,建议当被选中的时候用灰色,的那个未被选中的时候用白色,比如

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图