国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

安卓開發筆記——多種方式實現底部菜單欄(仿微信界面)

2019-11-14 23:53:59
字體:
來源:轉載
供稿:網友
安卓開發筆記——多種方式實現底部菜單欄(仿微信界面)

關于底部菜單是什么,我想沒必要介紹了,在市場上的APP里太常見了,這里提供兩種方式來實現。

記得之前寫過幾篇關于底部菜單實現的方法,有興趣的朋友可以看看:

1、《安卓開發復習筆記——TabHost組件(一)(實現底部菜單導航)》

2、《安卓開發復習筆記——TabHost組件(二)(實現底部菜單導航)》

3、《安卓開發筆記——Fragment+FragmentTabHost組件(實現新浪微博底部菜單)》

今天帶來種相對更通俗易懂的寫法,不再和過去一樣去沿用TabHost了,這次我們直接用LinearLayout布局來實現,先來看下實現效果圖:

中間內容區域有兩種實現方式:

1、ViewPager  --可滑動界面      2、Fragment  --固定界面

1、界面分析

這里有個小技巧,把底部菜單欄的每一個小的LinearLayout的寬度都設置成0dp,然后用weight權重去分配它,中間內容區域也是把高度設置成0dp,然后用weight權重去分配它。(weight默認是把界面里空閑的位置作為劃分位置,所以這里的寬度或者高度要注意設置成0dp)

2、具體實現(內容區域為ViewPager可滑動界面)

布局文件:

activity_top.xml(頂部布局)

 1 <RelativeLayout 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="55dp" 5     android:background="@drawable/title_bar"> 6  7     <TextView 8         android:layout_width="wrap_content" 9         android:layout_height="wrap_content"10         android:layout_centerInParent="true"11         android:text="微信"12         android:textSize="20dp" 13         android:textColor="#ffffff"/>14 15 </RelativeLayout>
View Code

activity_bottom.xml(底部布局)

  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="wrap_content"  5     android:background="@drawable/bottom_bar" >  6   7     <LinearLayout  8         android:id="@+id/ll_home"  9         android:layout_width="0dp" 10         android:layout_height="wrap_content" 11         android:layout_weight="1" 12         android:gravity="center" 13         android:orientation="vertical" > 14  15         <ImageView 16             android:id="@+id/iv_home" 17             android:layout_width="wrap_content" 18             android:layout_height="wrap_content" 19             android:src="@drawable/tab_weixin_View Code

activity_main.xml(主布局,引入上下布局)

 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/activity_top" /> 8  9     <android.support.v4.view.ViewPager10         android:id="@+id/vp_content"11         android:layout_width="match_parent"12         android:background="#ffffff"13         android:layout_height="0dp"14         android:layout_weight="1" >15     </android.support.v4.view.ViewPager>16 17     <include layout="@layout/activity_bottom" />18 19 </LinearLayout>
View Code

page_01.xml-page_04.xml(4個ViewPager的滑動界面,由于內容簡單這里只給出其中1個)

 1 <RelativeLayout 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  6     <TextView 7         android:layout_width="wrap_content" 8         android:layout_height="wrap_content" 9         android:layout_centerInParent="true"10         android:text="我是微信首頁"11         android:textSize="30dp" />12 13 </RelativeLayout>
View Code

具體實現代碼:

ViewPager適配器(關于ViewPager的使用方法這里就不多說了,不清楚的朋友看我這篇文章吧《安卓開發筆記——ViewPager組件(仿微信引導界面)》)

 1 package com.rabbit.tabdemo; 2  3 import java.util.List; 4  5 import android.support.v4.view.PagerAdapter; 6 import android.view.View; 7 import android.view.ViewGroup; 8 /** 9  * ViewPager適配器10  * @author Balla_兔子11  *12  */13 public class ContentAdapter extends PagerAdapter {14 15     private List<View> views;16 17     public ContentAdapter(List<View> views) {18         this.views = views;19     }20 21     @Override22     public int getCount() {23         return views.size();24     }25 26     @Override27     public boolean isViewFromObject(View arg0, Object arg1) {28         return arg0 == arg1;29     }30 31     @Override32     public Object instantiateItem(ViewGroup container, int position) {33         View view = views.get(position);34         container.addView(view);35         return view;36     }37 38     @Override39     public void destroyItem(ViewGroup container, int position, Object object) {40         container.removeView(views.get(position));41     }42 43 }

MainActivity(主界面代碼)

初始化控件后,完成對底部菜單的4個LinearLayout的點擊監聽事件,在用戶觸發點擊事件的時候,設置選擇狀態然后跳轉相對應的界面。為了使得滑動ViewPager也能同時觸發底部菜單狀態的改變,這里也對ViewPager設置了滑動監聽。其他的代碼注釋很全,看注釋就可以了。

  1 package com.rabbit.tabdemo;  2   3 import java.util.ArrayList;  4 import java.util.List;  5   6 import android.app.Activity;  7 import android.os.Bundle;  8 import android.support.v4.view.ViewPager;  9 import android.support.v4.view.ViewPager.OnPageChangeListener; 10 import android.view.View; 11 import android.view.View.OnClickListener; 12 import android.widget.ImageView; 13 import android.widget.LinearLayout; 14 import android.widget.TextView; 15  16 public class MainActivity extends Activity implements OnClickListener,OnPageChangeListener{ 17  18     // 底部菜單4個Linearlayout 19     private LinearLayout ll_home; 20     private LinearLayout ll_address; 21     private LinearLayout ll_friend; 22     private LinearLayout ll_setting; 23  24     // 底部菜單4個ImageView 25     private ImageView iv_home; 26     private ImageView iv_address; 27     private ImageView iv_friend; 28     private ImageView iv_setting; 29  30     // 底部菜單4個菜單標題 31     private TextView tv_home; 32     private TextView tv_address; 33     private TextView tv_friend; 34     private TextView tv_setting; 35  36     // 中間內容區域 37     private ViewPager viewPager; 38  39     // ViewPager適配器ContentAdapter 40     private ContentAdapter adapter; 41  42     private List<View> views; 43  44     @Override 45     protected void onCreate(Bundle savedInstanceState) { 46         super.onCreate(savedInstanceState); 47         setContentView(R.layout.activity_main); 48  49         // 初始化控件 50         initView(); 51         // 初始化底部按鈕事件 52         initEvent(); 53  54     } 55  56     private void initEvent() { 57         // 設置按鈕監聽 58         ll_home.setOnClickListener(this); 59         ll_address.setOnClickListener(this); 60         ll_friend.setOnClickListener(this); 61         ll_setting.setOnClickListener(this); 62          63         //設置ViewPager滑動監聽 64         viewPager.setOnPageChangeListener(this); 65     } 66  67     private void initView() { 68  69         // 底部菜單4個Linearlayout 70         this.ll_home = (LinearLayout) findViewById(R.id.ll_home); 71         this.ll_address = (LinearLayout) findViewById(R.id.ll_address); 72         this.ll_friend = (LinearLayout) findViewById(R.id.ll_friend); 73         this.ll_setting = (LinearLayout) findViewById(R.id.ll_setting); 74  75         // 底部菜單4個ImageView 76         this.iv_home = (ImageView) findViewById(R.id.iv_home); 77         this.iv_address = (ImageView) findViewById(R.id.iv_address); 78         this.iv_friend = (ImageView) findViewById(R.id.iv_friend); 79         this.iv_setting = (ImageView) findViewById(R.id.iv_setting); 80  81         // 底部菜單4個菜單標題 82         this.tv_home = (TextView) findViewById(R.id.tv_home); 83         this.tv_address = (TextView) findViewById(R.id.tv_address); 84         this.tv_friend = (TextView) findViewById(R.id.tv_friend); 85         this.tv_setting = (TextView) findViewById(R.id.tv_setting); 86  87         // 中間內容區域ViewPager 88         this.viewPager = (ViewPager) findViewById(R.id.vp_content); 89  90         // 適配器 91         View page_01 = View.inflate(MainActivity.this, R.layout.page_01, null); 92         View page_02 = View.inflate(MainActivity.this, R.layout.page_02, null); 93         View page_03 = View.inflate(MainActivity.this, R.layout.page_03, null); 94         View page_04 = View.inflate(MainActivity.this, R.layout.page_04, null); 95  96         views = new ArrayList<View>(); 97         views.add(page_01); 98         views.add(page_02); 99         views.add(page_03);100         views.add(page_04);101 102         this.adapter = new ContentAdapter(views);103         viewPager.setAdapter(adapter);104 105     }106 107     @Override108     public void onClick(View v) {109         // 在每次點擊后將所有的底部按鈕(ImageView,TextView)顏色改為灰色,然后根據點擊著色110         restartBotton();111         // ImageView和TetxView置為綠色,頁面隨之跳轉112         switch (v.getId()) {113         case R.id.ll_home:114             iv_home.setImageResource(R.drawable.tab_weixin_pressed);115             tv_home.setTextColor(0xff1B940A);116             viewPager.setCurrentItem(0);117             break;118         case R.id.ll_address:119             iv_address.setImageResource(R.drawable.tab_address_pressed);120             tv_address.setTextColor(0xff1B940A);121             viewPager.setCurrentItem(1);122             break;123         case R.id.ll_friend:124             iv_friend.setImageResource(R.drawable.tab_find_frd_pressed);125             tv_friend.setTextColor(0xff1B940A);126             viewPager.setCurrentItem(2);127             break;128         case R.id.ll_setting:129             iv_setting.setImageResource(R.drawable.tab_find_frd_pressed);130             tv_setting.setTextColor(0xff1B940A);131             viewPager.setCurrentItem(3);132             break;133 134         default:135             break;136         }137 138     }139 140     private void restartBotton() {141         // ImageView置為灰色142         iv_home.setImageResource(R.drawable.tab_weixin_normal);143         iv_address.setImageResource(R.drawable.tab_address_normal);144         iv_friend.setImageResource(R.drawable.tab_find_frd_normal);145         iv_setting.setImageResource(R.drawable.tab_settings_normal);146         // TextView置為白色147         tv_home.setTextColor(0xffffffff);148         tv_address.setTextColor(0xffffffff);149         tv_friend.setTextColor(0xffffffff);150         tv_setting.setTextColor(0xffffffff);151     }152 153     @Override154     public void onPageScrollStateChanged(int arg0) {155         156     }157 158     @Override159     public void onPageScrolled(int arg0, float arg1, int arg2) {160         161     }162 163     @Override164     public void onPageSelected(int arg0) {165         restartBotton();166         //當前view被選擇的時候,改變底部菜單圖片,文字顏色167         switch (arg0) {168         case 0:169             iv_home.setImageResource(R.drawable.tab_weixin_pressed);170             tv_home.setTextColor(0xff1B940A);171             break;172         case 1:173             iv_address.setImageResource(R.drawable.tab_address_pressed);174             tv_address.setTextColor(0xff1B940A);175             break;176         case 2:177             iv_friend.setImageResource(R.drawable.tab_find_frd_pressed);178             tv_friend.setTextColor(0xff1B940A);179             break;180         case 3:181             iv_setting.setImageResource(R.drawable.tab_find_frd_pressed);182             tv_setting.setTextColor(0xff1B940A);183             break;184 185         default:186             break;187         }188         189     }190 191 }

3、具體實現(內容區域為Fragment固定界面)

布局文件:

布局文件基本沒變化,只是把主界面的ViewPager改成了FramLayout,其他文件保持一致,就不貼出來了。

 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/activity_top" /> 8  9     <FrameLayout10         android:id="@+id/fl_content"11         android:layout_width="match_parent"12         android:background="#ffffff"13         android:layout_height="0dp"14         android:layout_weight="1" >15     </FrameLayout>16 17     <include layout="@layout/activity_bottom" />18 19 </LinearLayout>
View Code

具體實現代碼:

由于這次的內容是基于Fragment的,所以需要有4個Fragment文件,由于代碼相同這里只貼出一個。

Frgament(HomeFragment,AddressFragment,FriendFragment,SettingFragment)

 1 package com.rabbit.tabdemo; 2  3 import android.os.Bundle; 4 import android.support.annotation.Nullable; 5 import android.support.v4.app.Fragment; 6 import android.view.LayoutInflater; 7 import android.view.View; 8 import android.view.ViewGroup; 9 10 public class HomeFragment extends Fragment {11     @Override12     public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {13         return inflater.inflate(R.layout.page_01, container, false);14     }15 16 }
View Code

MainActivity(主界面代碼)

代碼很簡單,一看就能明白就不多說什么了,只提個需要注意的地方,由于便于向下兼容這里的Fragment是用V4包下的,在導入包的時候需要注意一下。

  1 package com.rabbit.tabdemo;  2   3 import android.os.Bundle;  4 import android.support.v4.app.Fragment;  5 import android.support.v4.app.FragmentActivity;  6 import android.support.v4.app.FragmentManager;  7 import android.support.v4.app.FragmentTransaction;  8 import android.view.View;  9 import android.view.View.OnClickListener; 10 import android.widget.ImageView; 11 import android.widget.LinearLayout; 12 import android.widget.TextView; 13  14 public class MainActivity extends FragmentActivity implements OnClickListener { 15     // 底部菜單4個Linearlayout 16     private LinearLayout ll_home; 17     private LinearLayout ll_address; 18     private LinearLayout ll_friend; 19     private LinearLayout ll_setting; 20  21     // 底部菜單4個ImageView 22     private ImageView iv_home; 23     private ImageView iv_address; 24     private ImageView iv_friend; 25     private ImageView iv_setting; 26  27     // 底部菜單4個菜單標題 28     private TextView tv_home; 29     private TextView tv_address; 30     private TextView tv_friend; 31     private TextView tv_setting; 32  33     // 4個Fragment 34     private Fragment homeFragment; 35     private Fragment addressFragment; 36     private Fragment friendFragment; 37     private Fragment settingFragment; 38  39     @Override 40     protected void onCreate(Bundle savedInstanceState) { 41         super.onCreate(savedInstanceState); 42         setContentView(R.layout.activity_main); 43  44         // 初始化控件 45         initView(); 46         // 初始化底部按鈕事件 47         initEvent(); 48         // 初始化并設置當前Fragment 49         initFragment(0); 50  51     } 52  53     private void initFragment(int index) { 54         // 由于是引用了V4包下的Fragment,所以這里的管理器要用getSupportFragmentManager獲取 55         FragmentManager fragmentManager = getSupportFragmentManager(); 56         // 開啟事務 57         FragmentTransaction transaction = fragmentManager.beginTransaction(); 58         // 隱藏所有Fragment 59         hideFragment(transaction); 60         switch (index) { 61         case 0: 62             if (homeFragment == null) { 63                 homeFragment = new HomeFragment(); 64                 transaction.add(R.id.fl_content, homeFragment); 65             } else { 66                 transaction.show(homeFragment); 67             } 68             break; 69         case 1: 70             if (addressFragment == null) { 71                 addressFragment = new AddressFragment(); 72                 transaction.add(R.id.fl_content, addressFragment); 73             } else { 74                 transaction.show(addressFragment); 75             } 76  77             break; 78         case 2: 79             if (friendFragment == null) { 80                 friendFragment = new FriendFragment(); 81                 transaction.add(R.id.fl_content, friendFragment); 82             } else { 83                 transaction.show(friendFragment); 84             } 85  86             break; 87         case 3: 88             if (settingFragment == null) { 89                 settingFragment = new SettingFragment(); 90                 transaction.add(R.id.fl_content, settingFragment); 91             } else { 92                 transaction.show(settingFragment); 93             } 94  95             break; 96  97         default: 98             break; 99         }100 101         // 提交事務102         transaction.commit();103 104     }105 106     //隱藏Fragment107     private void hideFragment(FragmentTransaction transaction) {108         if (homeFragment != null) {109             transaction.hide(homeFragment);110         }111         if (addressFragment != null) {112             transaction.hide(addressFragment);113         }114         if (friendFragment != null) {115             transaction.hide(friendFragment);116         }117         if (settingFragment != null) {118             transaction.hide(settingFragment);119         }120 121     }122 123     private void initEvent() {124         // 設置按鈕監聽125         ll_home.setOnClickListener(this);126         ll_address.setOnClickListener(this);127         ll_friend.setOnClickListener(this);128         ll_setting.setOnClickListener(this);129 130     }131 132     private void initView() {133 134         // 底部菜單4個Linearlayout135         this.ll_home = (LinearLayout) findViewById(R.id.ll_home);136         this.ll_address = (LinearLayout) findViewById(R.id.ll_address);137         this.ll_friend = (LinearLayout) findViewById(R.id.ll_friend);138         this.ll_setting = (LinearLayout) findViewById(R.id.ll_setting);139 140         // 底部菜單4個ImageView141         this.iv_home = (ImageView) findViewById(R.id.iv_home);142         this.iv_address = (ImageView) findViewById(R.id.iv_address);143         this.iv_friend = (ImageView) findViewById(R.id.iv_friend);144         this.iv_setting = (ImageView) findViewById(R.id.iv_setting);145 146         // 底部菜單4個菜單標題147         this.tv_home = (TextView) findViewById(R.id.tv_home);148         this.tv_address = (TextView) findViewById(R.id.tv_address);149         this.tv_friend = (TextView) findViewById(R.id.tv_friend);150         this.tv_setting = (TextView) findViewById(R.id.tv_setting);151 152     }153 154     @Override155     public void onClick(View v) {156 157         // 在每次點擊后將所有的底部按鈕(ImageView,TextView)顏色改為灰色,然后根據點擊著色158         restartBotton();159         // ImageView和TetxView置為綠色,頁面隨之跳轉160         switch (v.getId()) {161         case R.id.ll_home:162             iv_home.setImageResource(R.drawable.tab_weixin_pressed);163             tv_home.setTextColor(0xff1B940A);164             initFragment(0);165             break;166         case R.id.ll_address:167             iv_address.setImageResource(R.drawable.tab_address_pressed);168             tv_address.setTextColor(0xff1B940A);169             initFragment(1);170             break;171         case R.id.ll_friend:172             iv_friend.setImageResource(R.drawable.tab_find_frd_pressed);173             tv_friend.setTextColor(0xff1B940A);174             initFragment(2);175             break;176         case R.id.ll_setting:177             iv_setting.setImageResource(R.drawable.tab_find_frd_pressed);178             tv_setting.setTextColor(0xff1B940A);179             initFragment(3);180             break;181 182         default:183             break;184         }185 186     }187 188     private void restartBotton() {189         // ImageView置為灰色190         iv_home.setImageResource(R.drawable.tab_weixin_normal);191         iv_address.setImageResource(R.drawable.tab_address_normal);192         iv_friend.setImageResource(R.drawable.tab_find_frd_normal);193         iv_setting.setImageResource(R.drawable.tab_settings_normal);194         // TextView置為白色195         tv_home.setTextColor(0xffffffff);196         tv_address.setTextColor(0xffffffff);197         tv_friend.setTextColor(0xffffffff);198         tv_setting.setTextColor(0xffffffff);199     }200 201 }

到這里界面效果就基本實現了,就算是旋轉屏幕也能夠很好的達到適配效果,最后我們還需要做的2點,可能有些朋友已經發現了,在我們旋轉屏幕的時候,Fragment會重新調用onCreate方法,導致成員變量重新初始化了一次,Fragment對象也重置為空,然后就調用不到hide方法,從而出現了界面重復疊加的情況。

下面提供解決的方法,其實很簡單,只需要在AndroidManifest.xml里面對應的activity里添設置改換屏幕方向等操作時不觸發oncreate事件就可以。

1  android:configChanges="orientation|keyboardHidden|screenSize" 

最后我們隱藏下標題欄,在application里添加上:

1  android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" 

這樣就大功告成了!

總結:

基于ViewPager實現的內容:

優點:

1、界面可以滑動,美觀,流暢。

缺點:

1、當界面里有一些需要用手勢來實現的內容會起沖突,比如我們ListView里的側滑刪除。

2、由于采用的是ViewPager,所以頁面內容實現代碼會嚴重依賴于MainActivity,代碼太過冗余,不便于后期維護。

基于Fragment實現的內容:

優點:

1、Fragment文件單獨存在,各自頁面的內容各自去實現完成,有自己的生命周期,便于后期維護。

2、對于需要手勢操作的一些內容不會起沖突。

缺點:

1、界面不可滑動,比較死板。

補充:如果既想有ViewPager的滑動效果,又想ViewPager的頁卡里嵌套Fragment,可以使用FragmentPagerAdapter作為適配器,但需要注意Fragment生命周期的管理。

作者:Balla_兔子出處:http://m.survivalescaperooms.com/lichenwei/本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。正在看本人博客的這位童鞋,我看你氣度不凡,談吐間隱隱有王者之氣,日后必有一番作為!旁邊有“推薦”二字,你就順手把它點了吧,相得準,我分文不收;相不準,你也好回來找我!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 拉萨市| 武城县| 科技| 习水县| 新建县| 定安县| 通化市| 刚察县| 永年县| 长武县| 神木县| 嘉义市| 江口县| 龙南县| 汉沽区| 莱阳市| 当涂县| 万全县| 邵阳市| 五河县| 三台县| 大城县| 昌黎县| 长岛县| 剑阁县| 清涧县| 麦盖提县| 平果县| 登封市| 威远县| 隆安县| 阳春市| 叙永县| 大冶市| 介休市| 唐山市| 雷山县| 进贤县| 剑川县| 静宁县| 山东|