Actionbar入门(一)

参考:

           http://www.apkbus.com/android-125933-1-1.html

前提:

如果系统是3.0以上,就不需要进行任何操作,否则:

        1,  导入工程sdk\extras\android\support\v7\appcompat(sdk中自带的)并将该工程做为library引入到自己的项目中(该工程中自带有v7包,所以不需要自己重新导入)。

        2,Activity要继承ActionbarActivity。

        3 , 清单文件中的theme必须是android:theme="@style/Theme.AppCompat"或者是AppCompat的子类

        4,通过getSupportActionBar()得到Actionbar对象。

在XML中定义actions

        同菜单一样,所有的action button与action overflow都可以定义在res/menu文件夹下的xml文件中,都需要通过onCreateOptionsMenu()来生成相应的界面,并通过onOptionsItemSelected()响应点击事件。

系统3.0以上

建立main.xml文件

<menu xmlns:android="http://schemas.android.com/apk/res/android" >
    <item
        android:id="@+id/action_search"
        android:icon="@drawable/ic_action_search"
        android:showAsAction="ifRoom"
        android:title="@string/action_search"/>
    <item
        android:id="@+id/action_settings"
        android:showAsAction="never"
        android:title="@string/action_settings"/>
</menu>

使用v7包建立xml

        大部分和3.0以上一样,只不过showAsAction属性并不能使用android:前缀了(也就是说不能使用http://schemas.android.com/apk/res/android这个名称空间),因此我们需要自己定义xml名称空间(该名称空间的值必须是http://schemas.android.com/apk/res-auto,但是它的名可以随便取),并且使用该名称空间作为该属性的前缀。如:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:myns="http://schemas.android.com/apk/res-auto" >
    <!-- 自定义名称空间,值必须是http://schemas.android.com/apk/res-auto,名可以随便取 -->
    <item
        android:id="@+id/action_search"
        android:icon="@drawable/ic_action_search"
        android:title="@string/action_search"
        myns:showAsAction="ifRoom"/>
    <!-- showAsAction属性使用自定义的名称空间做为前缀,而不是3.0以上的android: -->
    <item
        android:id="@+id/action_settings"
        android:title="@string/action_settings"
        myns:showAsAction="never"/>
</menu>

生成界面:

        重写activity中的onCreateOptionsMenu方法:

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.main, menu);
		return true;
	}
经过以上两步,就可以在action button显示出来。

响应点击事件:

        重写activity中的onOptionsItemSelected(),并通过调用MenuItem.getItemId()判断点击的是哪一个条目。如:
public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {// 得到对应的id
		case R.id.action_search:
			Toast.makeText(this, R.string.action_search, Toast.LENGTH_SHORT)
					.show();
			break;
		case R.id.action_settings:
			Toast.makeText(this, R.string.action_settings, Toast.LENGTH_SHORT)
					.show();
			break;

		default:
			break;
		}
		return super.onOptionsItemSelected(item);
	}

返回parentActivity界面

        该功能主要用于在任何非主界面的activity中都能一次性返回到parentActivity中。这是和返回键的区别:返回键只能返回到上一次界面;而该功能却返回到parentActivity,无论是parentActivity与当前activity中间隔了几个activity。

清单文件中配置parentActivity   

<activity
            android:name="com.baigle.demo.MainActivity"
            android:logo="@drawable/small" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.baigle.demo.ThirdActivity"
            android:parentActivityName="com.baigle.demo.MainActivity" >
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="com.baigle.demo.MainActivity" />
        </activity>
         注意:对ThirdActivity来说,它不但要配置parentActivityName属性,还需要加上<meta-date>标签.并且,标签中的android:name的值是固定的,android:value的值就是它的parentActivity的全名(包名+类名)。

在activity设置   

protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//使用v7包时调用getSupportActionbar()
		getSupportActionBar().setDisplayHomeAsUpEnabled(true);
		/*
		 * 不使用v7包时,直接用:
		 * getActionBar().setDisplayHomeAsUpEnabled(true);
		 */
	}
	//使用v7包时,该方法可以不重写
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case android.R.id.home://此处的id值是固定的
			//此处是返回到parentActivity界面中,也可以进行别的操作。
			NavUtils.navigateUpFromSameTask(this);
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

注意

        在返回到parentActivity时,会把parentActivity上面的所有activity清除出栈 相当于intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
        上面是使用NavUtils直接返回到父Activity中,但在返回之前最好要先判断一下是否具有父Activity,调用NavUtils.getParentActivityName()返回父Activity的类名,如果该值为null,那就代表着没有父Activity。
        这里一般不会手动启动父Aitivity,首先NavUtils类的实现代码简洁,其次当清单文件中父Activity改变时,不需要手动的修改代码。

actionbar的重叠模式(overlay mode)

        默认的情况下,actionbar是显示在window顶部的,它占用了一部分window空间,从而使我们的activity布局所能使用的空间变小。而且,当actionbar显示或者隐藏的时候(通过调用show()或者hide()),会导致系统重新计算、排列布局。
        为了避免这种情况的出现,可以将actionbar设置为重叠模式(overlay mode)。在此种模式下,activity的布局会使用整个window,而actionbar会悬浮在布局上。不过,在此种情况下,actionbar会遮住布局的顶部。当然,我们也可以按照上面说的方法设置actionbar的背景,使它具备一定的透明度。
      将actionbar设置成overlay mode的方法是:自定义style,并且将其中的android:windowActionBarOverlay的值设置成true。

v7下

<style name="CustomActionBarTheme"
           parent="@android:style/Theme.AppCompat">
        <item name="android:windowActionBarOverlay"  tools:ignore="NewApi">true</item>

        <!-- Support library compatibility -->
        <item name="windowActionBarOverlay">true</item>
    </style>

系统3.0

<!-- the theme applied to the application or activity 。这里复制于官方文档,按照上面的自定义style方法试了下,可以用-->
    <style name="CustomActionBarTheme"
           parent="@android:style/Theme.Holo">
        <item name="android:windowActionBarOverlay">true</item>
    </style>

问题

       当为actionbar使用overlay mode时,它不会占据屏幕的上半部分,activity的布局会占据整个window。这样有可能使本应该在actionbar下面的部分被actionbar遮住。为此,我们可以在布局中为该部分设置一个额外的padding或者margin。
       3.0以上在布局中加上:
android:paddingTop="?android:attr/actionBarSize"
      v7在布局可以加上:
android:paddingTop="?attr/actionBarSize"

menu:

        它的根结点是<menu>也就是一个菜单,可以包含<item>和<group>两个子结点。

        <item>是用来定义一个菜单项的。每一个<item>下还可以包含<menu>,该<menu>就是子菜单,也就是点击该<item>后出现的菜单。

        <group>是将多个<item>合成一个菜单组,<group>中的属性是对整组菜单项都是有用的。如:

 <group
        android:checkableBehavior="single"
        test:showAsAction="always" >
        <item
            android:id="@+id/action4_item1"
            android:title="子菜单一"/>
        <item
            android:id="@+id/action4_item2"
            android:title="子菜单二"/>
    </group>
       其中的子菜单一和子菜单二属于一个菜单组,并且菜单组指定了单选。因此,这两个<item>就会以单选的形式存在,一次只能选择一个。但是它并不会和别的不包含在该<group>中的<item>冲突。

       <item>节点下只能包含<menu>节点,<group>节点下也只能包含<item>节点。<group>节点是不会出现在actionbar上的,它还是需要通过菜单按键来弹出。

示例:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:test="http://schemas.android.com/apk/res-auto" >
    <item
        android:id="@+id/action1"
        android:orderInCategory="100"
        android:title="菜单一"
        test:showAsAction="always">
        <menu>
            <item
                android:id="@+id/action1_item1"
                android:title="子菜单一">
                <menu>
                    <item
                        android:id="@+id/action1_item1_item1"
                        android:title="子子菜单一"/>
                    <item
                        android:id="@+id/action1_item1_item2"
                        android:title="子子菜单二"/>
                </menu>
            </item>
            <item
                android:id="@+id/action1_item2"
                android:title="子菜单二"/>
        </menu>
    </item>
    <group
        android:checkableBehavior="single"
        test:showAsAction="always" >
        <item
            android:id="@+id/action4_item1"
            android:title="子菜单一"/>
        <item
            android:id="@+id/action4_item2"
            android:title="子菜单二"/>
    </group>
</menu>

显示普通的UI组件:

        ActionBar中除了显示文字外,还可以指定一些UI组件。方法有二:

方法一:

       在<item>中使用actionViewClass属性,指定一个固定的View。

方法二:

       在<item>中使用actionLayout属性,指定视图对应的布局。因此,可以为该功能选项指定背景、文字颜色等选择器。

示例:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:test="http://schemas.android.com/apk/res-auto" >

    <item
        android:id="@+id/action1_item1_item1"
        test:actionViewClass="android.support.v7.widget.SearchView"
        test:showAsAction="always"/>
    <item
        android:id="@+id/action1_item1_item2"
        test:actionLayout="@layout/image_item"
        android:title="子子菜单二"
        test:showAsAction="always"/>
</menu>
要注意:

actionViewClass与actionLayout前面的也必须是自己命名的名称空间,而不能用android:。比如上面用的是test。如果是在3.0以上的系统中,可以直接用android:。

Actionbar与Fragment:

使用Actionbar的时候,继承的是ActionbarActivity,而ActionbarActivity又继承于v4包中的FragmentActivity。所以,这也给Actionbar与Fragment结合留下了可能。

示例:

public class MainActivity extends ActionBarActivity implements TabListener {

	private ActionBar bar;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		bar = getSupportActionBar();
		bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);//设置导航样式
		//设置导航条目
		bar.addTab(bar.newTab().setText("第一页").setTabListener(this));
		bar.addTab(bar.newTab().setText("第二页").setTabListener(this));
		bar.addTab(bar.newTab().setText("第三页").setTabListener(this));
	}
	@Override
	public void onTabSelected(Tab arg0, FragmentTransaction arg1) {
		MyFragment m = new MyFragment();
		Bundle bundle = new Bundle();
		bundle.putString(MyFragment.KEY, (String) arg0.getText());
		m.setArguments(bundle);//为fragment传递参数
		arg1.replace(R.id.container, m);
		//此处不要调用commit()方法,否则会报错。
	}
	@Override
	public void onTabReselected(Tab arg0, FragmentTransaction arg1) {

	}
	@Override
	public void onTabUnselected(Tab arg0, FragmentTransaction arg1) {

	}
}

上面的代码实现了tab标签导航。

常见问题:

        一:actionbar隐藏标题。当使用actionbar实现tab标签时,标题并没有隐藏。隐藏标题

bar.setDisplayShowHomeEnabled(false);
		bar.setDisplayShowTitleEnabled(false);

        二、actionbar显示在底部。有些时候actionbar会显示在底部。只需要在清单文件中进行配置:

<activity
            android:name="com.baigle.demo.MainActivity"
            android:label="@string/app_name"
            android:theme="@style/CustomActionBarTheme"
            android:uiOptions="splitActionBarWhenNarrow" >
            <meta-data
                android:name="android.support.UI_OPTIONS"
                android:value="splitActionBarWhenNarrow" />

就是要配置uiOptions属性,并且添加<meta-data>子标签

        三、action button显示图片与文字在<item>下设置icon,title属性,并将showAsAction加上withText值(如果多个值就用竖线隔开)。当屏幕宽度足够时,便会显示文字与图标,当宽度不够是只显示图标。如:

    <item
        android:id="@+id/action_search"
        android:icon="@drawable/ic_action_search"
        android:showAsAction="always|withText"
        android:title="搜索"/>
        四 、修改action button的点击效果(背景颜色的切换):更改style.xml中的android:actionButtonStyle属性的值,并且在该样式中更改android:background的值(点击成背景选择器就行)。如:

    <style name="MyActionbar" parent="@android:style/Theme.Holo.Light">
        <item name="android:actionButtonStyle">@style/buttonStyle</item>
    </style>

    <style name="buttonStyle" parent="Widget.ActionButton">
        <item name="android:background">@drawable/action_button_bc_selector</item>
    </style>

        五、动态修改action view的title属性:有可能在应用中随时要修改actionview的title属性。可以在需要修改的地方调用Activity.invalidateOptionsMenu(),重写onPrepareOptionsMenu(),并在该方法中修改title属性。如下:

	tv.setOnClickListener(new OnClickListener() {
		public void onClick(View v) {
			title += "-title";
			invalidateOptionsMenu();//点击时修改title属性,会重调onPrepareOptionsMenu()
		}
	});

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		super.onPrepareOptionsMenu(menu);
		MenuItem item = menu.findItem(R.id.tv_change);
		item.setTitle(title);
		return true;
	}















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值