Android开发秘籍学习笔记(十三)


最近在研究网易云音乐的User Interface,首页的Action Bar 还有三个Tab,今天就来研究这个是如何实现的。


我也搜了不少的ActionBar的博客,基本没有什么实例支持,都只是官方文档的翻译。http://blog.csdn.net/xyz_lmn/article/details/8132420


关于ActionBar


首先提下ActionBar,ActionBar是窗体功能来鉴别用户当前在app中的位置,提供给用户一些功能和导航,通过ActionBar可以方便的让系统自动适配不同尺寸的屏幕。

ActionBar包含如下内容:


  1. App icon
  2. Action item(项目)
  3. Action overflow(放不下的item,放在overflow里)

加入一个ActionBar

在你的布局中引入一个ActionBar,只需要2步
  1. 创建一个活动继承自ActionBarActivity(但是现在被AppCompatActivity替代,所以继承AppCompatActivity即可)
  2. 在你的activity声明中加入
    <activity android:theme="@style/Theme.AppCompat.Light">
删除ActionBar:
可以在程序中运行时隐藏ActionBar,像这样。
ActionBar actionBar = getSupportActionBar();
actionBar.hide();
android系统会自动调整布局来填充,隐藏的ActionBar。如果你希望它显示回来,可以使用show()方法。


首先是右边的两个图标 search和menu 这两个icon 是通过onCreateOptionsMenu()实现的:

public boolean onCreateOptionsMenu(Menu menu) {  
	    MenuInflater inflater = getMenuInflater();  
	    inflater.inflate(R.menu.menu, menu);  
	    return super.onCreateOptionsMenu(menu);  
	}  

通过在Menu中设置:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      tools:context=".MainActivity">

	<item
		android:id="@+id/action_search"
		android:icon="@drawable/actionbar_search"
		android:showAsAction="ifRoom"
		android:title="@string/action_search"/>
	<item
		android:id="@+id/action_menu"
		android:icon="@drawable/actionbar_menu"
		android:showAsAction="always"
		android:title="@string/action_more"/>
</menu>
showAsAction属性是可以确定item是在overflow里面还是外面。

注意showAsAction这个属性必须要自定义一个名字空间来使用

<span style="white-space:pre">	</span>xmlns:android="http://schemas.android.com/apk/res/android"
      <span style="white-space:pre">	</span>xmlns:yourapp="http://schemas.android.com/apk/res-auto"

  • ifRoom 会显示在ActionBar 如果屏幕空间不足,则藏到Overflow里
  • never 永远只在Overflow里显示,而且只显示标题
  • always 总是显示
  • withText 尽可能的显示标题。空间不足则不显示
  • collapseActionView 声明这个View被折叠到按钮。选择了按钮才会打开。配合ifRoom使用
这样就可以完成了右边两个icon,接下来看看左边三个icon是如何实现的:

TypedArray tabIconIds = getResources().obtainTypedArray(R.array.actionbar_icons);
		
		for(int i = 0; i < 3; i++){
			View view = getLayoutInflater().inflate(R.layout.actionbar_tab, null);
			ImageView tabIcon = (ImageView) view.findViewById(R.id.actionbar_tab_icon);
			
			tabIcon.setImageResource(tabIconIds.getResourceId(i, -1));
			
			actionBar.addTab(actionBar.newTab().setCustomView(view).setTabListener(tabListener));
		}
		enableEmbeddedTabs(actionBar);

这里使用了TypedArray来自定义属性。即定义tab icon的属性,具体的TypedArray的使用可以学习 http://blog.it985.com/13456.html


actionbar_tab.xml的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:orientation="horizontal">

	<ImageView
		android:id="@+id/actionbar_tab_icon"
		android:layout_width="55dp"
		android:layout_height="wrap_content"
		android:layout_gravity="center"
		android:src="@drawable/actionbar_discover"/>

</LinearLayout>

这里ImageView的src属性的值设置不设置都一样,最后都会从array中的actionbar_icons中顺序读取图片的资源

array中的actionbar_icons.xml代码:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="actionbar_icons">
        <item>@drawable/actionbar_discover</item>
        <item>@drawable/actionbar_music</item>
        <item>@drawable/actionbar_friends</item>
    </string-array>
</resources>

三个item中的值分别是三个icon的选择器这里贴出其中一个的:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
	<item android:drawable="@drawable/actionbar_discover_selected" android:state_selected="true"/>

	<item android:drawable="@drawable/actionbar_discover_normal"/>
</selector>


这样三个Tab icon就设置好了,我们看到上面的代码还有个setTabListener,代码如下:

ActionBar.TabListener tabListener = new ActionBar.TabListener() {
			@Override
			public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
			}
			
			@Override
			public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
				
			}
			
			@Override
			public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
				
			}
		};
如果要将其与Viewpager结合起来,只需添加转换的代码即可(具体的实现方法本人也未测试)。做这些之前别忘记获取ActionBar.....
<span style="white-space:pre">		</span>actionBar = getActionBar();
		
		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
		actionBar.setDisplayShowHomeEnabled(false);  
		actionBar.setDisplayShowTitleEnabled(false);


完成之后,应该就可以看到部分效果了。但是还是有问题,比如我的问题就是只显示一个Tab Icon 另外两个会藏在overflow中,但点开overflow,这三点Tab icon都消失了,但是却占据着三个空间,去网上看别人的代码,他们在style.xml中添加了许多的ActionBar的style,具体是如何什么问题我也不清楚,总之解决了。以下是关于ActionBar的一些style:

<style name="AppTheme" parent="android:Theme.Holo.Light">
        <item name="android:actionBarStyle">@style/EmbeddedActionBar</item>
		<item name="android:actionBarTabStyle">@style/EmbeddedTabStyle</item>
		<item name="android:actionBarTabBarStyle">@style/EmbeddedTabBarStyle</item>
    </style>
    
    <style name="EmbeddedActionBar" parent="NormalActionBar"/>

	<style name="EmbeddedTabStyle" parent="@android:style/Widget.Holo.Light.ActionBar.TabView">
		<item name="android:padding">0dp</item>
		<item name="android:gravity">center</item>
		<item name="android:background">@drawable/actionbar_tabs_bg</item>
	</style>

	<style name="EmbeddedTabBarStyle" parent="@android:style/Widget.Holo.Light.ActionBar.TabBar">
		<item name="android:divider">@null</item>
	</style>
	
	<style name="NormalActionBar" parent="@android:style/Widget.Holo.Light.ActionBar.Solid">
		<item name="android:title">私人FM</item>
		<item name="android:titleTextStyle">@style/action_bar_style</item>
		<item name="android:background">@color/actionbar_background</item>
	</style>

	<style name="action_bar_style">
		<item name="android:textColor">@color/white</item>
		<item name="android:textSize">18sp</item>
	</style>

最后的实现效果就是下图:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值