Android仿微信顶/底部菜单栏效果

时间:2021-09-26 12:37:50

本文要实现仿微信微信底部菜单栏+顶部菜单栏,采用viewpage来做,每一个page对应一个xml,当手指在viewpage左右滑动时,就相应显示不同的page(其实就是xml)并且同时改变底部菜单按钮的图片变暗或变亮,同时如果点击底部菜单按钮,左右滑动page(其实就是xml)并且改变相应按钮的亮度。

Android仿微信顶/底部菜单栏效果

一、布局
1、顶部菜单布局,命名为top_layout.xml

?
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
<?xml version="1.0" encoding="utf-8"?>
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="45dp"
 android:background="@drawable/title_bar" >
 <textview
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_marginleft="20dp"
  android:text="微信"
  android:layout_centervertical="true"
  android:textcolor="#ffffff"
  android:textsize="20sp"
  android:textstyle="bold"
  />
 <imagebutton
  android:id="@+id/top_add"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:background="@drawable/top_add"
  android:layout_centervertical="true"
  android:layout_alignparentright="true"
  />
  <imagebutton
  android:id="@+id/top_search"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:background="@drawable/top_search"
  android:layout_centervertical="true"
  android:layout_toleftof="@id/top_add"
  />
</relativelayout>

效果:

Android仿微信顶/底部菜单栏效果

2、底部菜单布局bottom_layout.xml

?
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
<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="60dp"
 android:background="@drawable/bottom_bar"
 android:orientation="horizontal" >
 
 <linearlayout
  android:id="@+id/id_tab_weixin"
  android:layout_width="0dp"
  android:layout_height="match_parent"
  android:layout_weight="1"
  android:gravity="center"
  android:orientation="vertical" >
 <!-- android:clickable="false" 是为了防止imagebutton截取了触摸事件 ,这里事件要给它的上一级linearlayout-->
  <imagebutton
    android:id="@+id/id_tab_weixin_img"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="#00000000"
   android:clickable="false"
   android:src="@drawable/tab_weixin_pressed" />
 
  <textview
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="微信"
   />
 </linearlayout>
 
 <linearlayout
   android:id="@+id/id_tab_address"
  android:layout_width="0dp"
  android:layout_height="match_parent"
  android:layout_weight="1"
  android:gravity="center"
  android:orientation="vertical" >
 
  <imagebutton
    android:id="@+id/id_tab_address_img"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="#00000000"
    android:clickable="false"
   android:src="@drawable/tab_address_normal" />
 
  <textview
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="通讯录"
   />
 </linearlayout>
 
 <linearlayout
  android:id="@+id/id_tab_frd"
  android:layout_width="0dp"
  android:layout_height="match_parent"
  android:layout_weight="1"
  android:gravity="center"
  android:orientation="vertical" >
 
  <imagebutton
    android:id="@+id/id_tab_frd_img"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="#00000000"
    android:clickable="false"
   android:src="@drawable/tab_find_frd_normal" />
 
  <textview
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="发现"
 />
 </linearlayout>
 
 <linearlayout
  android:id="@+id/id_tab_settings"
  android:layout_width="0dp"
  android:layout_height="match_parent"
  android:layout_weight="1"
  android:gravity="center"
  android:orientation="vertical" >
 
  <imagebutton
    android:id="@+id/id_tab_settings_img"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="#00000000"
   android:clickable="false"
   android:src="@drawable/tab_settings_normal" />
 
  <textview
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:text="我"
   />
 </linearlayout>
 
</linearlayout>

效果:

Android仿微信顶/底部菜单栏效果

3、整体布局
将上面两个加到activity_main.xml中去

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="vertical" >
 
 <include layout="@layout/top_layout" />
 
 <android.support.v4.view.viewpager
  android:id="@+id/id_viewpage"
  android:layout_width="fill_parent"
  android:layout_height="0dp"
  android:layout_weight="1" >
 </android.support.v4.view.viewpager>
"
 
 <include layout="@layout/bottom_layout" />
 
</linearlayout>

效果:

Android仿微信顶/底部菜单栏效果

效果还可以,底下菜单栏是有背景的,有点儿白色的,所以看得不是很清,一来微信是选中的
4、定义viewpage的四个布局
因为要用viewpage要加四个page,每个page对应一个xml,所以这里定义四个xml.
tab01.xml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:gravity="center"
 android:orientation="vertical" >
  <textview
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="这里是微信"
  android:layout_centervertical="true"
  android:textcolor="#000000"
  android:textsize="40sp"
  android:textstyle="bold"
  />
 
</linearlayout>

效果:

Android仿微信顶/底部菜单栏效果

tab02.xml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:gravity="center"
 android:orientation="vertical" >
  <textview
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="这里是通讯录"
  android:layout_centervertical="true"
  android:textcolor="#000000"
  android:textsize="40sp"
  android:textstyle="bold"
  />
 
</linearlayout>

效果:效果和上面一样,只是文字改了一下
tab03.xml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:gravity="center"
 android:orientation="vertical" >
  <textview
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="这里是发现"
  android:layout_centervertical="true"
  android:textcolor="#000000"
  android:textsize="40sp"
  android:textstyle="bold"
  />
 
</linearlayout>

效果:效果和上面一样,只是文字改了一下
tab04.xml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:gravity="center"
 android:orientation="vertical" >
  <textview
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:text="这里是我"
  android:layout_centervertical="true"
  android:textcolor="#000000"
  android:textsize="40sp"
  android:textstyle="bold"
  />
 
</linearlayout>

效果:效果和上面一样,只是文字改了一下
二、代码
1. mainactivity中把控件和viewpage初始化

?
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
package com.example.tabexample;
 
import java.util.arraylist;
import java.util.list;
import android.os.bundle;
import android.app.activity;
import android.support.v4.view.pageradapter;
import android.support.v4.view.viewpager;
import android.support.v4.view.viewpager.onpagechangelistener;
import android.view.layoutinflater;
import android.view.view;
import android.view.viewgroup;
import android.view.window;
import android.widget.imagebutton;
import android.widget.linearlayout;
 
public class mainactivity extends activity implements
  android.view.view.onclicklistener {
 
 private viewpager mviewpager;// 用来放置界面切换
 private pageradapter mpageradapter;// 初始化view适配器
 private list<view> mviews = new arraylist<view>();// 用来存放tab01-04
 // 四个tab,每个tab包含一个按钮
 private linearlayout mtabweixin;
 private linearlayout mtabaddress;
 private linearlayout mtabfrd;
 private linearlayout mtabsetting;
 // 四个按钮
 private imagebutton mweixinimg;
 private imagebutton maddressimg;
 private imagebutton mfrdimg;
 private imagebutton msettingimg;
 
 @override
 protected void oncreate(bundle savedinstancestate) {
  super.oncreate(savedinstancestate);
  requestwindowfeature(window.feature_no_title);
  setcontentview(r.layout.activity_main);
  initview();
  initviewpage();
  initevent();
 }
 
 private void initevent() {
  mtabweixin.setonclicklistener(this);
  mtabaddress.setonclicklistener(this);
  mtabfrd.setonclicklistener(this);
  mtabsetting.setonclicklistener(this);
  mviewpager.setonpagechangelistener(new onpagechangelistener() {
   /**
   *viewpage左右滑动时
   */
   @override
   public void onpageselected(int arg0) {
    int currentitem = mviewpager.getcurrentitem();
    switch (currentitem) {
    case 0:
      resetimg();
     mweixinimg.setimageresource(r.drawable.tab_weixin_pressed);
     break;
    case 1:
      resetimg();
     maddressimg.setimageresource(r.drawable.tab_address_pressed);
     break;
    case 2:
      resetimg();
     mfrdimg.setimageresource(r.drawable.tab_find_frd_pressed);
     break;
    case 3:
      resetimg();
     msettingimg.setimageresource(r.drawable.tab_settings_pressed);
     break;
    default:
     break;
    }
   }
 
   @override
   public void onpagescrolled(int arg0, float arg1, int arg2) {
 
   }
 
   @override
   public void onpagescrollstatechanged(int arg0) {
 
   }
  });
 }
 
 /**
  * 初始化设置
  */
 private void initview() {
  mviewpager = (viewpager) findviewbyid(r.id.id_viewpage);
  // 初始化四个linearlayout
  mtabweixin = (linearlayout) findviewbyid(r.id.id_tab_weixin);
  mtabaddress = (linearlayout) findviewbyid(r.id.id_tab_address);
  mtabfrd = (linearlayout) findviewbyid(r.id.id_tab_frd);
  mtabsetting = (linearlayout) findviewbyid(r.id.id_tab_settings);
  // 初始化四个按钮
  mweixinimg = (imagebutton) findviewbyid(r.id.id_tab_weixin_img);
  maddressimg = (imagebutton) findviewbyid(r.id.id_tab_address_img);
  mfrdimg = (imagebutton) findviewbyid(r.id.id_tab_frd_img);
  msettingimg = (imagebutton) findviewbyid(r.id.id_tab_settings_img);
 }
 
 /**
  * 初始化viewpage
  */
 private void initviewpage() {
 
  // 初妈化四个布局
  layoutinflater mlayoutinflater = layoutinflater.from(this);
  view tab01 = mlayoutinflater.inflate(r.layout.tab01, null);
  view tab02 = mlayoutinflater.inflate(r.layout.tab02, null);
  view tab03 = mlayoutinflater.inflate(r.layout.tab03, null);
  view tab04 = mlayoutinflater.inflate(r.layout.tab04, null);
 
  mviews.add(tab01);
  mviews.add(tab02);
  mviews.add(tab03);
  mviews.add(tab04);
 
  // 适配器初始化并设置
  mpageradapter = new pageradapter() {
 
   @override
   public void destroyitem(viewgroup container, int position,
     object object) {
    container.removeview(mviews.get(position));
 
   }
 
   @override
   public object instantiateitem(viewgroup container, int position) {
    view view = mviews.get(position);
    container.addview(view);
    return view;
   }
 
   @override
   public boolean isviewfromobject(view arg0, object arg1) {
 
    return arg0 == arg1;
   }
 
   @override
   public int getcount() {
 
    return mviews.size();
   }
  };
  mviewpager.setadapter(mpageradapter);
 }
 
 /**
  * 判断哪个要显示,及设置按钮图片
  */
 @override
 public void onclick(view arg0) {
 
  switch (arg0.getid()) {
  case r.id.id_tab_weixin:
   mviewpager.setcurrentitem(0);
   resetimg();
   mweixinimg.setimageresource(r.drawable.tab_weixin_pressed);
   break;
  case r.id.id_tab_address:
   mviewpager.setcurrentitem(1);
   resetimg();
   maddressimg.setimageresource(r.drawable.tab_address_pressed);
   break;
  case r.id.id_tab_frd:
   mviewpager.setcurrentitem(2);
   resetimg();
   mfrdimg.setimageresource(r.drawable.tab_find_frd_pressed);
   break;
  case r.id.id_tab_settings:
   mviewpager.setcurrentitem(3);
   resetimg();
   msettingimg.setimageresource(r.drawable.tab_settings_pressed);
   break;
  default:
   break;
  }
 }
 
 /**
  * 把所有图片变暗
  */
 private void resetimg() {
  mweixinimg.setimageresource(r.drawable.tab_weixin_normal);
  maddressimg.setimageresource(r.drawable.tab_address_normal);
  mfrdimg.setimageresource(r.drawable.tab_find_frd_normal);
  msettingimg.setimageresource(r.drawable.tab_settings_normal);
 }
 
}

代码量很短,只有几百行,功能就可以实现了,注意这里去掉程序原本的标题栏我直接用了
requestwindowfeature(window.feature_no_title); 

2、效果:

Android仿微信顶/底部菜单栏效果

三、思路说明
1、分别为顶部菜单栏和底部菜单栏新建一个布局
2、中间是viewpage,然后里面放四个page(tab01-tab04.xml),注意,要通过适配器给viewpage提供内容.
3、监听viewpage和底部菜单栏按钮的事件(注意,这里的按钮放在一个linearlayout中,所以我们监听了linearlayout的触摸事件,而屏蔽了imgaebutton的触摸事件)
4、
public void onclick(view arg0) 
这里面监听的是底部菜单的触摸事件,根据触摸的控件,改变自身的亮度、改变viewpage显示的内容
mviewpager.setonpagechangelistener(new onpagechangelistener()  

这里监听的是viewpage左右滑动的事件,改变相应控件的亮度、改变viewpage显示的内容
四、不足之处
1、最新版微信上应该是左右滑动是有部分亮度变化的,这里直接转变过去了。
2、最新版微信文字也要跟着变化,这里没做改变

以上就是本文的全部内容,希望对大家的学习有所帮助。