安卓开发笔记——多种方式实现底部菜单栏(仿微信界面)
2015-04-21 18:42
567 查看
关于底部菜单是什么,我想没必要介绍了,在市场上的APP里太常见了,这里提供两种方式来实现。
记得之前写过几篇关于底部菜单实现的方法,有兴趣的朋友可以看看:
1、《安卓开发复习笔记——TabHost组件(一)(实现底部菜单导航)》
2、《安卓开发复习笔记——TabHost组件(二)(实现底部菜单导航)》
3、《安卓开发笔记——Fragment+FragmentTabHost组件(实现新浪微博底部菜单)》
今天带来种相对更通俗易懂的写法,不再和过去一样去沿用TabHost了,这次我们直接用LinearLayout布局来实现,先来看下实现效果图:
中间内容区域有两种实现方式:
1、ViewPager --可滑动界面 2、Fragment --固定界面
View Code
MainActivity(主界面代码)
代码很简单,一看就能明白就不多说什么了,只提个需要注意的地方,由于便于向下兼容这里的Fragment是用V4包下的,在导入包的时候需要注意一下。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/04/d40ce9b9fe7d67ae12ebb8f32d39aea5.jpg)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/04/04937f693fa6c5bb15ddc95bf06e9f50.jpg)
到这里界面效果就基本实现了,就算是旋转屏幕也能够很好的达到适配效果,最后我们还需要做的2点,可能有些朋友已经发现了,在我们旋转屏幕的时候,Fragment会重新调用onCreate方法,导致成员变量重新初始化了一次,Fragment对象也重置为空,然后就调用不到hide方法,从而出现了界面重复叠加的情况。
下面提供解决的方法,其实很简单,只需要在AndroidManifest.xml里面对应的activity里添设置改换屏幕方向等操作时不触发oncreate事件就可以。
最后我们隐藏下标题栏,在application里添加上:
这样就大功告成了!
总结:
基于ViewPager实现的内容:
优点:
1、界面可以滑动,美观,流畅。
缺点:
1、当界面里有一些需要用手势来实现的内容会起冲突,比如我们ListView里的侧滑删除。
2、由于采用的是ViewPager,所以页面内容实现代码会严重依赖于MainActivity,代码太过冗余,不便于后期维护。
基于Fragment实现的内容:
优点:
1、Fragment文件单独存在,各自页面的内容各自去实现完成,有自己的生命周期,便于后期维护。
2、对于需要手势操作的一些内容不会起冲突。
缺点:
1、界面不可滑动,比较死板。
补充:如果既想有ViewPager的滑动效果,又想ViewPager的页卡里嵌套Fragment,可以使用FragmentPagerAdapter作为适配器,但需要注意Fragment生命周期的管理。
作者:Balla_兔子
出处:http://www.cnblogs.com/lichenwei/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
正在看本人博客的这位童鞋,我看你气度不凡,谈吐间隐隐有王者之气,日后必有一番作为!旁边有“推荐”二字,你就顺手把它点了吧,相得准,我分文不收;相不准,你也好回来找我!
记得之前写过几篇关于底部菜单实现的方法,有兴趣的朋友可以看看:
1、《安卓开发复习笔记——TabHost组件(一)(实现底部菜单导航)》
2、《安卓开发复习笔记——TabHost组件(二)(实现底部菜单导航)》
3、《安卓开发笔记——Fragment+FragmentTabHost组件(实现新浪微博底部菜单)》
今天带来种相对更通俗易懂的写法,不再和过去一样去沿用TabHost了,这次我们直接用LinearLayout布局来实现,先来看下实现效果图:
中间内容区域有两种实现方式:
1、ViewPager --可滑动界面 2、Fragment --固定界面
package com.rabbit.tabdemo; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class HomeFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { return inflater.inflate(R.layout.page_01, container, false); } }
View Code
MainActivity(主界面代码)
代码很简单,一看就能明白就不多说什么了,只提个需要注意的地方,由于便于向下兼容这里的Fragment是用V4包下的,在导入包的时候需要注意一下。
package com.rabbit.tabdemo; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentTransaction; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; public class MainActivity extends FragmentActivity implements OnClickListener { // 底部菜单4个Linearlayout private LinearLayout ll_home; private LinearLayout ll_address; private LinearLayout ll_friend; private LinearLayout ll_setting; // 底部菜单4个ImageView private ImageView iv_home; private ImageView iv_address; private ImageView iv_friend; private ImageView iv_setting; // 底部菜单4个菜单标题 private TextView tv_home; private TextView tv_address; private TextView tv_friend; private TextView tv_setting; // 4个Fragment private Fragment homeFragment; private Fragment addressFragment; private Fragment friendFragment; private Fragment settingFragment; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 初始化控件 initView(); // 初始化底部按钮事件 initEvent(); // 初始化并设置当前Fragment initFragment(0); } private void initFragment(int index) { // 由于是引用了V4包下的Fragment,所以这里的管理器要用getSupportFragmentManager获取 FragmentManager fragmentManager = getSupportFragmentManager(); // 开启事务 FragmentTransaction transaction = fragmentManager.beginTransaction(); // 隐藏所有Fragment hideFragment(transaction); switch (index) { case 0: if (homeFragment == null) { homeFragment = new HomeFragment(); transaction.add(R.id.fl_content, homeFragment); } else { transaction.show(homeFragment); } break; case 1: if (addressFragment == null) { addressFragment = new AddressFragment(); transaction.add(R.id.fl_content, addressFragment); } else { transaction.show(addressFragment); } break; case 2: if (friendFragment == null) { friendFragment = new FriendFragment(); transaction.add(R.id.fl_content, friendFragment); } else { transaction.show(friendFragment); } break; case 3: if (settingFragment == null) { settingFragment = new SettingFragment(); transaction.add(R.id.fl_content, settingFragment); } else { transaction.show(settingFragment); } break; default: break; } // 提交事务 transaction.commit(); } //隐藏Fragment private void hideFragment(FragmentTransaction transaction) { if (homeFragment != null) { transaction.hide(homeFragment); } if (addressFragment != null) { transaction.hide(addressFragment); } if (friendFragment != null) { transaction.hide(friendFragment); } if (settingFragment != null) { transaction.hide(settingFragment); } } private void initEvent() { // 设置按钮监听 ll_home.setOnClickListener(this); ll_address.setOnClickListener(this); ll_friend.setOnClickListener(this); ll_setting.setOnClickListener(this); } private void initView() { // 底部菜单4个Linearlayout this.ll_home = (LinearLayout) findViewById(R.id.ll_home); this.ll_address = (LinearLayout) findViewById(R.id.ll_address); this.ll_friend = (LinearLayout) findViewById(R.id.ll_friend); this.ll_setting = (LinearLayout) findViewById(R.id.ll_setting); // 底部菜单4个ImageView this.iv_home = (ImageView) findViewById(R.id.iv_home); this.iv_address = (ImageView) findViewById(R.id.iv_address); this.iv_friend = (ImageView) findViewById(R.id.iv_friend); this.iv_setting = (ImageView) findViewById(R.id.iv_setting); // 底部菜单4个菜单标题 this.tv_home = (TextView) findViewById(R.id.tv_home); this.tv_address = (TextView) findViewById(R.id.tv_address); this.tv_friend = (TextView) findViewById(R.id.tv_friend); this.tv_setting = (TextView) findViewById(R.id.tv_setting); } @Override public void onClick(View v) { // 在每次点击后将所有的底部按钮(ImageView,TextView)颜色改为灰色,然后根据点击着色 restartBotton(); // ImageView和TetxView置为绿色,页面随之跳转 switch (v.getId()) { case R.id.ll_home: iv_home.setImageResource(R.drawable.tab_weixin_pressed); tv_home.setTextColor(0xff1B940A); initFragment(0); break; case R.id.ll_address: iv_address.setImageResource(R.drawable.tab_address_pressed); tv_address.setTextColor(0xff1B940A); initFragment(1); break; case R.id.ll_friend: iv_friend.setImageResource(R.drawable.tab_find_frd_pressed); tv_friend.setTextColor(0xff1B940A); initFragment(2); break; case R.id.ll_setting: iv_setting.setImageResource(R.drawable.tab_find_frd_pressed); tv_setting.setTextColor(0xff1B940A); initFragment(3); break; default: break; } } private void restartBotton() { // ImageView置为灰色 iv_home.setImageResource(R.drawable.tab_weixin_normal); iv_address.setImageResource(R.drawable.tab_address_normal); iv_friend.setImageResource(R.drawable.tab_find_frd_normal); iv_setting.setImageResource(R.drawable.tab_settings_normal); // TextView置为白色 tv_home.setTextColor(0xffffffff); tv_address.setTextColor(0xffffffff); tv_friend.setTextColor(0xffffffff); tv_setting.setTextColor(0xffffffff); } }
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/04/d40ce9b9fe7d67ae12ebb8f32d39aea5.jpg)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202004/04/04937f693fa6c5bb15ddc95bf06e9f50.jpg)
到这里界面效果就基本实现了,就算是旋转屏幕也能够很好的达到适配效果,最后我们还需要做的2点,可能有些朋友已经发现了,在我们旋转屏幕的时候,Fragment会重新调用onCreate方法,导致成员变量重新初始化了一次,Fragment对象也重置为空,然后就调用不到hide方法,从而出现了界面重复叠加的情况。
下面提供解决的方法,其实很简单,只需要在AndroidManifest.xml里面对应的activity里添设置改换屏幕方向等操作时不触发oncreate事件就可以。
android:configChanges="orientation|keyboardHidden|screenSize"
最后我们隐藏下标题栏,在application里添加上:
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://www.cnblogs.com/lichenwei/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
正在看本人博客的这位童鞋,我看你气度不凡,谈吐间隐隐有王者之气,日后必有一番作为!旁边有“推荐”二字,你就顺手把它点了吧,相得准,我分文不收;相不准,你也好回来找我!
相关文章推荐
- 安卓开发笔记——多种方式实现底部菜单栏(仿微信界面)
- 多种方式实现底部菜单栏(仿微信界面)
- Android RadioGroup+ViewPager+ActionBar实现仿微信6.0界面(底部滑动菜单栏+导航栏)
- 安卓开发笔记——ViewPager组件(仿微信引导界面)
- 安卓开发复习笔记——ViewPager组件(仿微信引导界面)
- 安卓开发笔记——TabHost组件(一)(实现底部菜单导航)
- 安卓开发笔记——TabHost组件(二)(实现底部菜单导航)
- 安卓开发笔记——Fragment+ViewPager组件(高仿微信界面)
- 安卓开发笔记——Fragment+FragmentTabHost组件(实现新浪微博底部菜单)
- 安卓开发复习笔记——Fragment+FragmentTabHost组件(实现新浪微博底部菜单)
- 安卓开发复习笔记——Fragment+ViewPager组件(高仿微信界面)
- 安卓从零开发之购物商城(一)--底部菜单栏的的实现(FragmentTabHost)
- Android开发之微信底部菜单栏实现的几种方法汇总
- 安卓开发--应用市场的界面制作(一)--viewpager+fragment实现可滑动的底部导航栏
- 关于安卓开发实现底部菜单栏(已过时做法,不建议使用)
- Android高仿QQ及微信底部菜单的多种实现方式【附源码地址】
- 【微信开发笔记】常见的长按保存图片功能的实现方式及清晰度优化方式
- 【附源码地址】Android高仿QQ及微信底部菜单的多种实现方式
- 开发微信小程序(3)-全局配置app.json及底部导航栏实现
- 安卓开发中图片验证码的实现方式和工具类(附:模拟EditText密码可见性的动态切换)