Android仿微信底部菜單欄+頂部菜單欄(附源碼)

 林炳文Evankaka原創作品。轉載請註明出處http://blog.csdn.net/evankaka

        本文要實現仿微信微信底部菜單欄+頂部菜單欄,採用ViewPage來做,每一個page對應一個XML,當手指在ViewPage左右滑動時,就相應顯示不同的page(其實就是xml)並且同時改變底部菜單按鈕的圖片變暗或變亮,同時如果點擊底部菜單按鈕,左右滑動page(其實就是xml)並且改變相應按鈕的亮度。

最終效果:源碼免費下載


一、佈局

1、頂部菜單佈局,命名爲top_layout.xml

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="45dp"  
  5.     android:background="@drawable/title_bar" >  
  6.     <TextView  
  7.         android:layout_width="wrap_content"  
  8.         android:layout_height="wrap_content"  
  9.         android:layout_marginLeft="20dp"  
  10.         android:text="微信"  
  11.         android:layout_centerVertical="true"  
  12.         android:textColor="#ffffff"  
  13.         android:textSize="20sp"  
  14.         android:textStyle="bold"  
  15.         />  
  16.     <ImageButton   
  17.         android:id="@+id/top_add"  
  18.         android:layout_width="wrap_content"  
  19.         android:layout_height="wrap_content"  
  20.         android:background="@drawable/top_add"  
  21.         android:layout_centerVertical="true"  
  22.         android:layout_alignParentRight="true"  
  23.         />  
  24.        <ImageButton   
  25.         android:id="@+id/top_search"  
  26.         android:layout_width="wrap_content"  
  27.         android:layout_height="wrap_content"  
  28.         android:background="@drawable/top_search"  
  29.         android:layout_centerVertical="true"  
  30.         android:layout_toLeftOf="@id/top_add"  
  31.         />  
  32. </RelativeLayout>  
效果:


2、底部菜單佈局bottom_layout.xml

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="60dp"  
  5.     android:background="@drawable/bottom_bar"  
  6.     android:orientation="horizontal" >  
  7.    
  8.     <LinearLayout  
  9.         android:id="@+id/id_tab_weixin"  
  10.         android:layout_width="0dp"  
  11.         android:layout_height="match_parent"  
  12.         android:layout_weight="1"  
  13.         android:gravity="center"  
  14.         android:orientation="vertical" >  
  15.  <!-- android:clickable="false" 是爲了防止ImageButton截取了觸摸事件 ,這裏事件要給它的上一級linearlayout-->  
  16.         <ImageButton  
  17.              android:id="@+id/id_tab_weixin_img"  
  18.             android:layout_width="wrap_content"  
  19.             android:layout_height="wrap_content"  
  20.             android:background="#00000000"  
  21.             android:clickable="false"  
  22.             android:src="@drawable/tab_weixin_pressed" />  
  23.   
  24.         <TextView  
  25.             android:layout_width="wrap_content"  
  26.             android:layout_height="wrap_content"  
  27.             android:text="微信"  
  28.           />  
  29.     </LinearLayout>  
  30.   
  31.     <LinearLayout  
  32.          android:id="@+id/id_tab_address"  
  33.         android:layout_width="0dp"  
  34.         android:layout_height="match_parent"  
  35.         android:layout_weight="1"  
  36.         android:gravity="center"  
  37.         android:orientation="vertical" >  
  38.   
  39.         <ImageButton  
  40.              android:id="@+id/id_tab_address_img"  
  41.             android:layout_width="wrap_content"  
  42.             android:layout_height="wrap_content"  
  43.             android:background="#00000000"  
  44.              android:clickable="false"  
  45.             android:src="@drawable/tab_address_normal" />  
  46.   
  47.         <TextView  
  48.             android:layout_width="wrap_content"  
  49.             android:layout_height="wrap_content"  
  50.             android:text="通訊錄"  
  51.           />  
  52.     </LinearLayout>  
  53.   
  54.     <LinearLayout  
  55.         android:id="@+id/id_tab_frd"  
  56.         android:layout_width="0dp"  
  57.         android:layout_height="match_parent"  
  58.         android:layout_weight="1"  
  59.         android:gravity="center"  
  60.         android:orientation="vertical" >  
  61.   
  62.         <ImageButton  
  63.              android:id="@+id/id_tab_frd_img"  
  64.             android:layout_width="wrap_content"  
  65.             android:layout_height="wrap_content"  
  66.             android:background="#00000000"  
  67.              android:clickable="false"  
  68.             android:src="@drawable/tab_find_frd_normal" />  
  69.   
  70.         <TextView  
  71.             android:layout_width="wrap_content"  
  72.             android:layout_height="wrap_content"  
  73.             android:text="發現"  
  74.    />  
  75.     </LinearLayout>  
  76.   
  77.     <LinearLayout  
  78.         android:id="@+id/id_tab_settings"  
  79.         android:layout_width="0dp"  
  80.         android:layout_height="match_parent"  
  81.         android:layout_weight="1"  
  82.         android:gravity="center"  
  83.         android:orientation="vertical" >  
  84.   
  85.         <ImageButton  
  86.              android:id="@+id/id_tab_settings_img"  
  87.             android:layout_width="wrap_content"  
  88.             android:layout_height="wrap_content"  
  89.             android:background="#00000000"  
  90.             android:clickable="false"  
  91.             android:src="@drawable/tab_settings_normal" />  
  92.   
  93.         <TextView  
  94.             android:layout_width="wrap_content"  
  95.             android:layout_height="wrap_content"  
  96.             android:text="我"  
  97.             />  
  98.     </LinearLayout>  
  99.   
  100. </LinearLayout>  
效果:


3、整體佈局

將上面兩個加到activity_main.xml中去

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical" >  
  6.   
  7.     <include layout="@layout/top_layout" />  
  8.   
  9.     <android.support.v4.view.ViewPager  
  10.         android:id="@+id/id_viewpage"  
  11.         android:layout_width="fill_parent"  
  12.         android:layout_height="0dp"  
  13.         android:layout_weight="1" >  
  14.     </android.support.v4.view.ViewPager>  
  15. "  
  16.   
  17.     <include layout="@layout/bottom_layout" />  
  18.   
  19. </LinearLayout>  

效果:

效果還可以,底下菜單欄是有背景的,有點兒白色的,所以看得不是很清,一來微信是選中的

4、定義ViewPage的四個佈局

因爲要用ViewPage要加四個page,每個page對應一個xml,所以這裏定義四個xml.

tab01.xml

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:gravity="center"  
  6.     android:orientation="vertical" >  
  7.       <TextView  
  8.         android:layout_width="wrap_content"  
  9.         android:layout_height="wrap_content"  
  10.         android:text="這裏是微信"  
  11.         android:layout_centerVertical="true"  
  12.         android:textColor="#000000"  
  13.         android:textSize="40sp"  
  14.         android:textStyle="bold"  
  15.         />  
  16.   
  17. </LinearLayout>  
效果:


tab02.xml

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:gravity="center"  
  6.     android:orientation="vertical" >  
  7.       <TextView  
  8.         android:layout_width="wrap_content"  
  9.         android:layout_height="wrap_content"  
  10.         android:text="這裏是通訊錄"  
  11.         android:layout_centerVertical="true"  
  12.         android:textColor="#000000"  
  13.         android:textSize="40sp"  
  14.         android:textStyle="bold"  
  15.         />  
  16.   
  17. </LinearLayout>  

效果:效果和上面一樣,只是文字改了一下

tab03.xml

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:gravity="center"  
  6.     android:orientation="vertical" >  
  7.       <TextView  
  8.         android:layout_width="wrap_content"  
  9.         android:layout_height="wrap_content"  
  10.         android:text="這裏是發現"  
  11.         android:layout_centerVertical="true"  
  12.         android:textColor="#000000"  
  13.         android:textSize="40sp"  
  14.         android:textStyle="bold"  
  15.         />  
  16.   
  17. </LinearLayout>  
效果:效果和上面一樣,只是文字改了一下

tab04.xml

[html] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:gravity="center"  
  6.     android:orientation="vertical" >  
  7.       <TextView  
  8.         android:layout_width="wrap_content"  
  9.         android:layout_height="wrap_content"  
  10.         android:text="這裏是我"  
  11.         android:layout_centerVertical="true"  
  12.         android:textColor="#000000"  
  13.         android:textSize="40sp"  
  14.         android:textStyle="bold"  
  15.         />  
  16.   
  17. </LinearLayout>  

效果:效果和上面一樣,只是文字改了一下

二、代碼

1. MainActivity中把控件和ViewPage初始化

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. package com.example.tabexample;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5. import android.os.Bundle;  
  6. import android.app.Activity;  
  7. import android.support.v4.view.PagerAdapter;  
  8. import android.support.v4.view.ViewPager;  
  9. import android.support.v4.view.ViewPager.OnPageChangeListener;  
  10. import android.view.LayoutInflater;  
  11. import android.view.View;  
  12. import android.view.ViewGroup;  
  13. import android.view.Window;  
  14. import android.widget.ImageButton;  
  15. import android.widget.LinearLayout;  
  16.   
  17. public class MainActivity extends Activity implements  
  18.         android.view.View.OnClickListener {  
  19.   
  20.     private ViewPager mViewPager;// 用來放置界面切換  
  21.     private PagerAdapter mPagerAdapter;// 初始化View適配器  
  22.     private List<View> mViews = new ArrayList<View>();// 用來存放Tab01-04  
  23.     // 四個Tab,每個Tab包含一個按鈕  
  24.     private LinearLayout mTabWeiXin;  
  25.     private LinearLayout mTabAddress;  
  26.     private LinearLayout mTabFrd;  
  27.     private LinearLayout mTabSetting;  
  28.     // 四個按鈕  
  29.     private ImageButton mWeiXinImg;  
  30.     private ImageButton mAddressImg;  
  31.     private ImageButton mFrdImg;  
  32.     private ImageButton mSettingImg;  
  33.   
  34.     @Override  
  35.     protected void onCreate(Bundle savedInstanceState) {  
  36.         super.onCreate(savedInstanceState);  
  37.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  38.         setContentView(R.layout.activity_main);  
  39.         initView();  
  40.         initViewPage();  
  41.         initEvent();  
  42.     }  
  43.   
  44.     private void initEvent() {  
  45.         mTabWeiXin.setOnClickListener(this);  
  46.         mTabAddress.setOnClickListener(this);  
  47.         mTabFrd.setOnClickListener(this);  
  48.         mTabSetting.setOnClickListener(this);  
  49.         mViewPager.setOnPageChangeListener(new OnPageChangeListener() {  
  50.             /** 
  51.             *ViewPage左右滑動時 
  52.             */  
  53.             @Override  
  54.             public void onPageSelected(int arg0) {  
  55.                 int currentItem = mViewPager.getCurrentItem();  
  56.                 switch (currentItem) {  
  57.                 case 0:  
  58.                      resetImg();  
  59.                     mWeiXinImg.setImageResource(R.drawable.tab_weixin_pressed);  
  60.                     break;  
  61.                 case 1:  
  62.                      resetImg();  
  63.                     mAddressImg.setImageResource(R.drawable.tab_address_pressed);  
  64.                     break;  
  65.                 case 2:  
  66.                      resetImg();  
  67.                     mFrdImg.setImageResource(R.drawable.tab_find_frd_pressed);  
  68.                     break;  
  69.                 case 3:  
  70.                      resetImg();  
  71.                     mSettingImg.setImageResource(R.drawable.tab_settings_pressed);  
  72.                     break;  
  73.                 default:  
  74.                     break;  
  75.                 }  
  76.             }  
  77.   
  78.             @Override  
  79.             public void onPageScrolled(int arg0, float arg1, int arg2) {  
  80.   
  81.             }  
  82.   
  83.             @Override  
  84.             public void onPageScrollStateChanged(int arg0) {  
  85.   
  86.             }  
  87.         });  
  88.     }  
  89.   
  90.     /** 
  91.      * 初始化設置 
  92.      */  
  93.     private void initView() {  
  94.         mViewPager = (ViewPager) findViewById(R.id.id_viewpage);  
  95.         // 初始化四個LinearLayout  
  96.         mTabWeiXin = (LinearLayout) findViewById(R.id.id_tab_weixin);  
  97.         mTabAddress = (LinearLayout) findViewById(R.id.id_tab_address);  
  98.         mTabFrd = (LinearLayout) findViewById(R.id.id_tab_frd);  
  99.         mTabSetting = (LinearLayout) findViewById(R.id.id_tab_settings);  
  100.         // 初始化四個按鈕  
  101.         mWeiXinImg = (ImageButton) findViewById(R.id.id_tab_weixin_img);  
  102.         mAddressImg = (ImageButton) findViewById(R.id.id_tab_address_img);  
  103.         mFrdImg = (ImageButton) findViewById(R.id.id_tab_frd_img);  
  104.         mSettingImg = (ImageButton) findViewById(R.id.id_tab_settings_img);  
  105.     }  
  106.   
  107.     /** 
  108.      * 初始化ViewPage 
  109.      */  
  110.     private void initViewPage() {  
  111.   
  112.         // 初媽化四個佈局  
  113.         LayoutInflater mLayoutInflater = LayoutInflater.from(this);  
  114.         View tab01 = mLayoutInflater.inflate(R.layout.tab01, null);  
  115.         View tab02 = mLayoutInflater.inflate(R.layout.tab02, null);  
  116.         View tab03 = mLayoutInflater.inflate(R.layout.tab03, null);  
  117.         View tab04 = mLayoutInflater.inflate(R.layout.tab04, null);  
  118.   
  119.         mViews.add(tab01);  
  120.         mViews.add(tab02);  
  121.         mViews.add(tab03);  
  122.         mViews.add(tab04);  
  123.   
  124.         // 適配器初始化並設置  
  125.         mPagerAdapter = new PagerAdapter() {  
  126.   
  127.             @Override  
  128.             public void destroyItem(ViewGroup container, int position,  
  129.                     Object object) {  
  130.                 container.removeView(mViews.get(position));  
  131.   
  132.             }  
  133.   
  134.             @Override  
  135.             public Object instantiateItem(ViewGroup container, int position) {  
  136.                 View view = mViews.get(position);  
  137.                 container.addView(view);  
  138.                 return view;  
  139.             }  
  140.   
  141.             @Override  
  142.             public boolean isViewFromObject(View arg0, Object arg1) {  
  143.   
  144.                 return arg0 == arg1;  
  145.             }  
  146.   
  147.             @Override  
  148.             public int getCount() {  
  149.   
  150.                 return mViews.size();  
  151.             }  
  152.         };  
  153.         mViewPager.setAdapter(mPagerAdapter);  
  154.     }  
  155.   
  156.     /** 
  157.      * 判斷哪個要顯示,及設置按鈕圖片 
  158.      */  
  159.     @Override  
  160.     public void onClick(View arg0) {  
  161.   
  162.         switch (arg0.getId()) {  
  163.         case R.id.id_tab_weixin:  
  164.             mViewPager.setCurrentItem(0);  
  165.             resetImg();  
  166.             mWeiXinImg.setImageResource(R.drawable.tab_weixin_pressed);  
  167.             break;  
  168.         case R.id.id_tab_address:  
  169.             mViewPager.setCurrentItem(1);  
  170.             resetImg();  
  171.             mAddressImg.setImageResource(R.drawable.tab_address_pressed);  
  172.             break;  
  173.         case R.id.id_tab_frd:  
  174.             mViewPager.setCurrentItem(2);  
  175.             resetImg();  
  176.             mFrdImg.setImageResource(R.drawable.tab_find_frd_pressed);  
  177.             break;  
  178.         case R.id.id_tab_settings:  
  179.             mViewPager.setCurrentItem(3);  
  180.             resetImg();  
  181.             mSettingImg.setImageResource(R.drawable.tab_settings_pressed);  
  182.             break;  
  183.         default:  
  184.             break;  
  185.         }  
  186.     }  
  187.   
  188.     /** 
  189.      * 把所有圖片變暗 
  190.      */  
  191.     private void resetImg() {  
  192.         mWeiXinImg.setImageResource(R.drawable.tab_weixin_normal);  
  193.         mAddressImg.setImageResource(R.drawable.tab_address_normal);  
  194.         mFrdImg.setImageResource(R.drawable.tab_find_frd_normal);  
  195.         mSettingImg.setImageResource(R.drawable.tab_settings_normal);  
  196.     }  
  197.   
  198. }  
代碼量很短,只有幾百行,功能就可以實現了,注意這裏去掉程序原本的標題欄我直接用了
[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. requestWindowFeature(Window.FEATURE_NO_TITLE);  

2、效果:



三、思路說明

1、分別爲頂部菜單欄和底部菜單欄新建一個佈局

2、中間是ViewPage,然後裏面放四個Page(tab01-tab04.xml),注意,要通過適配器給ViewPage提供內容.

3、監聽ViewPage和底部菜單欄按鈕的事件(注意,這裏的按鈕放在一個LinearLayout中,所以我們監聽了LinearLayout的觸摸事件,而屏蔽了Imgaebutton的觸摸事件)

4、

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. public void onClick(View arg0)  
這裏面監聽的是底部菜單的觸摸事件,根據觸摸的控件,改變自身的亮度、改變ViewPage顯示的內容

[java] view plaincopy在CODE上查看代碼片派生到我的代碼片
  1. mViewPager.setOnPageChangeListener(new OnPageChangeListener()   

這裏監聽的是ViewPage左右滑動的事件,改變相應控件的亮度、改變ViewPage顯示的內容

四、不足之處

1、最新版微信上應該是左右滑動是有部分亮度變化的,這裏直接轉變過去了。

2、最新版微信文字也要跟着變化,這裏沒做改變


            林炳文Evankaka原創作品。轉載請註明出處http://blog.csdn.net/evankaka

發佈了54 篇原創文章 · 獲贊 7 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章