Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android學習系列(23)--App主界面實現

Android學習系列(23)--App主界面實現

編輯:Android開發實例

在上篇文章《Android學習系列(22)--App主界面比較》中我們淺略的分析了幾個主界面布局,選了一個最大眾化的經典布局。
今天我們就這個經典布局,用代碼具體的實現它。

1.預覽圖
先看下最終的界面設計圖:

  

上面頂部是一個9patch背景圖片+標題文字;
下面底部是5個tab標簽,表示應用的5大模塊。
中間內容部分則是各個模塊的具體內容,可以再分類,或者直接顯示內容。 

2.准備素材
按照上篇文章的界面,我們需要事先提供兩大方面的素材:頂部+底部。
頂部的素材非常簡單,最重要的事背景(9patch的圖片):


底部的素材稍微多一點:
(1).每個tab的背景都需要正常和選中兩種,一共10張圖片;
(2).每個tab之間有一張分割線,1張圖片;
(3).為了自適應屏幕寬度,並保持圖形不變形,必須tab背景和下面botton這個背景色一致,所以需要1張同背景的背景圖片。
如下:
(1). 

         

(2).

(3).

在這裡呢,我再三考量,決定還是把圖片和文字放在一起,這樣一能大大降低代碼的復雜性,而且能保證漂亮的樣式,我們通過Photoshop來控制,靈活性大大增強。
以上是我在網上隨便找了幾張照片,稍微處理了一下,作為下面我們實現的素材。

3.實現原理
這裡,我采用了getDecorView方法,發現這種方法布局和代碼比較簡潔,看上去性能也不錯(待查)。
用核心代碼來說明一下原理:

        //mainTabContainer是一個空布局,做為每個tab的容器
        //activity是每個tab對應的activity
        //getDecorView是對應的activity的視圖,添加到tab容器中,就能實現切換activity的效果了
        mainTabContainer.removeAllViews();
        mainTabIntent = new Intent(this,activity);
        mainTabContainer.addView(localActivityManager.startActivity(id, mainTabIntent).getDecorView());

  通過切換不同的activity的decorView,實現tab的視圖切換。

4.基本框架
布局界面思路非常清晰,頂部+底部+中間tab內容
我采用相對布局(相對於線性布局,我經常選擇幀布局和相對布局,我更喜歡這兩個小巧的布局):

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <LinearLayout android:id="@+id/main_tab_banner"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="10dip"
        android:orientation="horizontal"
        android:gravity="center"
        android:background="@drawable/main_banner_bg"
        android:layout_alignParentTop="true">
        <!-- 標題 -->
    </LinearLayout>
    <LinearLayout android:id="@+id/main_tab"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center"
        android:background="@drawable/tab_bg"
        android:layout_alignParentBottom="true">
        <!-- 內容 -->
    </LinearLayout>
    <LinearLayout android:id="@+id/main_tab_container"
        android:layout_above="@id/main_tab"
        android:layout_below="@id/main_tab_banner"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#FFFFE0">
    </LinearLayout>
</RelativeLayout>

看起來很復雜的東西,分解一下就簡單的多了。
在標題處,加上一個TextView,做為標題顯示。
在內容處,我們需要填充5個Tab背景和1個分割線,請參考《Android學習系列(5)--App布局初探之簡單模型》 中的模型四,使用了layout_weight的屬性,平均分割了5個tab.
最終我們的布局文件如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <LinearLayout android:id="@+id/main_tab_banner"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="10dip"
        android:orientation="horizontal"
        android:gravity="center"
        android:background="@drawable/main_banner_bg"
        android:layout_alignParentTop="true">
        <TextView android:id="@+id/main_tab_banner_title"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="欣賞美花"
            android:textSize="20dip"
            android:textColor="#000000"/>
    </LinearLayout>
    <LinearLayout android:id="@+id/main_tab"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center"
        android:background="@drawable/tab_bg"
        android:layout_alignParentBottom="true">
        <ImageView android:id="@+id/appreciate_tab_btn"
            android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:gravity="center_horizontal|bottom"
            android:src="@drawable/appreciate_press"/>
        <ImageView android:gravity="center"
            android:layout_gravity="center_vertical"
            android:layout_width="5dip"
            android:layout_height="wrap_content"
            android:src="@drawable/tab_split"/>
        <ImageView android:id="@+id/discuss_tab_btn"
            android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal|bottom"
            android:textSize="16dip"
            android:src="@drawable/discuss_normal"
            android:textColor="#000000"/>
        <ImageView android:gravity="center"
            android:layout_gravity="center_vertical"
            android:layout_width="5dip"
            android:layout_height="wrap_content"
            android:src="@drawable/tab_split"/>
        <ImageView android:id="@+id/identification_tab_btn"
            android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal|bottom"
            android:textSize="16dip"
            android:src="@drawable/identification_normal"
            android:textColor="#000000"/>
        <ImageView android:gravity="center"
            android:layout_gravity="center_vertical"
            android:layout_width="5dip"
            android:layout_height="wrap_content"
            android:src="@drawable/tab_split"/>
        <ImageView android:id="@+id/favorite_tab_btn"
            android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal|bottom"
            android:textSize="16dip"
            android:textColor="#000000"
            android:src="@drawable/favorite_normal"/>
        <ImageView android:gravity="center"
            android:layout_gravity="center_vertical"
            android:layout_width="5dip"
            android:layout_height="wrap_content"
            android:src="@drawable/tab_split"/>
        <ImageView android:id="@+id/setting_tab_btn"
            android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center_horizontal|bottom"
            android:textSize="16dip"
            android:src="@drawable/setting_normal"
            android:textColor="#000000"/>
    </LinearLayout>
    <LinearLayout android:id="@+id/main_tab_container"
        android:layout_above="@id/main_tab"
        android:layout_below="@id/main_tab_banner"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="#FFFFE0">
    </LinearLayout>
</RelativeLayout>

其中的main_tab_container是容器布局,到時候動態存放切換的activity的視圖。
這時候,效果圖如下:


中間的內容為空,tab點擊也沒有任何效果,我們繼續實現。
這就是布局文件main_tab_frame.xml. 

5.事件效果
現在我們把點擊效果,切換標題,這些效果關聯起來。
選擇不同的tab,顯示不同的標題,同時切換不同的activity.
以點擊評花的主要代碼為例子:

        //評花
        discussImageView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                //標題
                mainTabTitleTextView.setText("評花論花");
                //切換內容
                setContainerView("discuss", DiscussTabActivity.class);
                //切換tab頁背景                   
                appreciateImageView.setImageResource(R.drawable.appreciate_normal);
                discussImageView.setImageResource(R.drawable.discuss_press);
                identificationImageView.setImageResource(R.drawable.identification_normal);
                favoriteImageView.setImageResource(R.drawable.favorite_normal);
                settingImageView.setImageResource(R.drawable.setting_normal);
            }
        });
        //切換activity
        public void setContainerView(String id,Class<?> activity){
            mainTabContainer.removeAllViews();
            mainTabIntent = new Intent(this,activity);
            mainTabContainer.addView(localActivityManager.startActivity(id, mainTabIntent).getDecorView());
        }

我們繼承ActivityGroup這個類,實現這個完整的類MainTabFrame.java:

public class MainTabFrame extends ActivityGroup {
    
    //Tab Activity Layout
    private LocalActivityManager localActivityManager = null;
    private LinearLayout mainTabContainer = null;
    private Intent mainTabIntent = null;

    //Tab banner title
    private TextView mainTabTitleTextView = null; 
    //Tab ImageView
    private ImageView appreciateImageView = null;
    private ImageView discussImageView = null;
    private ImageView identificationImageView = null;
    private ImageView favoriteImageView = null;
    private ImageView settingImageView = null;
    
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main_tab_frame);
        
        mainTabContainer = (LinearLayout)findViewById(R.id.main_tab_container);
        localActivityManager = getLocalActivityManager();
        setContainerView("appreciate", AppreciateTabActivity.class);
        
        initTab();
        
    }

    
    /**
     * 初始化Tab項
     */
    private void initTab() {
        mainTabTitleTextView = (TextView)findViewById(R.id.main_tab_banner_title);
        appreciateImageView = (ImageView)findViewById(R.id.appreciate_tab_btn);
        discussImageView = (ImageView)findViewById(R.id.discuss_tab_btn);
        identificationImageView = (ImageView)findViewById(R.id.identification_tab_btn);
        favoriteImageView = (ImageView)findViewById(R.id.favorite_tab_btn);
        settingImageView = (ImageView)findViewById(R.id.setting_tab_btn);
        
        //賞花
        appreciateImageView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mainTabTitleTextView.setText("欣賞美花");
                setContainerView("appreciate", AppreciateTabActivity.class);
                appreciateImageView.setImageResource(R.drawable.appreciate_press);
                discussImageView.setImageResource(R.drawable.discuss_normal);
                identificationImageView.setImageResource(R.drawable.identification_normal);
                favoriteImageView.setImageResource(R.drawable.favorite_normal);
                settingImageView.setImageResource(R.drawable.setting_normal);
            }
        });
        
        //評花
        discussImageView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mainTabTitleTextView.setText("評花論花");
                setContainerView("discuss", DiscussTabActivity.class);
                appreciateImageView.setImageResource(R.drawable.appreciate_normal);
                discussImageView.setImageResource(R.drawable.discuss_press);
                identificationImageView.setImageResource(R.drawable.identification_normal);
                favoriteImageView.setImageResource(R.drawable.favorite_normal);
                settingImageView.setImageResource(R.drawable.setting_normal);
            }
        });
        
        //識花
        identificationImageView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mainTabTitleTextView.setText("亮眼識花");
                setContainerView("identification", IdentificationTabActivity.class);
                appreciateImageView.setImageResource(R.drawable.appreciate_normal);
                discussImageView.setImageResource(R.drawable.discuss_normal);
                identificationImageView.setImageResource(R.drawable.identification_press);
                favoriteImageView.setImageResource(R.drawable.favorite_normal);
                settingImageView.setImageResource(R.drawable.setting_normal);
            }
        });
        
        //收藏
        favoriteImageView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mainTabTitleTextView.setText("我的收藏");
                setContainerView("favorite", FavoriteTabActivity.class);
                appreciateImageView.setImageResource(R.drawable.appreciate_normal);
                discussImageView.setImageResource(R.drawable.discuss_normal);
                identificationImageView.setImageResource(R.drawable.identification_normal);
                favoriteImageView.setImageResource(R.drawable.favorite_press);
                settingImageView.setImageResource(R.drawable.setting_normal);
            }
        });
        
        //設置
        settingImageView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                mainTabTitleTextView.setText("定義設置");
                setContainerView("setting", SettingTabActivity.class);
                appreciateImageView.setImageResource(R.drawable.appreciate_normal);
                discussImageView.setImageResource(R.drawable.discuss_normal);
                identificationImageView.setImageResource(R.drawable.identification_normal);
                favoriteImageView.setImageResource(R.drawable.favorite_normal);
                settingImageView.setImageResource(R.drawable.setting_press);
            }
        });
    }
    
    public void setContainerView(String id,Class<?> activity){
        mainTabContainer.removeAllViews();
        mainTabIntent = new Intent(this,activity);
        mainTabContainer.addView(localActivityManager.startActivity(id, mainTabIntent).getDecorView());
    }
}

  具體的每個activity怎麼顯示的,再通過AppreciateTabActivity,DiscussTabActivity,IdentificationTabActivity,FavoriteTabActivity,SettingTabActivity這些獨自實現,不再累述。

6.擴展建議
這裡補充兩點:
(1).標題欄在上述示例中,我是放在MainTabFrame,這樣做的好處是,統一了,方便了;這樣做的缺點是,如果每個activity的標題欄是不同的按鈕,不同的操作,會有些膨脹。所以,標題欄放在主Acvtivity和子Activity中,考慮一下即可。
(2).tab的切換效果,我做的非常簡單,具體的圖片陰影,凹凸,文字色彩區分都沒有去做(本人對Photoshop實在不熟),美化方面還可以大大改進。

7.小結 
通過實現這麼個簡單的主界面框架,能使我們快速的開始我們相應的感興趣項目,提供了一種大眾化得參考,是android學習者必備基礎。 
這種東西的積累和分析也是能提高我們感覺應用的審美感。 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved