博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android学习系列(23)--App主界面实现
阅读量:6276 次
发布时间:2019-06-22

本文共 12076 字,大约阅读时间需要 40 分钟。

在上篇文章《》中我们浅略的分析了几个主界面布局,选了一个最大众化的经典布局。

今天我们就这个经典布局,用代码具体的实现它。

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=""
    
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个分割线,请参考《》 中的模型四,使用了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=""
    
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学习者必备基础。 
这种东西的积累和分析也是能提高我们感觉应用的审美感。 

转载地址:http://narpa.baihongyu.com/

你可能感兴趣的文章
路由模式 - direct
查看>>
form表单的target属性
查看>>
mysql的常用引擎
查看>>
Linux基础(day40)
查看>>
第二个Java应用和Tomcat的管理功能
查看>>
10.28 rsync工具介绍 10.29/10.30 rsync常用选项 10.31 rsync通过ssh同步
查看>>
使用Layer弹窗时遇到Layer.Close()后dom元素延迟性销毁的问题 @Gyb
查看>>
LVS DR +keepalived配置
查看>>
安装redis.msi 及启动命令
查看>>
k8s集群部署四(部署Flannel网络)
查看>>
C4C和Outlook的集成
查看>>
人脸检测,人脸识别,机器学习库Dlib在VS2015上的详细安装教程,示例运行
查看>>
数组——冒泡排序算法
查看>>
微信H5支付坑一--手续费未结算
查看>>
Spring Cloud Alibaba发布第二个版本,Spring 发来贺电
查看>>
Netty 备录 (一)
查看>>
netfilter 五个表五个链介绍,iptables案例
查看>>
Ubuntu服务器界面认识及创建用户
查看>>
网站如何防止sql注入攻击
查看>>
【TeeChart .NET教程】(四)轴控制
查看>>