文档章节

程序猿媛 八:Android侧滑栏+底部导航栏(选项卡)

花佟林雨月
 花佟林雨月
发布于 2014/09/15 13:16
字数 1472
阅读 5478
收藏 13

Android侧滑栏+底部导航栏(选项卡)

声明:博文为原创,文章内容为,效果展示,思路阐述,及代码片段。

转载请保留原文出处“http://my.oschina.net/gluoyer/blog”,谢谢!

引子:更新手机QQ5.1,发现小企鹅整合了侧滑栏,加底部导航栏的风格,跟风一下。

展示应用下载程序猿媛2.0

实现效果:

360手机助手截图0914_23_03_01  360手机助手截图0914_23_04_02  360手机助手截图0914_23_04_01

本文介绍:

  • FragmentManager管理底部导航栏对应Fragment内容切换。
  • 利用Slidingmenu展示侧滑栏;

FragmentManager管理底部导航栏对应Fragment内容切换:

    底部导航栏,以前介绍过“程序猿媛二:Android底部导航栏(选项卡)”,利用RadioGroup做导航栏,ViewPager结合Fragment管理显示页面。

    此处涉及到图文显示,以及需要扩展(实际应用中,显示新消息提醒等),使用自定义导航项布局,并在代码中管理点击切换内容的方式。同时,考虑到“程序猿媛二”中,定义及管理对应关系有点繁琐的问题,特意进行了代码优化,使得管理更加方便。

  •     初始化导航内容:

定义管理映射:
private SparseArray<BaseFragment> navigateMap = new SparseArray<BaseFragment>();

// 添加导航内容
setContentView(R.layout.slide_menu_content_frame);
navigateMap.clear();
mapNaviToFragment(R.id.navi_item_home, new HomeFragment()); // 首页
mapNaviToFragment(R.id.navi_item_work_notes, new WorkNotesFragment()); // 工作笔记
mapNaviToFragment(R.id.navi_item_third_libs, new ThirdLibsFragment()); // 第三方
// 设置首页默认显示
replaceFragment(fm, R.id.navi_item_home); // 执行内容切换方法,后续描述

/**
 * 初始化map
 * @param id 导航view ID
 * @param fragment
 */
private void mapNaviToFragment(int id, BaseFragment fragment) {
	View view = findViewById(id);
	Utils.logh(TAG, "mapNaviToFragment " + id + " view: " + view);
	view.setOnClickListener(this); // 设置导航点击事件
	view.setSelected(false); // 默认添加时,非选中
	navigateMap.put(id, fragment); // 添加到管理映射
}

    可以看到初始化map(被系统建议使用SparseArray替代HashMap,不了解的问度娘吧)时,直接用View的id作为key。如此,后续点击切换时,就可以直接通过View的选中状态来判断,当前点击后,是否需要替换显示内容。不再需要额外定义标签,及记录当前选择标签等;代码复用也更方便。

  • 点击切换处理

/**
 * 点击后,切换内容
 * @param view 点击view
 * @return 点击view,是否为导航view
 */
private boolean clickSwitchContent(View view) {
	int id = view.getId();
	if(navigateMap.indexOfKey(id) < 0) {
		// 点击非导航view
		return false;
	}
	Utils.logh(TAG, "switchContent " + id + " select: " + view.isSelected() + " view: " + view);
	if(!view.isSelected()) {
		// 当前非选中状态:需切换到新内容
		replaceFragment(getSupportFragmentManager(), id);
	} else {
		Utils.logh(TAG, " ignore --- selected !!! ");
	}
	return true;
	
}

@Override
public void onClick(View v) {
	if(clickSwitchContent(v)) {
		return ;
	}
	// 处理其他点击事件
}

    实现系统onClick点击方法时,封装了clickSwitchContent方法,通过navigateMap查看点击View是否为导航View。非导航View,返回处理其他点击事件;是导航View,根据view的选中状态,非选中时,切换到新的Fragment显示内容。

  • 执行内容切换

/**
 * 执行内容切换
 * @param fm
 * @param id 导航view ID
 */
private void replaceFragment(FragmentManager fm, int id) {
	Utils.logh(TAG, "replaceFragment EntryCount: " + fm.getBackStackEntryCount()
			+ " size: " + (null == fm.getFragments() ? "0[null]" : fm.getFragments().size()));
	String tag = String.valueOf(id);
	// 执行替换
	FragmentTransaction trans = fm.beginTransaction();
	if(null == fm.findFragmentByTag(tag)) {
		trans.replace(R.id.content_frame, navigateMap.get(id), tag);
		// 不存在时,添加到stack,避免切换时,先前的被清除{fm.getFragments()}
		// {存在时,不添加,避免BackStackEntry不断累加}
		Utils.logh(TAG, "null +++ add to back");
		trans.addToBackStack(tag);
	} else {
		trans.replace(R.id.content_frame, fm.findFragmentByTag(tag), tag);
	}
	trans.commit();
	Utils.logh(TAG, "replace map: " + navigateMap.get(id) + "\n" +
					"---- fm tag: " + fm.findFragmentByTag(tag));
	// 重置导航选中状态
	for(int i=0, size=navigateMap.size(); i<size; i++) {
		int curId = navigateMap.keyAt(i);
		Utils.logh(TAG, "curId: " + curId);
		if(curId == id) {
			findViewById(id).setSelected(true);
		} else {
			findViewById(curId).setSelected(false);
		}
	}
}

    方法中,主要两部分功能:执行替换;重置导航选中状态。

    这里主要介绍下,执行替换中,addToBackStack的处理。关于FragmentManager的介绍,比比皆是,却翻来覆去。度娘说,大家都转疯了。

    addToBackStack,大家应该都知道,是一个历史操作的记录。但此处应用,是非常规的,作为了一个绑定标识。抛开系统源码的讲解,和官方文档的不尽翻译。用更直观的方式,阐述下此处对addToBackStack的使用。

    如果,不用addToBackStack方法,打印如下左侧,用addToBackStack方法,打印如下右侧:

image

很明显,不加到backstack的话,切换过程中,系统会销毁之前的Fragment,再回来的时候,要重新绑定,创建,通过getFragments().size()方法获取的FragmentManager中的Fragment列表也是不同的:只存放当前存放所有添加到backstack的{size比我们初步想到的貌似多了1,要记得侧滑栏也是一个Fragment哈}。

    当然,addToBackStack也可以不做限制,每次都添加,只是通过getBackStackEntryCount()方法会看到,记录会不断累积,而我们又不需要(当然,你要非需要,额外处理一下),所有就只是判断一下,不做重复添加了,毕竟,使用很另类,只是绑定标识,而已。

    哈,简化过的几个方法,处理了原本对应繁琐的问题,也有更好的复用性。

 

利用Slidingmenu展示侧滑栏:

    侧滑栏的应用介绍可以参照,程序猿媛 七:slidingmenu侧滑栏导航。原来整理成了jar包放到了libs里面。考虑出现问题时,更容易跟踪等情况,将源码放到工程extras目录下(碰到导入相关问题的话,请先度娘一哈)。完整源码请膜拜Jeremy Feinstein的“SlidingMenu-GitHub”。

   slidingmenu目录下,只放置了供大家引用的基础工程,同时,把动画相关,从源码示例工程,提取出CustomAnimation.java文件,调用时,如下即可:

SlidingMenu sm = getSlidingMenu();

sm.setBehindCanvasTransformer((new CustomAnimation()).getCustomZoomAnimation());

当然,你也可以加入自己实现的动画显示方式。   欢迎反馈,后续丰富动画代码。

 

全文完,希望对您有帮助,谢谢!

展示应用下载程序猿媛2.0

转载请保留原文出处“http://my.oschina.net/gluoyer/blog”,谢谢!

© 著作权归作者所有

花佟林雨月
粉丝 78
博文 11
码字总数 10652
作品 0
成都
私信 提问
程序猿媛七:slidingmenu侧滑栏导航

SlidingMenu侧滑栏导航 声明:博文为原创,文章内容为,效果展示,思路阐述,及代码片段。 转载请保留原文出处“http://my.oschina.net/gluoyer/blog/214399”,谢谢! 您可以到博客的“友情...

花佟林雨月
2014/03/30
2.5K
0
程序猿媛二:Android底部导航栏(选项卡)

底部导航栏(选项卡) ViewPager+RadioGroup 声明:博文为原创,文章内容为,效果展示,思路阐述,及代码片段。源码请通过应用内下载。 转载请保留原文出处“http://my.oschina.net/gluoyer...

花佟林雨月
2013/11/10
17.8K
3
React Native开发之react-navigation库详解

众所周知,在多页面应用程序中,页面的跳转是通过路由或导航器来实现的。在0.44版本之前,开发者可以直接使用官方提供的Navigator组件来实现页面的跳转,不过从0.44版本开始,Navigator被官方...

xiangzhihong
06/04
0
0
Android底部导航栏(可滑动)----TabLayout+viewPager

【TabLayout】   ①TabLayout是选项卡,在屏幕空间有限的情况下,对不同的空间进行分组。属于android support design,更多的用于新闻上,如果放在底部也可做底部导航栏        ②T...

汪菜菜
03/12
0
0
Android 4.0设计规范10大改变

对比Android 4.0与Android2.3及之前版本的App设计指导,总结了Android 4.0设计的10大改变: 1. 导航栏 (详见模式PATTERNS>导航Navigation) 由之前的物理按键导航(返回、菜单、搜索、主页)变...

晨曦之光
2012/03/01
743
1

没有更多内容

加载失败,请刷新页面

加载更多

灵光一闪来个科普贴:Linux文件系统

在计算机系统中,各种需要保存的信息都是以文件的形式存在的。文件管理是对系统信息资源的管理,是操作系统的一项重要功能。 1.文件与文件系统: 1.1文件: 文件是具有名字的一组相关信息的有...

Linux就该这么学
23分钟前
3
0
ExtJS 4.2 评分组件

本文转载于:专业的前端网站➸ExtJS 4.2 评分组件 上一文章是扩展ExtJS自带的Date组件。在这里将创建一个评分组件。 目录 1. 介绍 2. 示例 3. 资源下载 1. 介绍 代码参考的是 Sencha Touch 2...

前端老手
26分钟前
3
0
如何为视频添加封面?

一个好的视频封面可以吸引观众的眼球,从而起到事半功倍的宣传效果,但是很多小伙伴并不知道怎么给视频添加封面。下面分享一个制作封面否方法,操作起来也比较简单的,有兴趣的小伙伴请接着往...

白米稀饭2019
36分钟前
3
0
如何使用soapUI模拟webservice客户端发送请求

参考资料 https://jingyan.baidu.com/article/cbcede0712849a02f40b4d88.html 左边是请求参数,可以自己填写!按着那个绿色三角箭头可以模拟发送请求,右边是返回的报文 soapui如何发送xml格...

故久呵呵
今天
6
0
Java Security 介绍

1.介绍 Java平台设计的重点是安全性。在其核心,java语言本身是类型安全的并且提供了垃圾自动回收,这使其增加了应用程序代码的健壮性。安全的类加载以及验证机制确保了只有合法的代码才能够...

lixiaobao
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部