ActionBar学习总结

ActionBar是在3.0(API 11)新加入的部分,在4.0(API  14)以后成熟化。之前看书学Menu的时候出现了很多问题,而且基本不怎么好解决。(学校图书馆实在都是老书)后来,在网上查资料才发现,ActionBar相当于是将以前的TitleBar和Menu结合起来了。

这里是学习资料,感谢两位老师。

http://blog.csdn.net/guolin_blog/article/details/18234477

http://blog.csdn.net/xyz_lmn/article/details/8132420

接下来,是我自己的学习总结。

第一步、首先我们先创建Actionbar

毕竟我是个菜鸟,我开始用安卓手机的时候都是4.0的时代了。也被低版本的问题困扰了很久,v7包导入了以后出现各种奇怪的问题,而且我也不知道,这里不做讨论。直接设置minSDK=14(4.0),此版本是自带ActionBar的。我们只需要用getActionBar()方法就可以得到ActionBar了。此外,可以通过hide()和show()方法来让ActionBar显示和隐藏(一定要注意布局的变动)

我这边是用一个按钮来操控显示隐藏的

btnActionbar.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				if (flagActionBar) {
					actionbar.hide();
					btnActionbar.setText("显示ActionBar");
					flagActionBar=false;
				} else {
					actionbar.show();
					btnActionbar.setText("隐藏ActionBar");
					flagActionBar=true;
				}
			}
		});



第二步、 注入菜单

跟ActionBar是一个原理,使用getMenuInflater()方法得到填充器,再用inflate()就好

public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.menu_actionbar_item, menu);
		return true;
	}
接着,是在menu文件夹下新建一个Resource.xml文件

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:id="@+id/item_01"
        android:icon="@drawable/fire_theme01"
        android:showAsAction="ifRoom|withText"
        android:title="@string/actionbar_item_01"/>
    <item
        android:id="@+id/item_02"
        android:icon="@drawable/fire_theme02"
        android:showAsAction="ifRoom|withText"
        android:title="@string/actionbar_item_02"/>
   

</menu>
列出了两项,有需求可以再加。这边做个简单说明,icon是图标,title是显示的文字(当然你长按操作项会有Toast显示Title)。showAsAction这个属性呢有 

never、always、ifRoom、withText、collapseActionView

前三项对应的呢是选择出现在overflow(三个竖点)外,其中ifRoom是在有足够空间的时候显示在overflow外(推荐使用)。而withText是显示Title在overflow外的(在手机上依旧不显示,平板上显示)。collapseActionView是让该元素能点击后拓展开,并响应事件(以我自己的理解)。


第三步、填充完了,加入菜单的响应点击事件,并简单实现返回的功能(非物理按键型)

首先是

@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.item_01:
			Intent intent = new Intent(this, NewActivity01.class);
			intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			startActivity(intent);
			return true;
		case R.id.item_02:
			Intent intent2 = new Intent(this, NewActivity02.class);
			intent2.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
			startActivity(intent2);
			return true;
	
		default:
			return super.onOptionsItemSelected(item);
		}
	}
这里简单说明一下,一定要return  true。这样系统的Menu才不会做处理,交给你响应(我也不懂说的对不对。。。汗)FLAG_ACTIVITY_CLEAR_TOP的作用呢,是当打开新的Activity时,如果以前有了,直接把以前的都关了。(通俗的说就是,Activity1暂停了,打开了Activit2,那么再打开Activity1时,之前的Activity1会自动销毁)这样的好处自然是让系统运行更流畅。


至于向上返回

需要添加

actionBar.setDisplayHomeAsUpEnabled(true);
以及,响应处应为
   case android.R.id.home:
	finish();
	return true;
这样你通过点击最左边的图标,返回父级界面了。



第四步、让overflow里的图标能显示出来

这边其实不太好理解,用的是Java里反射的方法(Java不是太会,只会一点皮毛)我也上网查阅了一些资料,大概就是通过获取方法的名字,然后来改写(大致是这样的吧。。。。汗)

这里用到的是MenuBuilder里的setOptionalIconVisible()方法,默认的是false,我们只要将其改成true就好了。

我这边结合按键来实现的显示与隐藏切换(按钮那部分就不粘了)

 public boolean onMenuOpened(int featureId, Menu menu) {
	 if (featureId==Window.FEATURE_ACTION_BAR&&menu!=null) {
	 if (menu.getClass().getSimpleName().equals("MenuBuilder")) {
	 try {
	 Method method=menu.getClass().getDeclaredMethod("setOptionalIconsVisible",
	 Boolean.TYPE);
	 method.setAccessible(true);
	 method.invoke(menu, flagOverflow);
	 } catch (Exception e) {
	 // TODO: handle exception
	 }
	 }
	 }
	 return super.onMenuOpened(featureId, menu);
	 }


第五步、添加子菜单

新建一个class,extends ActionProvider

通过onPrepareSubMenu方法来添加子菜单

public void onPrepareSubMenu(SubMenu subMenu) {
		subMenu.clear();
		subMenu.add("画册").setIcon(R.drawable.fire_theme04)
				.setOnMenuItemClickListener(new OnMenuItemClickListener() {

					@Override
					public boolean onMenuItemClick(MenuItem item) {
						
						return true;
					}
				});
		subMenu.add("日记").setIcon(R.drawable.fire_theme05)
				.setOnMenuItemClickListener(new OnMenuItemClickListener() {

					@Override
					public boolean onMenuItemClick(MenuItem item) {
						
						return true;
					}
				});
	}
当然,还要有一个判断方法

@Override
	public boolean hasSubMenu() {
		return true;
	}
这些完成之后,别忘记了,在menu的布局文件里,将你想添加子菜单的菜单项添上(一定要是完整的包名哦~~)

android:actionProviderClass="com.dota.example.myactionbardemo.MyActionBarProvider"

贴士:可以在Manifest里修改application或者activity的属性,logo代表左侧图标,label代表标题


第六步、结合ViewPager+Actionbar.Tab+Fragment来实现可滑动的标签

这里稍稍复杂,我们细细来

一、先新建所需的Fragment(片段),这个东西类似Activity,可以看成是数个这玩意组成Activity的。(我又开始按着自己的理解胡说八道了,你们按着自己的理解来)

public class FragmentTree extends Fragment{
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		return inflater.inflate(R.layout.fragment_tree, container, false);
	}
}
以相同的方式完成数个Fragment(记得配好布局xml)

这边有个要注意的地方,因为要涉及ViewPager的使用,这边Fragment的import为

import android.support.v4.app.Fragment;
千万不要弄成

import android.app.Fragment;
不然之后处理会很麻烦

二、导入ViewPager

是在主布局中哦~~~

 <android.support.v4.view.ViewPager
        android:id="@+id/pagerChange"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </android.support.v4.view.ViewPager>
三、添加Tab项

我们通过新建一个类,来将Fragment和Tab联系起来

class MyTab {
		private int text;
		private Class fragment;

		public MyTab(int text, Class fragment) {
			this.text = text;
			this.fragment = fragment;
		}

		public int getText() {
			return text;
		}

		public void setText(int text) {
			this.text = text;
		}

		public Class getFragment() {
			return fragment;
		}

		public void setFragment(Class fragment) {
			this.fragment = fragment;
		}

	}
然后新建一个ArrayList,把元素放进去
private List<MyTab> tabs = new ArrayList<MyTab>(3);


tabs.add(new MyTab(R.string.tab_title01, FragmentCookie.class));
tabs.add(new MyTab(R.string.tab_title02, FragmentTree.class));
tabs.add(new MyTab(R.string.tab_title03, FragmentSnowman.class));
这之后,把Tab填进去,并绑定好监听器

actionbar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);		//确立有Tab的导航模式
		for (MyTab tab : tabs) {
			Tab t = actionbar.newTab();
			t.setText(tab.getText()).setTabListener(this);
			actionbar.addTab(t);
		}

这边TabListener需要implement,并实现3个方法

public void onTabSelected(Tab tab, FragmentTransaction ft) {
		// TODO Auto-generated method stub
		viewPager.setCurrentItem(tab.getPosition());
	}

	@Override
	public void onTabUnselected(Tab tab, FragmentTransaction ft) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onTabReselected(Tab tab, FragmentTransaction ft) {
		// TODO Auto-generated method stub

	}
当选中某个Tab时,切换到对应的Pager(其实这个是下一步有关的)

四、实现ViewPager的滑动
viewPager.setAdapter(new TabFragmentPagerAdapter(
				getSupportFragmentManager()));
		viewPager.setOnPageChangeListener(this);
这边用到了一个Adapter,extends于FragmentPagerAdapter 

并且有个要注意的,需将主Activity extends  改成FragmentActivity ,这样才可以用getSupportFragmentManager()方法。除此以外,还要注意接口均是v4的,不是app的。如下:

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
让主Activity  implement  OnPageChangeListener

然后是3个方法

@Override
	public void onPageScrollStateChanged(int arg0) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onPageScrolled(int arg0, float arg1, int arg2) {
		// TODO Auto-generated method stub

	}

	@Override
	public void onPageSelected(int i) {
		actionbar.selectTab(actionbar.getTabAt(i));
	}
最后,把Adapter的部分写下来

class TabFragmentPagerAdapter extends FragmentPagerAdapter {

		public TabFragmentPagerAdapter(FragmentManager fragmentManager) {
			super(fragmentManager);
		}

		@Override
		public Fragment getItem(int i) {
			try {
				return (Fragment) tabs.get(i).getFragment().newInstance();
			} catch (Exception e) {
				// TODO: handle exception
			}
			return null;
		}

		@Override
		public int getCount() {
			return tabs.size();
		}

	}
这里,主要是把对应好编号的Tab和Fragment匹配并newInstance一个实例




第七步、自定义样式
这部分我就不详细说了,老师这里写的特别详细,特别好

http://blog.csdn.net/guolin_blog/article/details/25466665

直接上代码吧

  <style name="CustomActionBarTheme" parent="android:Theme.Holo.Light">
        <item name="android:actionBarStyle">@style/MyActionBar</item>
        <item name="android:actionBarTabTextStyle">@style/MyActionBarTabText</item>
        <item name="android:actionBarTabStyle">@style/MyActionBarTab</item>
      <item name="android:actionBarTabBarStyle">@style/MyActionBarTabBar</item>
      <item name="android:actionBarDivider">@drawable/divide01</item>
        <item name="android:itemBackground">@drawable/background001</item>
    </style>

    <style name="MyActionBar" parent="@android:style/Widget.Holo.Light.ActionBar">
        <item name="android:background">#ffc4ff</item>
        <item name="android:titleTextStyle">@style/MyActionBarTitleText</item>
    </style>

    <style name="MyActionBarTitleText" parent="@android:style/TextAppearance.Holo.Widget.ActionBar.Title">
        <item name="android:textColor">#3a7bbc</item>
    </style>

    <style name="MyActionBarTabText" parent="@android:style/Widget.Holo.Light.ActionBar.TabText">
        <item name="android:textColor">#007fff</item>
        <item name="android:textSize">20sp</item>
        <item name="android:textStyle">normal</item>
    </style>

    <style name="MyActionBarTab" parent="@android:style/Widget.Holo.ActionBar.TabView">
        <item name="android:background">@drawable/actionbar_tab_indicator</item>

    </style>

    <style name="MyActionBarTabBar" parent="@android:style/Widget.Holo.ActionBar.TabBar">
        <item name="android:background">#000000</item>
    </style>
记得编辑完了要在Manifest中引用哦~~
 android:theme="@style/CustomActionBarTheme"
我自己又另外加了两个

分别用蓝笔,绿笔标出了

蓝笔对应

 <item name="android:actionBarDivider">@drawable/divide01</item>

绿笔对应

 <item name="android:actionBarTabBarStyle">@style/MyActionBarTabBar</item>


就是颜色配的好像很奇怪,不过还是一点点地又完整地复习了一遍ActionBar的使用。大笑

完整代码下载地址:

http://download.csdn.net/detail/zerolovesc1993/8411991













评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值