• Android学习系列(23)--App主界面实现


    在上篇文章《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方法,发现这种方法布局和代码比较简洁,看上去性能也不错(待查)。
    用核心代码来说明一下原理:

    1
    2
    3
    4
    5
    6
    //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内容
    我采用相对布局(相对于线性布局,我经常选择帧布局和相对布局,我更喜欢这两个小巧的布局):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    <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.
    最终我们的布局文件如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    <?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.
    以点击评花的主要代码为例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    //评花
    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:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    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学习者必备基础。 
    这种东西的积累和分析也是能提高我们感觉应用的审美感。 

  • 相关阅读:
    mysql 新用户添加和权限
    分治法
    插入排序
    猴子分桃问题
    关于PHP面向对象 静态方法的疑问
    php中static 静态变量和普通变量的区别
    php函数引用返回
    redis 限制请求次数的写法
    cas单点登录认证原理
    聚簇索引和非聚簇索引
  • 原文地址:https://www.cnblogs.com/Alex80/p/4185112.html
Copyright © 2020-2023  润新知