actionbar_actionbarsherlock - CSDN
精华内容
参与话题
  • 使用ActionBar的好处是,它可以给提供一种全局统一的UI界面,使得用户在使用任何一款软件时都懂得该如何操作,并且ActionBar还可以自动适应各种不同大小的屏幕。下面是一张使用ActionBar的界面截图。其中,[1]是...

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/18234477


    本篇文章主要内容来自于Android Doc,我翻译之后又做了些加工,英文好的朋友也可以直接去读原文。

    http://developer.android.com/guide/topics/ui/actionbar.html


    Action Bar是一种新増的导航栏功能,在Android 3.0之后加入到系统的API当中,它标识了用户当前操作界面的位置,并提供了额外的用户动作、界面导航等功能。使用ActionBar的好处是,它可以给提供一种全局统一的UI界面,使得用户在使用任何一款软件时都懂得该如何操作,并且ActionBar还可以自动适应各种不同大小的屏幕。下面是一张使用ActionBar的界面截图:




    其中,[1]是ActionBar的图标,[2]是两个action按钮,[3]是overflow按钮。


    由于Action Bar是在3.0以后的版本中加入的,如果想在2.x的版本里使用ActionBar的话则需要引入Support Library,不过3.0之前版本的市场占有率已经非常小了,这里简单起见我们就不再考虑去做向下兼容,而是只考虑4.0以上版本的用法。


    添加和移除Action Bar


    ActionBar的添加非常简单,只需要在AndroidManifest.xml中指定Application或Activity的theme是Theme.Holo或其子类就可以了,而使用Eclipse创建的项目自动就会将Application的theme指定成Theme.Holo,所以ActionBar默认都是显示出来的。新建一个空项目并运行,效果如下图所示:




    而如果想要移除ActionBar的话通常有两种方式,一是将theme指定成Theme.Holo.NoActionBar,表示使用一个不包含ActionBar的主题,二是在Activity中调用以下方法:

    ActionBar actionBar = getActionBar();
    actionBar.hide();

    现在重新运行一下程序,就可以看到ActionBar不再显示了,如下图所示:




    修改Action Bar的图标和标题


    默认情况下,系统会使用<application>或者<activity>中icon属性指定的图片来作为ActionBar的图标,但是我们也可以改变这一默认行为。如果我们想要使用另外一张图片来作为ActionBar的图标,可以在<application>或者<activity>中通过logo属性来进行指定。比如项目的res/drawable目录下有一张weather.png图片,就可以在AndroidManifest.xml中这样指定:
    <activity
        android:name="com.example.actionbartest.MainActivity"
        android:logo="@drawable/weather" >
    </activity>
    现在重新运行一下程序,效果如下图所示:



    OK,ActionBar的图标已经修改成功了,那么标题中的内容该怎样修改呢?其实也很简单,使用label属性来指定一个字符串就可以了,如下所示:
    <activity
        android:name="com.example.actionbartest.MainActivity"
        android:label="天气"
        android:logo="@drawable/weather" >
    </activity>
    现在重新运行一下程序,结果如下图所示:



    添加Action按钮


    ActionBar还可以根据应用程序当前的功能来提供与其相关的Action按钮,这些按钮都会以图标或文字的形式直接显示在ActionBar上。当然,如果按钮过多,ActionBar上显示不完,多出的一些按钮可以隐藏在overflow里面(最右边的三个点就是overflow按钮),点击一下overflow按钮就可以看到全部的Action按钮了。

    当Activity启动的时候,系统会调用Activity的onCreateOptionsMenu()方法来取出所有的Action按钮,我们只需要在这个方法中去加载一个menu资源,并把所有的Action按钮都定义在资源文件里面就可以了。

    那么我们先来看下menu资源文件该如何定义,代码如下所示:
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        tools:context="com.example.actionbartest.MainActivity" >
    
        <item
            android:id="@+id/action_compose"
            android:icon="@drawable/ic_action_compose"
            android:showAsAction="always"
            android:title="@string/action_compose"/>
        <item
            android:id="@+id/action_delete"
            android:icon="@drawable/ic_action_delete"
            android:showAsAction="always"
            android:title="@string/action_delete"/>
        <item
            android:id="@+id/action_settings"
            android:icon="@drawable/ic_launcher"
            android:showAsAction="never"
            android:title="@string/action_settings"/>
    
    </menu>
    可以看到,这里我们通过三个<item>标签定义了三个Action按钮。<item>标签中又有一些属性,其中id是该Action按钮的唯一标识符,icon用于指定该按钮的图标,title用于指定该按钮可能显示的文字(在图标能显示的情况下,通常不会显示文字),showAsAction则指定了该按钮显示的位置,主要有以下几种值可选:always表示永远显示在ActionBar中,如果屏幕空间不够则无法显示,ifRoom表示屏幕空间够的情况下显示在ActionBar中,不够的话就显示在overflow中,never则表示永远显示在overflow中。
    接着,重写Activity的onCreateOptionsMenu()方法,代码如下所示:
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	MenuInflater inflater = getMenuInflater();
    	inflater.inflate(R.menu.main, menu);
    	return super.onCreateOptionsMenu(menu);
    }
    这部分代码很简单,仅仅是调用了MenuInflater的inflate()方法来加载menu资源就可以了。现在重新运行一下程序,结果如下图所示:



    可以看到,action_compose和action_delete这两个按钮已经在ActionBar中显示出来了,而action_settings这个按钮由于showAsAction属性设置成了never,所以被隐藏到了overflow当中,只要点击一下overflow按钮就可以看到它了。

    这里我们注意到,显示在ActionBar上的按钮都只有一个图标而已,我们在title中指定的文字并没有显示出来。没错,title中的内容通常情况下只会在overflow中显示出来,ActionBar中由于屏幕空间有限,默认是不会显示title内容的。但是出于以下几种因素考虑,即使title中的内容无法显示出来,我们也应该给每个item中都指定一个title属性:
    • 当ActionBar中的剩余空间不足的时候,如果Action按钮指定的showAsAction属性是ifRoom的话,该Action按钮就会出现在overflow当中,此时就只有title能够显示了。
    • 如果Action按钮在ActionBar中显示,用户可能通过长按该Action按钮的方式来查看到title的内容。


    响应Action按钮的点击事件


    当用户点击Action按钮的时候,系统会调用Activity的onOptionsItemSelected()方法,通过方法传入的MenuItem参数,我们可以调用它的getItemId()方法和menu资源中的id进行比较,从而辨别出用户点击的是哪一个Action按钮,比如:
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    	switch (item.getItemId()) {
    	case R.id.action_compose:
    		Toast.makeText(this, "Compose", Toast.LENGTH_SHORT).show();
    		return true;
    	case R.id.action_delete:
    		Toast.makeText(this, "Delete", Toast.LENGTH_SHORT).show();
    		return true;
    	case R.id.action_settings:
    		Toast.makeText(this, "Settings", Toast.LENGTH_SHORT).show();
    		return true;
    	default:
    		return super.onOptionsItemSelected(item);
    	}
    }
    可以看到,我们让每个Action按钮被点击的时候都弹出一个Toast,现在重新运行一下代码,结果如下图所示:




    通过Action Bar图标进行导航


    启用ActionBar图标导航的功能,可以允许用户根据当前应用的位置来在不同界面之间切换。比如,A界面展示了一个列表,点击某一项之后进入了B界面,这时B界面就应该启用ActionBar图标导航功能,这样就可以回到A界面。

    我们可以通过调用setDisplayHomeAsUpEnabled()方法来启用ActionBar图标导航功能,比如:
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
    	setTitle("天气");
    	setContentView(R.layout.activity_main);
    	ActionBar actionBar = getActionBar();
    	actionBar.setDisplayHomeAsUpEnabled(true);
    }
    现在重新运行一下程序,结果如下图所示:



    可以看到,在ActionBar图标的左侧出现了一个向左的箭头,通常情况下这都表示返回的意思,因此最简单的实现就是在它的点击事件里面加入finish()方法就可以了,如下所示:
    	@Override
    	public boolean onOptionsItemSelected(MenuItem item) {
    		switch (item.getItemId()) {
    		case android.R.id.home:
    			finish();
    			return true;
    		……
    		}
    	}
    当点击ActionBar图标的时候,系统同样会调用onOptionsItemSelected()方法,并且此时的itemId是android.R.id.home,所以finish()方法也就是加在这里的了。
    现在看上去,ActionBar导航和Back键的功能貌似是一样的。没错,如果我们只是简单地finish了一下,ActionBar导航和Back键的功能是完全一样的,但ActionBar导航的设计初衷并不是这样的,它和Back键的功能还是有一些区别的,举个例子吧。



    上图中的Conversation List是收件箱的主界面,现在我们点击第一封邮件会进入到Conversation1 details界面,然后点击下一封邮件会进入到Conversation 2 details界面,再点击下一封邮箱会进入到Conversation3 details界面。好的,这个时候如果我们按下Back键,应该会回到Conversation 2 details界面,再按一次Back键应该回到Conversation1 details界面,再按一次Back键才会回到Conversation List。而ActionBar导航则不应该表现出这种行为,无论我们当前在哪一个Conversation details界面,点击一下导航按钮都应该回到Conversation List界面才对。

    这就是ActionBar导航和Back键在设计上的区别,那么该怎样才能实现这样的功能呢?其实并不复杂,实现标准的ActionBar导航功能只需三步走。

    第一步我们已经实现了,就是调用setDisplayHomeAsUpEnabled()方法,并传入true。

    第二步需要在AndroidManifest.xml中配置父Activity,如下所示:
    <activity
        android:name="com.example.actionbartest.MainActivity"
        android:logo="@drawable/weather" >
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="com.example.actionbartest.LaunchActivity" />
    </activity>
    可以看到,这里通过meta-data标签指定了MainActivity的父Activity是LaunchActivity,在Android 4.1版本之后,也可以直接使用android:parentActivityName这个属性来进行指定,如下所示:
    <activity
        android:name="com.example.actionbartest.MainActivity"
        android:logo="@drawable/weather"
        android:parentActivityName="com.example.actionbartest.LaunchActivity" >
    </activity>
    第三步则需要对android.R.id.home这个事件进行一些特殊处理,如下所示:
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    	switch (item.getItemId()) {
    	case android.R.id.home:
    		Intent upIntent = NavUtils.getParentActivityIntent(this);
    		if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
    			TaskStackBuilder.create(this)
    					.addNextIntentWithParentStack(upIntent)
    					.startActivities();
    		} else {
    			upIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    			NavUtils.navigateUpTo(this, upIntent);
    		}
    		return true;
            ......
    	}
    }
    其中,调用NavUtils.getParentActivityIntent()方法可以获取到跳转至父Activity的Intent,然后如果父Activity和当前Activity是在同一个Task中的,则直接调用navigateUpTo()方法进行跳转,如果不是在同一个Task中的,则需要借助TaskStackBuilder来创建一个新的Task。

    这样,就按照标准的规范成功实现ActionBar导航的功能了。

    添加Action View


    ActionView是一种可以在ActionBar中替换Action按钮的控件,它可以允许用户在不切换界面的情况下通过ActionBar完成一些较为丰富的操作。比如说,你需要完成一个搜索功能,就可以将SeachView这个控件添加到ActionBar中。

    为了声明一个ActionView,我们可以在menu资源中通过actionViewClass属性来指定一个控件,例如可以使用如下方式添加SearchView:
    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <item
            android:id="@+id/action_search"
            android:icon="@drawable/ic_action_search"
            android:actionViewClass="android.widget.SearchView"
            android:showAsAction="ifRoom|collapseActionView"
            android:title="@string/action_search" />
        ......
    
    </menu>
    注意在showAsAction属性中我们还声明了一个collapseActionView,这个值表示该控件可以被合并成一个Action按钮。
    现在重新运行一下程序,效果如下图所示:



    OK,果然有一个搜索样式的Action按钮出现了,现在点击一下这个搜索按钮,效果如下图所示:



    可以看到,这时SearchView就会展开占满整个ActionBar,而其它的Action按钮由于将showAsAction属性设置成了ifRoom,此时都会隐藏到overflow当中。

    如果你还希望在代码中对SearchView的属性进行配置(比如添加监听事件等),完全没有问题,只需要在onCreateOptionsMenu()方法中获取该ActionView的实例就可以了,代码如下所示:
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	MenuInflater inflater = getMenuInflater();
    	inflater.inflate(R.menu.main, menu);
    	MenuItem searchItem = menu.findItem(R.id.action_search);
    	SearchView searchView = (SearchView) searchItem.getActionView();
    	// 配置SearchView的属性
    	......
    	return super.onCreateOptionsMenu(menu);
    }
    在得到了SearchView的实例之后,就可以任意地配置它的各种属性了。关于SearchView的更多详细用法,可以参考官方文档 http://developer.android.com/guide/topics/search/search-dialog.html 。

    除此之外,有些程序可能还希望在ActionView展开和合并的时候显示不同的界面,其实我们只需要去注册一个ActionView的监听器就能实现这样的功能了,代码如下所示:
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	MenuInflater inflater = getMenuInflater();
    	inflater.inflate(R.menu.main, menu);
    	MenuItem searchItem = menu.findItem(R.id.action_search);
    	searchItem.setOnActionExpandListener(new OnActionExpandListener() {
    		@Override
    		public boolean onMenuItemActionExpand(MenuItem item) {
    			Log.d("TAG", "on expand");
    			return true;
    		}
    		
    		@Override
    		public boolean onMenuItemActionCollapse(MenuItem item) {
    			Log.d("TAG", "on collapse");
    			return true;
    		}
    	});
    	return super.onCreateOptionsMenu(menu);
    }
    可以看到,调用MenuItem的setOnActionExpandListener()方法就可以注册一个监听器了,当SearchView展开的时候就会回调onMenuItemActionExpand()方法,当SearchView合并的时候就会调用onMenuItemActionCollapse()方法,我们在这两个方法中进行相应的UI操作就可以了。

    Overflow按钮不显示的情况


    虽然现在我们已经掌握了不少ActionBar的用法,但是当你真正去使用它的时候还是可能会遇到各种各样的问题,比如很多人都会碰到overflow按钮不显示的情况。明明是同样的一份代码,overflow按钮在有些手机上会显示,而在有些手机上偏偏就不显示,这是为什么呢?后来我总结了一下,overflow按钮的显示情况和手机的硬件情况是有关系的,如果手机没有物理Menu键的话,overflow按钮就可以显示,如果有物理Menu键的话,overflow按钮就不会显示出来。比如我们启动一个有Menu键的模拟器,然后将代码运行到该模拟器上,结果如下图所示:



    可以看到,ActionBar最右边的overflow按钮不见了!那么此时我们如何查看隐藏在overflow中的Action按钮呢?其实非常简单,按一下Menu键,隐藏的内容就会从底部出来了,如下图所示:



    看到这里相信不少朋友都想吐槽一下了,这显然是一种非常蛋疼的设计,在不同手机上竟然显示了不同的界面,而且操作方法也完全不一样,这样会给用户一种非常不习惯的感觉。话说Google为什么要把ActionBar的overflow设计成这样我也不太理解,但是我们还是有办法改变这一默认行为的。

    实际上,在ViewConfiguration这个类中有一个叫做sHasPermanentMenuKey的静态变量,系统就是根据这个变量的值来判断手机有没有物理Menu键的。当然这是一个内部变量,我们无法直接访问它,但是可以通过反射的方式修改它的值,让它永远为false就可以了,代码如下所示:
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    	......
    	setOverflowShowingAlways();
    }
    
    private void setOverflowShowingAlways() {
    	try {
    		ViewConfiguration config = ViewConfiguration.get(this);
    		Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
    		menuKeyField.setAccessible(true);
    		menuKeyField.setBoolean(config, false);
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    }
    这里我们在onCreate()方法的最后调用了setOverflowShowingAlways()方法,而这个方法的内部就是使用反射的方式将sHasPermanentMenuKey的值设置成false,现在重新运行一下代码,结果如下图所示:



    可以看到,即使是在有Menu键的手机上,也能让overflow按钮显示出来了,这样就可以大大增加我们软件界面和操作的统一性。

    让Overflow中的选项显示图标


    如果你点击一下overflow按钮去查看隐藏的Action按钮,你会发现这部分Action按钮都是只显示文字不显示图标的,如下图所示:



    这是官方的默认效果,Google认为隐藏在overflow中的Action按钮都应该只显示文字。当然,如果你认为这样不够美观,希望在overflow中的Action按钮也可以显示图标,我们仍然可以想办法来改变这一默认行为。

    其实,overflow中的Action按钮应不应该显示图标,是由MenuBuilder这个类的setOptionalIconsVisible方法来决定的,如果我们在overflow被展开的时候给这个方法传入true,那么里面的每一个Action按钮对应的图标就都会显示出来了。调用的方法当然仍然是用反射了,代码如下所示:
    @Override
    public boolean onMenuOpened(int featureId, Menu menu) {
    	if (featureId == Window.FEATURE_ACTION_BAR && menu != null) {
    		if (menu.getClass().getSimpleName().equals("MenuBuilder")) {
    			try {
    				Method m = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
    				m.setAccessible(true);
    				m.invoke(menu, true);
    			} catch (Exception e) {
    			}
    		}
    	}
    	return super.onMenuOpened(featureId, menu);
    }
    可以看到,这里我们重写了一个onMenuOpened()方法,当overflow被展开的时候就会回调这个方法,接着在这个方法的内部通过返回反射的方法将MenuBuilder的setOptionalIconsVisible变量设置为true就可以了。

    现在重新运行一下代码,结果如下图所示:



    好了,目前为止我们已经把ActionBar的基础知识介绍完了,那么今天的讲解就到这里,下篇文章中我会带领大家一起更深入地了解ActionBar,感兴趣的朋友请继续阅读 Android ActionBar完全解析,使用官方推荐的最佳导航栏(下)

    关注我的技术公众号,每天都有优质技术文章推送。关注我的娱乐公众号,工作、学习累了的时候放松一下自己。

    微信扫一扫下方二维码即可关注:

            

    展开全文
  • ActionBar

    千次阅读 2016-05-07 19:44:58
    1.在res/menu下建立main.xml android:id="@+id/action_share" android:actionProviderClass="android.widget.ShareActionProvider" android:showAsAction="ifRoom" andr

    1.在res/menu下建立main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
        <item
            android:id="@+id/action_share"
            android:actionProviderClass="android.widget.ShareActionProvider"
            android:showAsAction="ifRoom"
            android:title="share"/>
        <item
            android:id="@+id/action_search"
            android:icon="@drawable/ic_action_search"
            android:showAsAction="ifRoom"
            android:title="search"/>
        <item
            android:id="@+id/action_setting"
            android:showAsAction="never"
            android:title="setting"/>
        <item
            android:id="@+id/action_help"
            android:showAsAction="never"
            android:title="help"/>
    </menu>
    解释:

    1.1.android:actionProviderClass="android.widget.ShareActionProvider"

    分享图标是Android自带的。

    为了实现ShareActionprovider的分享功能,我们必须实现一个分享的Intent。这个Intent除了包括ACTION_SEND和extras等其他Intent向其他应用传输内容所须要的内容外,还须要上面的内容。在你的Activity或Fragment中充填你的单菜资源时,须要找到 MenuItem,用使MenuItem.getActionProvider到得ShareActionProvider实例,通过setShareProvider来更新分享的Intent。

        actionProviderClass实现,下面会有详细说明

    1.2.android:showAsAction="ifRoom"

    1.3.Android自带的ActionBar的样式选择

    1.3.1.AndroidManifest.xml

    android:theme="@style/AppTheme"  //样式选择
    
    1.3.2.Ctrl键+鼠标点击android:theme="@style/AppTheme" 进入到styles.xml
    <resources>
        <!-- Base application theme. -->
        <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
            <!-- Customize your theme here. -->
        </style>
    
    </resources>
    这里选择的样式是android:Theme.Holo.Light.DarkActionBar

    1.3.3.Ctrl键+鼠标点击android:Theme.Holo.Light.DarkActionBar 进入到themes_hole.xml


    里面有很多的样式,可以选择。修改styles.xml的选择就可以了。

    2.MainActivity文件

    import android.app.Activity;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.ViewConfiguration;
    import java.lang.reflect.Field;
    
    public class MainActivity extends Activity {
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            try {
                ViewConfiguration config = ViewConfiguration.get(this);
                Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
                if(menuKeyField != null) {
                    menuKeyField.setAccessible(true);
                    menuKeyField.setBoolean(config, false);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    
        }
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }
    
    }
    
    解释:
    try {
                ViewConfiguration config = ViewConfiguration.get(this);
                Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");
                if(menuKeyField != null) {
                    menuKeyField.setAccessible(true);
                    menuKeyField.setBoolean(config, false);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
    原因是:现在很多手机都有自带的菜单项,所以ActionBar上的三个点自动隐藏,要是它一直显示,则把这段代码放置于onCrete方法中。



    3.实现


    @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            switch (item.getItemId()){
                //设置返回键
                case android.R.id.home:
                   
                    break;
                case R.id.action_search:
                    Toast.makeText(this, "Action_Search", Toast.LENGTH_LONG).show();
                    break;
                case R.id.action_setting:
                    Toast.makeText(this, "Action_setting", Toast.LENGTH_LONG).show();
                    break;
                case R.id.action_help:
                    Toast.makeText(this, "帮助", Toast.LENGTH_LONG).show();
                    break;
    
            }
            return super.onOptionsItemSelected(item);
        }
    



    4.设置返回键

    4.1.返回父级

    AndroidManifest.xml中添加<meta-data  ..../>

     <activity
                android:name="com.rj141.sb.actionbardemo01.MainActivity"
                android:label="@string/app_name" >
                <meta-data 
                    android:name="android.support.PARENT_ACTIVITY"
                    android:value="com.rj141.sb.actionbardemo01.ParentActivity"
                    /> 
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
            <activity android:name="ParentActivity"></activity>
    MainActivity的onCreate()方法中添加

    //Android  3.0以上版本用getActionbar()  3.0以下getSupportActionBar()
            getActionBar().setDisplayHomeAsUpEnabled(true);

    4.2.返回上一级

    MainActivity的onCreate()方法中添加

    //Android  3.0以上版本用getActionbar()  3.0以下getSupportActionBar()
            getActionBar().setDisplayHomeAsUpEnabled(true);
    在onOptionsItemSelected(MenuItem item)中,补充


    //设置返回键
                case android.R.id.home:
                    finish();
                    break;



    5.Provider

    在main.xml中设置

    <item
            android:id="@+id/action_share"
            android:actionProviderClass="android.widget.ShareActionProvider"
            android:showAsAction="ifRoom"
            android:title="share"/>
    MainActivity

    private ShareActionProvider mShareActionProvider;
    @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.main, menu);
            MenuItem shareItem = menu.findItem(R.id.action_share);
            mShareActionProvider = (ShareActionProvider) shareItem.getActionProvider();
            mShareActionProvider.setShareIntent(getDefaultIntent());
            return true;
        }
        private Intent getDefaultIntent(){
            Intent intent = new Intent(Intent.ACTION_SEND);
            intent.setType("image/*");
            return intent;
        }

    6.自定义ActionBar的样式


    在values.xml中,创建themes.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources xmlns:android="http://schemas.android.com/apk/res/android">
        <!-- 定义style,继承已有的style -->
        <style name="CustomActionBarTheme" parent="@android:style/Theme.Holo.Light.DarkActionBar">
            <!-- 复写actionBarStyle,指向已复写的background -->
            <item name="android:actionBarStyle">@style/CustomBackground</item>
        </style>
    
        <style name="CustomBackground" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse">
            <!-- 复写background -->
            <item name="android:background">@drawable/action_background</item>
        </style>
    <pre name="code" class="html"> 
    <!-- 另一个样式 -->
     <style name="CustomActionBarOverlayTheme" parent="@android:style/Theme.Holo" > <item name="android:windowActionBarOverlay">true</item> </style></resources>

    AndroidManifest.xml引用
    

    android:theme="@style/CustomActionBarTheme">







    展开全文
  • Android UI开发第二十四篇——Action Bar

    万次阅读 多人点赞 2014-08-05 15:26:27
    Action bar是一个标识应用程序和用户位置的窗口功能,并且给用户提供操作和导航模式。...你能够用ActionBar的对象的API来控制操作栏的行为和可见性,这些API被添加在Android3.0(API 级别 11)中。


                 Action bar是一个标识应用程序和用户位置的窗口功能,并且给用户提供操作和导航模式。在大多数的情况下,当你需要突出展现用户行为或全局导航的activity中使用action bar,因为action bar能够使应用程序给用户提供一致的界面,并且系统能够很好根据不同的屏幕配置来适应操作栏的外观。你能够用ActionBar的对象的API来控制操作栏的行为和可见性,这些API被添加在Android3.0(API 级别 11)中。

          Action bar的主要目的是:

            1.  提供一个用于识别应用程序的标示和用户的位置的专用空间。

             这个空间的左边是应用的图标或logo,以及Activity的标题。但是,如果是像当前选择的标签这样的标识当前View对象的导航标签,你可以选择删除Activity的标题。

            2.  在不同的应用程序之间提供一致的导航和视觉体验。

            Action bar提供了用于Fragment间切换的内置导航标签。它还提供了一个用于替换导航模式或优化当前视觉效果(如按照不同条件排序的列表)的下拉列表。

            3.  突出Activity的关键操作(如“搜索”、“创建”、“共享”等),并且在可预见的方法内给用户提供快捷的访问。

           对于关键的用户操作,你能够通过把选项菜单项作为操作项直接放到操作栏中,从而提供快捷的访问。操作项目还能提供一个操作窗口,这个窗口给更直接的操作行为提供一个嵌入的窗口部件。没有改进成操作项的菜单项在溢出菜单中还是有效的,用户既可以使用设备上的菜单按钮(设备上有按钮的时候),也可以使用操作栏中的溢出菜单按钮(当设备上不包含菜单按钮时)来显示这些操作项目。

           上面的总结一下:Action bar就是替换3.0以前的tittle bar和menu。

                 

            图1. Honeycomb Gallery应用中的操作栏,从左边开始,依次是logo、导航选项标签和操作项(在右边插入的一个悬浮菜单按钮)。

             Note: If you're looking for information about the contextual action bar for displaying contextual action items, see the Menu guide.

            Action Bar Design   For design guidelines, read Android Design's Action Bar guide.


    添加Action Bar

           从Android3.0(API级别 11)开始,Action bar被包含在所有的使用Theme.Hole主题的Activity(或者是这些Activity的子类)中,当targetSdkVersion或minSdkVersion属性被设置为“11”或更大的数值是,这个主题是默认的主题一。如:

    <manifest ... >
        <uses-sdk android:minSdkVersion="4"
                  android:targetSdkVersion="11" />
        ...
    </manifest>

           在这个例子中,应用程序要求最小的API版本级别是4(Android 1.6),但是它还要求了目标API版本级别是11(Android 3.0)。这样,当应用程序运行在Android3.0或更高的版本上时,系统就会给每个Activity应用holographic  主题,这样,每个Activity就会包含Action bar。

            如果你想使用ActionBar API来进行添加导航模式和修改操作栏样式的操作,你应该把minSdkVersion属性设置为“11”或更大的值。有一些方法可以使你的应用支持更旧的Android版本,同时在API等级为11或更高的API等级的机器的使你的应用支持一些Action bar apis。为了保持后向兼容,请参考边框内的内容(边框内容如下)。

    Remaining backward-compatible

    If you want to provide an action bar in your application and remain compatible with versions of Android older than 3.0, you need to create the action bar in your activity's layout (because theActionBar class is not available on older versions).

    To help you, the Action Bar Compatibility sample app provides an API layer and action bar layout that allows your app to use some of theActionBar APIs and also support older versions of Android by replacing the traditional title bar with a custom action bar layout.

    删除Action bar

          如果你不想要Action bar,把Activity的主题设置为Theme.Holo.NoActionBar就可以了,如:

    <activity android:theme="@android:style/Theme.Holo.NoActionBar">
             或者使用Action bar的 hide()方法,如下:

    ActionBar actionBar = getActionBar();
    actionBar.hide();

           当Action bar隐藏时,系统会调整你的Activity来填充当前有效的屏幕空间。你能够使用show()方法来再次显示操作栏。

          在隐藏和删除Action bar时,要当心为了适应被Action bar占用的空间而导致的Activity的重新布局。如果你的Activity有规律的隐藏和显示Action bar,你可能想要使用覆盖模式。覆盖模式在Activity的顶部描画操作栏,而不是在它们所拥有的屏幕的区域。这样,在Action bar隐藏和重新显示时,你的布局保持不变。要使用覆盖模式,就要给Activity创建一个主题,并且把android:windowActionBarOverlay属性设置为true。

           提示:如果你有一个删除了Action bar的定制化的Activity主题,它把android:windowActionBar样式属性设置为false。但是,如果你使用了删除Action bar的一个主题,那么,创建窗口将不允许Action bar再显示,因此,你不能在以后给这个Activity添加Action bar---因为getActionBar()方法将返回null。


    添加操作项

           有些时候,你可能想要让用户直接访问选项菜单中的一个项目,因此你要把应该在Action bar中显示的菜单项作为一个操作项来声明。操作项能够能够包含一个图标或文本标题。如果一个菜单项不作为一个操作项显示,那么系统就会把它放到悬浮菜单中。悬浮菜单既可以通过设备的Menu按钮来显示,也可以在Action bar中一个额外的按钮来显示。

           当Activity首次启动时,系统会调用onCreateOptionsMenu()方法给你的Activity组装Action bar和悬浮菜单。在这个回调方法中应该加载在XML文件中定义的菜单项资源,如:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main_activity, menu);
        return true;
    }

                 

             图2. 带有图标和文本标题的两个操作项,和悬浮菜单按钮。

           在XML文件中,你能够通过给<item>元素声明android:showAsAction=”ifRoom”属性,请求把一个菜单项作为一个操作项来显示。用这种方式,只在有有效的空间时,菜单项才能显示在Action bar中。如果没有足够的空间,这个菜单项会显示在悬浮菜单中。

            如果你的菜单项支持标题和图标---带有android:title和android:icon属性---那么默认情况下,操作项仅显示图标。如果你要显示文本标题,就要给android:showAsAction属性添加withText设置,如:

      

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

    提示:withText值示意Action bar要显示文本标题。Action bar会尽可能的显示这个标题,但是,如果图标有效并且受到Action bar空间的限制,文本标题有可能显示不全。

    当用户选择了一个操作项时,Activity会接收一个onOptionsItemSelected()的回调,要把android:id属性支持的ID传递给这个方法。

    给每个菜单项定义android:title属性是至关重要的,即使你没有给操作项声明标题。原因如下:

    1.  如果Action bar中没有足够的空间来显示操作项,那么菜单项就会显示在悬浮菜单中,并仅显示标题;

    2.  屏幕阅读器要给视障用户朗读菜单项标题;

    3.  如果仅用图标来显示操作项,那么,用户能够长按这个项目,用操作项的标题来显示提示信息。

    注意:如果你添加源于Fragment对象的菜单项,那么通过Fragment类的onCreateOptionsMenu onCreateOptionsMenu回调方法,当用户选择其中一个Fragment菜单项时,系统会对用那个Fragment对象对应的onOptionsItemSelected()方法。但是,Activity有机会首先处理这个事件,因为系统在调用对应的Fragment对象的onOptionsItemSelected()方法之前会调用Activity的相同的回调方法。

           你也能够声明一个菜单项,让它始终作为操作项来显示,而不是在空间不足时就放到悬浮菜单中。大多数情况下,你不应该使用always属性值来强制一个菜单项始终显示在操作栏中,但是,当提供了一个不给悬浮菜单提供默认操作的操作窗口时,你就需要始终显示一个菜单项。但是要警惕,太多的操作项会创建一个混乱的UI,并且会导致窄屏设备上的布局问题。最好的方法是使用ifRoom属性值,它允许系统在操作栏空间不足的时候,把菜单项移到悬浮菜单中。

    选择操作项:

           通过评估一些关键的特性,你应该仔细的选择选项菜单中的那些菜单项应该作为操作项来显示,通常,每个操作项应该至少满足下列特性之一:

            1.  经常使用:用户百分之七十以上的访问都需要使用的操作,或者是要连续的多次使用的操作。

            2.  重要:它是一个用户能够很容易找到的操作,即使它不是经常性的操作,也需要用户在需要的时候能够轻易的找到它,并执行。

                 如,Wi-Fi设置中的添加网络等。

            3.  典型:它是一些类似应用程序的操作栏中提供的典型操作,因此,用户都期望在操作栏中能够找到它。

                如,电子邮件或社交应用程序中的“刷新”操作。

            如果你想要把四个以上的菜单项调整为操作项,那么你就应该认真考虑一下他们相对的重要性级别,并且尝试不要超过四个以上的操作项设置(并且还有使用“ifRoom”属性值的设置,允许系统在遇到空间受限的比较小的屏幕的时候,能够把靠后的操作项放到悬浮菜单中)。即使在一些宽屏设备上,空间充足,你也不应该创建很多操作项,这样会扰乱UI的布局,而且更像一个桌面工具栏,因此要保持最小数量的操作项。

           另外,以下操作应该永远不要作为操作项来显示:设置、帮助、意见反馈、或类似的操作。要把它们始终保留在悬浮菜单中。

           注意:不是所有的设备都给检索提供了专有的硬件按钮,因此,如果是你应用程序中的一个重要功能,它应该始终作为一个操作项来显示(而且通常要把放到第一项的位置,尤其是操作窗口中提供这个操作的时候)。

    使用分离式操作栏

            当你的应用程序正在Android4.0(API 级别 14)或以上的版本上运行,那么还有一种叫做“分隔操作栏”的额外模式对action bar有效。当你启用分隔操作栏模式时,在屏幕的底部会显示一个独立的横条,用于显示Activity在窄屏设备(如竖屏手机)上运行时的所有操作项。

           把action bar分隔成独立的操作项,确保在窄屏设备上有合适的空间来显示所有的操作项,同时把导航条和标题元素留在顶部。

           要启用分离式操作栏,只需简单的在<application>或<activity>元素中添加uiOptions=”splitActionBarWhenNarrow”属性设置就可以了。

           要注意,Android会基于当前屏幕的尺寸用各种方式来调整操作栏的外观。使用分离式操作栏只是你能够启用的允许操作栏针对不同屏幕尺寸来进一步优化用户体验的选项之一。你还可以允许操作栏把导航选项标签折叠到主操作栏中,如果你在操作栏中使用导航选项标签,那么一旦操作项在窄屏设备上被分离,这些导航选项标签就可能填充到主操作栏中,而不是被分离到堆叠起来的操作栏。尤其是如果你禁用了操作栏的图标和标题(用setDisplayShowHomeEnabled(false)setDisplayShowTitleEnabled(false)方法),那么导航选项标签就会折叠到主操作栏中,如下图3中第二个设备的显示:

                           

    图3. 左侧是带有导航选项标签的分离式操作栏,右侧是禁用了应用图标和标题的分离式操作栏。

    注意:尽管android:uiOptions属性在Android4.0(API 级别 14)中才被添加,但是为了保持跟Android的低版本的兼容性,即使你的minSdkVersion属性值小于14,那么你的应用程序也可以安全的包含android:uiOptions属性。在旧版本上运行时,因为系统不能理解这个属性,所以只是简单的忽略了这个XML属性。在你的清单文件中包含这个属性的唯一条件是,你必须在支持API级别14或更高以上版本的平台上编译你的应用程序。为了保持兼容性,你不能在你的应用程序代码中使用由minSdkVersion属性声明的版本所不支持的API,只有XML属性才能被旧的平台版本安全的忽略。

    导航栏使用应用图标

           默认情况下,应用程序图标显示在操作栏的左边。你能够把这个图标当做操作项来使用。应用程序应该在这个图标上响应以下两个操作之一:

           1.  返回应用程序的“主”Activity;

           2.  向应用程序上级页面导航。

           当用户触摸这个图标时,系统会调用Activity带有android.R.id.home ID的onOptionsItemSelected()方法。在这个响应中,你既可以启动主Activity,也可以返回你的应用程序结构化层次中用户上一步操作的界面。

           如果你要通过应用程序图标的响应来返回主Activity,那么就应该在Itent对象中包括FLAG_ACTIVITY_CLEAR_TOP标识。用这个标记,如果你要启动的Activity在当前任务中已经存在,那么,堆栈中这个Activity之上的所有的Activity都有被销毁,并且把这个Activity显示给用户。添加这个标识往往是重要的,因为返回主Activity相当与一个回退的动作,因此通常不应该再创建一个新的主Activity的实例,否则,最终可能会在当前任务中产生一个很长的拥有多个主Activity的堆栈。

    例如,下例的onOptionsItemSelected()方法实现了返回应用程序的主Activity的操作:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                // app icon in action bar clicked; go home
                Intent intent = new Intent(this, HomeActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }
           在用户从另一个应用程序进入当前Activity的情况下,你可能还想要添加FLAG_ACTIVITY_NEW_TASK标识。这个标识确保在用户返回主页或上级页面时,新的Activity不会被添加到当前的任务中,而是在属于你自己的应用程序的任务中启动。例如,如果用户通过被另一个应用程序调用的Intent对象启动了你的应用程序中的一个Activity,那么选择操作栏图标来返回主页或上级页面时,FLAG_ACTIVITY_CLEAR_TOP标识会在属于你的应用程序的任务中启动这个Activity(不是当前任务)。系统既可以用这个新的Activity做根Activity来启动一个新的任务,也可以把存在后台的拥有这个Activity实例的一个既存任务带到前台来,并且目标Activity会接受onNewIntent()回调。因此,如果你的Activity要接收另一个应用程序的Intent对象,那么通常应该给这个Intent对象添加FLAG_ACTIVITY_NEW_TASK标识,如:
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);

    注意:如果你要使用应用图标来返回主页,要注意从Android4.0(API 级别 14)开始,必须通过调用setHomeButtonEnabled(true)方法确保这个图标能够作为一个操作项(在以前的版本,默认情况下,这个图标就能够作为一个操作项)。

    向应用程序上级页面导航

           作为传统的回退导航(把用户带回任务历史中的前一个窗口)的补充,你能够让action bar图标提供向上级页面导航的功能,它应用把用户带回到你的应用程序的上级页面。例如,当前页面时你的应用程序层次比较深的一个页面,触摸应用程序图标应该返回返回上一级页面(当前页面的父页面)。
              
             图4. Email应用程序的标准图标(左)和向上导航图标(右)。系统会自动添加向上指示。
           例如,图5演示了当用户从一个应用程序导航到一个属于不同应用程序的Activity时,“回退”按钮的行为。

                

           但是,如果在编辑完邮件之后,想要停留在Email应用程序中,那么向上导航就允许你把用户导航到Email应用程序中编辑邮件页面的上级页面,而不是返回到前一个Activity。图6演示了这种场景,在这个场景中,用户进入到Email应用程序后,不是按回退按钮,而是按操作栏图标来向上导航。

           

             图6. 从People应用进入Email应用后,向上导航的行为。

             要是应用程序图标能够向上导航,就要在你的ActionBar中调用SetDisplayHomeAsUpEnabledtrue(true)方法。

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        setContentView(R.layout.main);
        ActionBar actionBar = getActionBar();
        actionBar.setDisplayHomeAsUpEnabled(true);
        ...
    }

           当用户触摸这个图标时,系统会调用带有android.R.id.home ID的onOptionsItemSelected()方法。

           请记住要在Intent对象中使用FLAG_ACTIVITY_CLEAR_TOP标识,以便你不会这个父Activity存在的情况下,再创建一个新的实例。例如,如果你不使用FLAG_ACTIVITY_CLEAR_TOP标识,那么向上导航后,再按回退按钮,实际上会把用户带到应用程序的下级页面,这是很奇怪的。

    注意:如果有很多用户能够到达应用程序中当前Activity的路径,那么,向上图标应该沿着当前Activity的实际启动路径逐步的向会导航。

    添加操作视窗

           操作视窗是作为操作项目按钮的替代品显示在操作栏中的一个可视构件。例如,如果你有一个用于搜索的可选菜单项,你可以用SearchView类来替代操作栏上的搜索按钮,如图7所示:

                 

           图7. 折叠(上)和展开(下)的搜索视窗的操作栏

           要个菜单资源中的一个项目声明一个操作视窗,你既可以使用android:actionLayout属性也android:actionViewClass属性来分别指定一个布局资源或要使用的可视构件类。例如:

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:id="@+id/menu_search"
              android:title="@string/menu_search"
              android:icon="@drawable/ic_menu_search"
              android:showAsAction="ifRoom|collapseActionView"
              android:actionViewClass="android.widget.SearchView" />
    </menu>

            android:showAsAction属性也可包含“collapseActionView”属性值,这个值是可选的,并且声明了这个操作视窗应该被折叠到一个按钮中,当用户选择这个按钮时,这个操作视窗展开。否则,这个操作视窗在默认的情况下是可见的,并且即便在用于不适用的时候,也要占据操作栏的有效空间。

           如果需要给操作视窗添加一些事件,那么就需要在onCreateOptionsMenu()回调执行期间做这件事。你能够通过调用带有菜单项ID的findItem()方法来获取菜单项,然后再调用getActionView()方操作视窗中的元素。例如,使用以下方法获取上例中的搜索视窗构件。

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.options, menu);
        SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
        // Configure the search info and add any event listeners
        ...
        return super.onCreateOptionsMenu(menu);
    }

    处理可折叠的操作视窗

            操作视窗让你在不改变Activity或Fragment的情况下,就可以给用户提供快捷的访问和丰富的操作。但是,默认情况下让操作视窗可见可能不太合适。要保证操作栏的空间(尤其是在小屏幕设备上运行时),你能够把操作视窗折叠进一个操作项按钮中。当用户选择这个按钮时,操作视窗就在操作栏中显示。被折叠的时候,如果你定义了android:showAsAction=”ifRoom”属性,那么系统可能会把这个项目放到溢出菜单中,但是当用户选项了这个菜单项,它依然会显示在操作栏中。通过给android:showAsAction属性添加“collapseActionView”属性值,你能够让操作视窗可以折叠起来。

            因为在用户选择这个项目时,系统会展开这个操作视窗,所以你不必要在onOptionsItemSelected()回调方法中响应这个菜单项。在用户选择这个菜单项时,系统会依然调用onOptionsItemSelected()方法,但是除非你在方法中返回了true(指示你已经替代系统处理了这个事件),否则系统会始终展开这个操作视窗。

           当用户选择了操作栏中的“向上”图标或按下了回退按钮时,系统也会把操作视窗折叠起来。

    如果需要,你能够在代码中通过在expandActionView()和collapseActionView()方法来展开或折叠操作视窗。

           注意:尽管把操作视窗折叠起来是可选的,但是,如果包含了SearchView对象,我们推荐你始终把这个视窗折叠起来,只有在需要的时候,由用户选择后才把它给展开。在提供了专用的“搜索”按钮的设备上也要小心了,如果用户按下了“搜索”按钮,那么也应该把这个搜索视窗给展开,简单的重写Activity的onKeyUp()回调方法,监听KEYCODE_SEARCH类型的按键事件,然后调用expandActionView()方法,就可以把操作视窗给展开。

    如果你需要根据操作视窗的可见性来更新你的Activity,那么你可以定义一个OnActionExpandListener事件,并且用setOnActionExpandListener()方法来注册这个事件,然后就能够在操作视窗展开和折叠时接受这个回调方法了,如:

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.options, menu);
        MenuItem menuItem = menu.findItem(R.id.actionItem);
        ...
    
        menuItem.setOnActionExpandListener(new OnActionExpandListener() {
            @Override
            public boolean onMenuItemActionCollapse(MenuItem item) {
                // Do something when collapsed
                return true;  // Return true to collapse action view
            }
    
            @Override
            public boolean onMenuItemActionExpand(MenuItem item) {
                // Do something when expanded
                return true;  // Return true to expand action view
            }
        });
    }

    添加一个操作提供器

           与操作视窗类似,操作提供器(由ActionProvider类定义的)用一个定制的布局代替一个操作项目,它还需要对所有这些项目行为的控制。当你在操作栏中给一个菜单项声明一个操作项目时,它不仅要一个定制的布局来控制这个菜单项的外观,而且当它在显示在溢出菜单中时,还要处理它的默认事件。无论是在操作栏中还是在溢出菜单中,它都能够提供一个子菜单。

           例如,ActionProvider的扩展类ShareActionProvider,它通过在操作栏中显示一个有效的共享目标列表来方便共享操作。与使用传统的调用ACTION_SEND类型Intent对象的操作项不同,你能够声明一个ShareActionProvider对象来处理一个操作项。这种操作提供器会保留一个带有处理ACTION_SEND类型Intent对象的应用程序的下拉列表,即使这个菜单项显示在溢出菜单中。因此,当你使用像这样的操作提供器时,你不必处理有关这个菜单项的用户事件。

    要给一个操作项声明一个操作提供器,就要在菜单资源中对应的<item>元素中定义android:actionProviderClass属性,提供器要使用完整的类名。例如:

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:id="@+id/menu_share"
              android:title="@string/share"
              android:showAsAction="ifRoom"
              android:actionProviderClass="android.widget.ShareActionProvider" />
        ...
    </menu>

           在这个例子中,用ShareActionProvider类作为操作提供器,在这里,操作提供器需要菜单项的控制,并处理它们在操作栏中的外观和行为以及在溢出菜单中的行为。你必须依然给这个菜单项提供一个用于溢出菜单的文本标题。

    尽管操作提供器提供了它在溢出菜单中显示时所能执行的默认操作,但是Activity(或Fragment)也能够通过处理来自onOptionsItemSelected()回调方法的点击事件来重写这个默认操作。如果你不在这个回调方法中处理点击事件,那么操作提供器会接收onPerformDefaultAction()回调来处理事件。但是,如果操作提供器提供了一个子菜单,那么Activity将不会接收onOptionsItemSelected()回调,因为子菜单的显示替代了选择时调用的默认菜单行为。

    使用ShareActionProvider类

           如果你想要在操作栏中提供一个“共享”操作,以充分利用安装在设备上的其他应用程序(如,把一张图片共享给消息或社交应用程序使用),那么使用ShareActionProvider类是一个有效的方法,而不是添加一个调用ACTION_SEND类型Intent对象的操作项。当你给一个操作项使用ShareActionProvider类时,它会呈现一个带有能够处理ACTION_SEND类型Intent对象的应用程序的下拉列表(如图8所示)。
                    

            图8. Gallery 应用截屏,用ShareActionProvider对象展开显示共享目标。

            创建子菜单的所有逻辑,包括共享目标的封装、点击事件的处理(包在溢出菜单中的项目显示)等,都在ShareActionProvider类中实现了---你需要编写的唯一的代码是给对应的菜单项声明操作提供器,并指定共享的Intent对象。

            默认情况,ShareActionProvider对象会基于用户的使用频率来保留共享目标的排列顺序。使用频率高的目标应用程序会显示在下来列表的上面,并且最常用的目标会作为默认共享目标直接显示在操作栏。默认情况下,排序信息被保存在由DEFAULT_SHARE_HISTORY_FILE_NAME指定名称的私有文件中。如果你只使用一种操作类型ShareActionProvider类或它的一个子类,那么你应该继续使用这个默认的历史文件,而不需要做任何事情。但是,如果你使用了不同类型的多个操作的ShareActionProvider类或它的一个子类,那么为了保持它们自己的历史,每种ShareActionProvider类都应该指定它们自己的历史文件。给每种ShareActionProvider类指定不同的历史文件,就要调用setShareHistoryFileName()方法,并且提供一个XML文件的名字(如,custom_share_history.xml)

            注意:尽管ShareActionProvider类是基于使用频率来排列共享目标的,但是这种行为是可扩展的,并且ShareActionProvider类的扩展能够基于历史文件执行不同的行为和排序。

            要添加ShareActionProvider对象,只需简单的给android.actionProviderClass属性设定android.widget.ShareActionProvider属性值就可以了。唯一要做的事情是定义你要用于共享的Intent对象,你必须先调用getActionProvider()方法来获取跟菜单项匹配的ShareActionProvider对象,然后调用setShareIntent()方法。

          如果对于共享的Intent对象的格式依赖与被选择的菜单项,或其他的在Activity生存周期内改变的变量,那么你应该把ShareActionProvider对象保存在一个成员属性里,并在需要的时候调用setShareIntent()方法来更新它。如:

    private ShareActionProvider mShareActionProvider;
    ...
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        mShareActionProvider = (ShareActionProvider) menu.findItem(R.id.menu_share).getActionProvider();
    
        // If you use more than one ShareActionProvider, each for a different action,
        // use the following line to specify a unique history file for each one.
        // mShareActionProvider.setShareHistoryFileName("custom_share_history.xml");
    
        // Set the default share intent
        mShareActionProvider.setShareIntent(getDefaultShareIntent());
    
        return true;
    }
    // When you need to update the share intent somewhere else in the app, call
    // mShareActionProvider.setShareIntent()
           上例中ShareActionProvider对象处理所有的跟这个菜单项有关的用户交互,并且不需要处理来自onOptionsItemSelected()回调方法的点击事件。

    创建一个自定义的操作提供器

           当你想要创建一个有动态行为和在悬浮菜单中有默认图标的操作视窗时,继承ActionProvider类来定义这些行为是一个比好的的方案。创建自己的操作提供器,提供一个有组织的可重用的组件,而不是在Fragment或Activity的代码中处理各种操作项的变换和行为。

           要创建自己的操作提供器,只需简单的继承ActionProvider类,并且实现合适的回调方法。你应该实现以下重要的回调方法:

    ActionProvider()

            这个构造器把应用程序的Context对象传递个操作提供器,你应该把它保存在一个成员变量中,以便其他的回调方法使用。

    OnCreateActionView()

            这是你给菜单项定义操作视窗的地方。使用从构造器中接收的Context对象,获取一个LayoutInflater对象的实例,并且用XML资源来填充操作视窗,然后注册事件监听器。如:

    public View onCreateActionView() {
        // Inflate the action view to be shown on the action bar.
        LayoutInflater layoutInflater = LayoutInflater.from(mContext);
        View view = layoutInflater.inflate(R.layout.action_provider, null);
        ImageButton button = (ImageButton) view.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // Do something...
            }
        });
        return view;
    }

    onPerformDefaultAction()
             
    在选中悬浮菜单中的菜单时,系统会调用这个方法,并且操作提供器应该这对这个选中的菜单项执行默认的操作。

           但是,如果你的操作提供器提供了一个子菜单,即使是悬浮菜单中一个菜单项的子菜单,那么也要通过onPrepareSubMenu()回调方法来显示子菜单。这样onPerformDefaultAction()在子菜单显示时就不会被调用。

           注意:实现了onOptionsItemSelected()回调方法的Activity或Frament对象能够通过处理item-selected事件(并且返回true)来覆盖操作提供器的默认行为,这种情况下,系统不会调用onPerformDefaultAction()回调方法。

    添加导航选项标签

           当你想要在一个Activity中提供导航选择标签时,使用操作栏的选项标签是一个非常好的选择(而不是使用TabWidget类),因为系统会调整操作栏选项标签来适应不同尺寸的屏幕的需要---在屏幕足够宽的时候,导航选项标签会被放到主操作栏中;当屏幕太窄的时候,选项标签会被放到一个分离的横条中,如图9和图10所示。
          
              图9. Honeycomb Gallery应用程序中的操作栏选项标签的截图
          
              图10. 在窄屏设备上被堆放在操作栏中的选项标签的截屏 

           要使用选项标签在Fragmengt之间切换,你必须在每次选择一个选项标签时执行一个Fragment事务。如果你不熟悉如何使用FragmentTransaction对象来改变Fragment,请阅读Fragment开发指南。

           首先,你的布局必须包含一个用于放置跟每个Fragment对象关联的选项标签的ViewGroup对象。并且要确保这个ViewGroup对象有一个资源ID,以便你能够在选项标签的切换代码中能够引用它。另外,如果选项标签的内容填充在Activity的布局中(不包括操作栏),那么Activity不需要任何布局(你甚至不需要调用setContentView()方法)。相反,你能够把每个Fragment对象放到默认的根ViewGroup对象中,你能够用android.R.id.content ID来引用这个ViewGroup对象(在Fragment执行事务期间,你能够在下面的示例代码中看到如何使用这个ID的。

            决定了Fragment对象在布局中的显示位置后,添加选项标签的基本过程如下:

              1.  实现ActionBar.TabListener接口。这个接口中回调方法会响应选项标签上的用户事件,以便你能够切换Fragment对象;

               2.  对于每个要添加的选项标签,都要实例化一个ActionBar.Tab对象,并且调用setTabListener()方法设置ActionBar.Tab对象的事件监听器。还可以用setText()或setIcon()方法来设置选项标签的标题或图标。

             3.  通过调用addTab()方法,把每个选项标签添加到操作栏。

            在查看ActionBar.TabListener接口时,注意到回调方法只提供了被选择的ActionBar.Tab对象和执行Fragment对象事务的FragmentTransaction对象---没有说明任何有关Fragment切换的事。因此。你必须定义自己的每个ActionBar.Tab之间的关联,以及ActionBar.Tab所代表的适合的Fragment对象(为了执行合适的Fragment事务)。依赖你的设计,会有几种不同的方法来定义这种关联。在下面的例子中,ActionBar.TabListener接口的实现提供了一个构造器,这样每个新的选项标签都会使用它自己的监听器实例。每个监听器实例都定义了几个在对应Fragment对象上执行事务时必须的几个成员变量。

           例如,以下示例是ActionBar.TabListener接口的一种实现,在这个实现中,每个选项标签都使用了它自己的监听器实例:

    public static class TabListener<T extends Fragment> implements ActionBar.TabListener {
        private Fragment mFragment;
        private final Activity mActivity;
        private final String mTag;
        private final Class<T> mClass;
    
        /** Constructor used each time a new tab is created.
          * @param activity  The host Activity, used to instantiate the fragment
          * @param tag  The identifier tag for the fragment
          * @param clz  The fragment's Class, used to instantiate the fragment
          */
        public TabListener(Activity activity, String tag, Class<T> clz) {
            mActivity = activity;
            mTag = tag;
            mClass = clz;
        }
    
        /* The following are each of the ActionBar.TabListener callbacks */
    
        public void onTabSelected(Tab tab, FragmentTransaction ft) {
            // Check if the fragment is already initialized
            if (mFragment == null) {
                // If not, instantiate and add it to the activity
                mFragment = Fragment.instantiate(mActivity, mClass.getName());
                ft.add(android.R.id.content, mFragment, mTag);
            } else {
                // If it exists, simply attach it in order to show it
                ft.attach(mFragment);
            }
        }
    
        public void onTabUnselected(Tab tab, FragmentTransaction ft) {
            if (mFragment != null) {
                // Detach the fragment, because another one is being attached
                ft.detach(mFragment);
            }
        }
    
        public void onTabReselected(Tab tab, FragmentTransaction ft) {
            // User selected the already selected tab. Usually do nothing.
        }
    }

           警告:针对每个回调中的Fragment事务,你都不必调用commit()方法---系统会调用这个方法,并且如果你自己调用了这个方法,有可能会抛出一个异常。你也不能把这些Fragment事务添加到回退堆栈中。

    在这个例子中,当对应的选项标签被选择时,监听器只是简单的把一个Fragment对象附加(attach()方法)到Activity布局上---或者,如果没有实例化,就会创建这个Fragment对象,并且把它添加(add()方法)到布局中(android.R.id.content ViewGroup的一个子类),当这个选项标签解除选择时,对应的Fragment对象也会被解除与布局的依附关系。

           ActionBar.TabListener的实现做了大量的工作,剩下的事情就是创建每个ActionBar.Tab对象并把它添加到ActionBar对象中,另外,你必须调用setNavigationMode(NAVIGATION_MODE_TABS)方法来让选项标签可见。如果选项标签的标题实际指示了当前的View对象,你也可以通过调用setDisplayShowTitleEnabled(false)方法来禁用Activity的标题。

           例如,下面的代码使用上面定义的监听器在操作栏中添加了两个选项标签。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Notice that setContentView() is not used, because we use the root
        // android.R.id.content as the container for each fragment
    
        // setup action bar for tabs
        ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        actionBar.setDisplayShowTitleEnabled(false);
    
        Tab tab = actionBar.newTab()
                .setText(R.string.artist)
                .setTabListener(new TabListener<ArtistFragment>(
                        this, "artist", ArtistFragment.class));
        actionBar.addTab(tab);
    
        tab = actionBar.newTab()
            .setText(R.string.album)
            .setTabListener(new TabListener<AlbumFragment>(
                    this, "album", AlbumFragment.class));
        actionBar.addTab(tab);
    }

            注意:以上有关ActionBar.TabListener的实现,只是几种可能的技术之一。在API Demos应用中你能够看到更多的这种样式。

            如果Activity终止了,那么你应该保存当前选择的选项标签的状态,以便当用户再次返回时,你能够打开合适的选项标签。在保存状态的时刻,你能够用getSelectedNavigationIndex()方法查询当前的被选择的选项标签。这个方法返回被选择的选项标签的索引位置。

           警告:保存每个Fragment所必须的状态是至关重要的,因为当用户用选项标签在Fragment对象间切换时,它会查看Fragment在离开时样子。

           注意:在某些情况下,Android系统会把操作栏选项标签作为一个下拉列表来显示,以便确保操作栏的最优化显示。

    添加下拉式导航

           作为Activity内部的另一种导航(或过滤)模式,操作栏提供了内置的下拉列表。下拉列表能够提供Activity中内容的不同排序模式。

           启用下拉式导航的基本过程如下:

             1.  创建一个给下拉提供可选项目的列表,以及描画列表项目时所使用的布局;

             2.  实现ActionBar.OnNavigationListener回调,在这个回调中定义当用户选择列表中一个项目时所发生的行为;

             3.  用setNavigationMode()方法该操作栏启用导航模式,如:

    ActionBar actionBar = getActionBar();
    actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);

            4.  用setListNavigationCallbacks()方法给下拉列表设置回调方法,如:

    actionBar.setListNavigationCallbacks(mSpinnerAdapter, mNavigationCallback);

    这个方法需要SpinnerAdapter和ActionBar.OnNavigationListener对象。下面是 SpinnerAdapter and ActionBar.OnNavigationListener 的例子。

     Example SpinnerAdapter and OnNavigationListener

    设置操作栏的样式

           如果你对应用程序中的可视构件进行了定制化的设计,那么你可能也会要对操作栏做一些重新设计,以便跟应用程序的设计匹配。要这样做的话,需要使用Android的样式与主题框架中的一些特殊的样式属性来重新设置操作栏的样式。

           注意:改变外观的背景图片依赖与当前按钮的状态(选择、按下、解除选择),因此你使用的可描画的资源必须是一个可描画的状态列表。

           警告:对于你提供的所有可描画的背景,要确保使用NinePatch类型可描画资源,以便允许图片的拉伸。NinePatch类型的图片应该比40像素高30像素宽的图片要小。


    普通的外观

    android:windowActionBarOverlay

          这个属性声明了操作栏是否应该覆盖Activity布局,而不是相对Activity的布局位置的偏移。这个属性的默认值是false。

          通常,在屏幕上,操作栏需要它自己的空间,并且把剩下的空间用来填充Activity的布局。当操作栏四覆盖模式时,Activity会使用所有的有效空间,系统会在Activity的上面描画操作栏。如果你想要在操作栏隐藏和显示时,布局中的内容保持固定的尺寸好位置,那么这种覆盖模式是有用的。你也可能只是为了显示效果来使用它,因为你可以给操作栏设置半透明的背景,以便用户依然能够看到操作栏背后的Activity布局。

           注意:默认情况下,Holo主题会用半透明背景来描画操作栏。但是,你能够用自己的样式来修改它,并且默认的情况下,DeviceDefault主题在不同的设备上可能使用不透明的背景。

           覆盖模式被启用时,Activity布局不会感知到操作栏覆盖在它的上面,因此,在操作栏覆盖的区域,最好不要放置一些重要的信息或UI组件。如果适合,你能够引用平台的actionBarSize值来决定操作栏的高度,例如,在XML布局文件中引用这个值。

    <SomeView
        ...
        android:layout_marginTop="?android:attr/actionBarSize" />

           你还能够用getHeight()方法在运行时获取操作栏的高度。如果在Activity生存周期的早期调用这个方法,那么在调用时所反映的操作栏的高度可能不包括被堆放的操作栏(因为导航选项标签)。要看如何在运行时判断操作栏总的高度(包括被堆放的操作栏),请看Honeycomb Gallery示例应用中的TitlesFragment类。

    操作项元素

    android:actionButtonStyle给操作项按钮定义样式资源。android:actionBarItemBackground 给每个操作项的背景定义可描画资源(被添加在API 级别 14中)。android:itemBackground 给每个悬浮菜单项的背景定义可描画资源。android:actionBarDivider给操作项之间的分隔线定义可描画资源(被添加在API 级别 14中)android:actionMenuTextColor给显示在操作项中文本定义颜色。android:actionMenuTextAppearance 给显示在操作项中文本定义样式资源。android:actionBarWidgetTheme给作为操作视窗被填充到操作栏中的可视构件定义主题资源(被添加在API级别14中)。导航选项标签

    android:actionBarTabStyle 给操作栏中的选项标签定义样式资源。android:actionBarTabBarStyle给显示在导航选项标签下方的细条定义样式资源。android:actionBarTabTextStyle给导航选项标签中的文本定义样式资源。下拉列表

    android:actionDropDownStyle 给下拉导航列表定义样式(如背景和文本样式)。如,下例XML文件中给操作栏定义了一些定制的样式:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- the theme applied to the application or activity -->
        <style name="CustomActivityTheme" parent="@android:style/Theme.Holo">
            <item name="android:actionBarTabTextStyle">@style/CustomTabTextStyle</item>
            <item name="android:actionBarDivider">@drawable/ab_divider</item>
            <item name="android:actionBarItemBackground">@drawable/ab_item_background</item>
        </style>
    
        <!-- style for the action bar tab text -->
        <style name="CustomTabTextStyle" parent="@android:style/TextAppearance.Holo">
            <item name="android:textColor">#2456c2</item>
        </style>
    </resources>

           注意:一定要在<style>标签中声明一个父主题,这样定制的主题可以继承所有没有明确声明的样式。在修改操作栏样式时,使用父主题是至关重要的,它会让你能够简单的覆写你想要改变的操作栏样式,而不影响你不想修改的样式(如文本的外观或操作项的边缘)。

          你能够在清单文件中把定制的主题应用到整个应用程序或一个单独的Activity对象,如:

    <application android:theme="@style/CustomActivityTheme" ... />

    高级样式

          如果需要比上述属性更高级的样式,可以在Activity的主题中包含android:actionBarStyle和android:actionBarSplitStyle属性。这两个属性的每一个都指定了另一种能够给操作栏定义各种属性的样式,包括带有android:background、android:backgroundSplit、android:backgroundStacked属性的不同背景。如果要覆盖这些操作栏样式,就要确保定义一个像Widget.Holo.ActionBar这样的父操作栏样式。

    例如,如果要改变操作栏背景,你可以使用下列样式:

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <!-- the theme applied to the application or activity -->
        <style name="CustomActivityTheme" parent="@android:style/Theme.Holo">
            <item name="android:actionBarStyle">@style/MyActionBar</item>
            <!-- other activity and action bar styles here -->
        </style>
    
        <!-- style for the action bar backgrounds -->
        <style name="MyActionBar" parent="@android:style/Widget.Holo.ActionBar">
            <item name="android:background">@drawable/ab_background</item>
            <item name="android:backgroundStacked">@drawable/ab_background</item>
            <item name="android:backgroundSplit">@drawable/ab_split_background</item>
        </style>
    </resources>


    原文地址:http://developer.android.com/guide/topics/ui/actionbar.html#ActionView



    /**
    * @author 张兴业
    *  我的新浪微博:@张兴业TBOW
    */


    展开全文
  • ActionBar 样式详解 -- 样式 主题 简介

    千次阅读 2016-05-03 11:34:14
    1. 样式资源解析 (1) 样式简介 ...样式解析 : 样式是设置给 View 组件的多个属性的集合;... TextView 设置 文字大小, 颜色, 对齐方式等, 如果需要给多个 TextView 设置同样的属性, 这里使用样式就可以大大节省了...
    1. 样式资源解析


    (1) 样式简介

    样式解析 : 样式是设置给 View 组件的多个属性的集合
    -- 样式的好处 : 给一个 TextView 设置 文字大小, 颜色, 对齐方式等, 如果需要给多个 TextView 设置同样的属性, 这里使用样式就可以大大节省了代码量;

    样式指定 : 每个 View 组件都有一个 style 属性, 可以通过该属性指定 样式, 注意与 android:style 属性区分;


    (2) 样式标签定义

    样式定义的位置 /res/values/ 目录下的 跟标签是 <resources /> 标签的 xml 文件, 如默认的 styles.xml 文件;

    样式标签解析 : <style /> 标签在 <resources /> 标签内, <style /> 标签的子标签是 <item />;
    -- 根标签 : <style /> 标签都是定义在 <resources /> 标签内部;
    -- 子标签 : <item /> 标签是 <style /> 标签的子标签, 其定义了具体的 View 组件的属性;

    <style /> 标签属性 : 
    -- name 属性 : 指定样式的名称, 如 定义 TextView 组件, name 属性可以是 "android:textColor" 等 TextView 组件的属性;
    -- parent 属性 : <style /> 标签可以继承另外一个标签, 该标签会获得被集成标签的所有属性格式, 重复定义属性格式, 子标签的属性会覆盖父标签的属性;


    (3) 样式示例 

    样式资源文件 
    <?xml version="1.0" encoding="utf-8"?><resources xmlns:android="http://schemas.android.com/apk/res/android"> <style name="text1"> <item name="android:gravity">center</item> <item name="android:textColor">@android:color/holo_green_dark</item> <item name="android:textSize">30dp</item> <item name="android:textStyle">bold</item> <item name="android:padding">20dip</item> <item name="android:background">@android:color/holo_orange_light</item> </style> <style name="text2"> <item name="android:gravity">center</item> <item name="android:textColor">@android:color/holo_blue_dark</item> <item name="android:textSize">40dp</item> <item name="android:textStyle">italic</item> <item name="android:padding">30dip</item> <item name="android:background">@android:color/holo_red_light</item> </style> </resources>

    布局文件 : 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="cn.org.octopus.actionbar.style.MainActivity$PlaceholderFragment" > <TextView android:id="@+id/text1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="样式一" style="@style/text1"/> <TextView android:id="@+id/text2" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="30dp" android:layout_below="@id/text1" android:text="样式二" style="@style/text2"/></RelativeLayout>

    2. 主题资源解析


    (1) 主题资源 与 样式资源比较

    主题资源 与 样式资源 相同点 : 定义方式基本相同, 都是在 /res/values 目录下的 带 <resources /> 根标签的 xml 中定义;

    主题资源 与 样式资源 不同点 : 
    -- 作用范围 : 样式资源一般作用于 单个 View 组件, 主题资源作用于 整个 Application 应用或者 指定的 Activity, Theme 是在 AndroidManifest.xml 中指定的;
    -- 属性内容 : 主题资源一般用于定义改变窗口的外观格式等;


    (2) Theme 主题设置方法

    Theme 主题使用方法 : 
    -- 在 Manifest.xml 文件中配置 : 为 <application /> 或者 <activity /> 标签设置 android.theme 属性 "@style/style_name", 设置的也是一个 style 样式属性;
    -- Activity 代码中设置 : 在 onCreate() 方法的 setContentView() 方法之前调用 setTheme(R.style.style_name) 方法设置 Theme 主题, 如果在 setComtentView 之后调用就不会起作用;


    (3) Android 系统定义的 Theme 
    android:theme="@android:style/Theme.Dialog" : Activity显示为对话框模式android:theme="@android:style/Theme.NoTitleBar" : 不显示应用程序标题栏android:theme="@android:style/Theme.NoTitleBar.Fullscreen" : 不显示应用程序标题栏,并全屏android:theme="Theme.Light ": 背景为白色android:theme="Theme.Light.NoTitleBar" : 白色背景并无标题栏android:theme="Theme.Light.NoTitleBar.Fullscreen" : 白色背景,无标题栏,全屏android:theme="Theme.Black" : 背景黑色android:theme="Theme.Black.NoTitleBar" : 黑色背景并无标题栏android:theme="Theme.Black.NoTitleBar.Fullscreen" : 黑色背景,无标题栏,全屏android:theme="Theme.Wallpaper" : 用系统桌面为应用程序背景android:theme="Theme.Wallpaper.NoTitleBar" : 用系统桌面为应用程序背景,且无标题栏android:theme="Theme.Wallpaper.NoTitleBar.Fullscreen" : 用系统桌面为应用程序背景,无标题栏,全屏android:theme="Theme.Translucent : 透明背景android:theme="Theme.Translucent.NoTitleBar" : 透明背景并无标题android:theme="Theme.Translucent.NoTitleBar.Fullscreen" : 透明背景并无标题,全屏android:theme="Theme.Panel ": 面板风格显示android:theme="Theme.Light.Panel" : 平板风格显示


    (4) 常用的 Theme 设置属性

    <item name="windowBackground">@android:drawable/screen_background_selector_dark</item> 界面背景图片 <item name="windowFrame">@null</item> 界面前景图片 <item name="windowNoTitle">false</item> 是否带有标题 <item name="windowFullscreen">false</item> 是否全屏 <item name="windowIsFloating">false</item> 是否是悬浮窗


    (5) Theme 示例程序

    style 样式 : 
    <?xml version="1.0" encoding="utf-8"?><resources> <style name="octopus_style"> <item name="android:windowBackground">@drawable/bg1</item> <item name="android:windowFullscreen">true</item> <item name="android:windowNoTitle">true</item> <item name="android:windowIsFloating">true</item> </style></resources>

    Manifest.xml 中配置 : 
    <activity android:name="cn.org.octopus.actionbar.style.MainActivity" android:label="@string/app_name" android:theme="@style/octopus_style">




    二. ActionBar 样式解析


    1. AppTheme 解析


    (1) AppTheme 引入

    在 AndroidManifest.xml 中默认的主题 : AppTheme, AppTheme 是在 /res/alues/style.xml 中定义的;
    <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" >


    (2) AppTheme 定义

    style.xml 文件 : 该文件定义了 AppTheme 主题;
    -- 代码示例 : 
    <resources> <!-- Base application theme, dependent on API level. This theme is replaced by AppBaseTheme from res/values-vXX/styles.xml on newer devices. --> <style name="AppBaseTheme" parent="android:Theme.Light"> <!-- Theme customizations available in newer API levels can go in res/values-vXX/styles.xml, while customizations related to backward-compatibility can go here. --> </style> <!-- Application theme. --> <style name="AppTheme" parent="AppBaseTheme"> <!-- All customizations that are NOT specific to a particular API-level can go here. --> </style> </resources>
    -- 代码解析 : AppTheme 主题继承了 AppBaseTheme 主题, 而 AppBaseTheme 主题确不是固定的, 在 /res/values-v14 中的 style.xml 中也定义了 AppBaseTheme, 该 AppBaseTheme 可以覆盖 在 res/values/style.xml 中定义的主题;



    2. AppBaseTheme 解析


    (1) AppBaseTheme 简介 

    AppBaseTheme 简介 : 
    -- AppBaseTheme 父类 : 在 Android 工程创建时会有一个选择 Theme 的标题样式, AppBaseTheme 就会继承这个样式;
    -- AppBaseTheme 位置 : 在 Android 工程中, /res/values/style.xml /res/vaules-v11/style.xml res/values-v14/style.xml 中都定义了 AppBaseTheme 主题; 
    -- style 样式优先级 : 定义在 values-vxx 中的样式优先级会高于 定义在 values 中的样式, 如果有重复定义 优先级高的会覆盖优先级低的;


    (2) AppBaseTheme 代码分析

    定义在 /res/values/style.xml 中的 AppBaseTheme : 该主题依赖于 API 版本, 如果在对应版本的 values 中定义了 AppBaseTheme , 会覆盖该项;
    <!-- Base application theme, dependent on API level. This theme is replaced by AppBaseTheme from res/values-vXX/styles.xml on newer devices. --> <style name="AppBaseTheme" parent="android:Theme.Light"> <!-- Theme customizations available in newer API levels can go in res/values-vXX/styles.xml, while customizations related to backward-compatibility can go here. --> </style>

    定义在 /res/values-11/style.xml 中的 AppBaseTheme : 如果 API 的版本 高于 11, 就会默认使用该 AppBaseTheme;
    <resources> <!-- Base application theme for API 11+. This theme completely replaces AppBaseTheme from res/values/styles.xml on API 11+ devices. --> <style name="AppBaseTheme" parent="android:Theme.Holo.Light"> <!-- API 11 theme customizations can go here. --> </style></resources>

    定义在 /res/values-14/style.xml 中的 AppBaseTheme : 如果 API 的版本 高于 14, 就会默认使用该 AppBaseTheme;
    <resources> <!-- Base application theme for API 14+. This theme completely replaces AppBaseTheme from BOTH res/values/styles.xml and res/values-v11/styles.xml on API 14+ devices. --> <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar"> <!-- API 14 theme customizations can g o here. --> </style></resources>


    3. Activity 主题样式 android:Theme.Holo.Light.DarkActionBar 

    这里我们分析 API-14 对应的主题样式 : 在上面的 /res/values-v14/style.xml 中定义的 AppBaseTheme 如果在 API-14 的情况下继承的是 android:Theme.Holo.Light.DarkActionBar 主题样式, 该主题定义在 sdk/platforms/android-19/data/res/values/themes.xml 文件中;
    -- 代码示例 : 
    <!-- Variant of the holographic (light) theme that has a solid (opaque) action bar with an inverse color profile. The dark action bar sharply stands out against the light content. --> <style name="Theme.Holo.Light.DarkActionBar"> <item name="android:windowContentOverlay">@android:drawable/ab_solid_shadow_holo</item> <item name="android:actionBarStyle">@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse</item> <item name="actionBarWidgetTheme">@android:style/Theme.Holo</item> <item name="actionDropDownStyle">@android:style/Widget.Holo.Spinner.DropDown.ActionBar</item> <item name="actionButtonStyle">@android:style/Widget.Holo.ActionButton</item> <item name="actionOverflowButtonStyle">@android:style/Widget.Holo.ActionButton.Overflow</item> <item name="actionModeBackground">@android:drawable/cab_background_top_holo_dark</item> <item name="actionModeSplitBackground">@android:drawable/cab_background_bottom_holo_dark</item> <item name="actionModeCloseDrawable">@android:drawable/ic_cab_done_holo_dark</item> <item name="homeAsUpIndicator">@android:drawable/ic_ab_back_holo_dark</item> <item name="actionBarTabStyle">@style/Widget.Holo.Light.ActionBar.TabView.Inverse</item> <item name="actionBarTabBarStyle">@style/Widget.Holo.Light.ActionBar.TabBar.Inverse</item> <item name="actionBarTabTextStyle">@style/Widget.Holo.Light.ActionBar.TabText.Inverse</item> <item name="actionBarDivider">@android:drawable/list_divider_holo_dark</item> <item name="actionBarItemBackground">@android:drawable/item_background_holo_dark</item> <item name="actionMenuTextColor">?android:attr/textColorPrimaryInverse</item> <item name="actionModeStyle">@style/Widget.Holo.Light.ActionMode.Inverse</item> <item name="actionModeCloseButtonStyle">@style/Widget.Holo.ActionButton.CloseMode</item> <item name="actionModePopupWindowStyle">@android:style/Widget.Holo.PopupWindow.ActionMode</item> <item name="actionModeCutDrawable">@android:drawable/ic_menu_cut_holo_dark</item> <item name="actionModeCopyDrawable">@android:drawable/ic_menu_copy_holo_dark</item> <item name="actionModePasteDrawable">@android:drawable/ic_menu_paste_holo_dark</item> <item name="actionModeSelectAllDrawable">@android:drawable/ic_menu_selectall_holo_dark</item> <item name="actionModeShareDrawable">@android:drawable/ic_menu_share_holo_dark</item> <item name="actionModeFindDrawable">@android:drawable/ic_menu_find_holo_dark</item> <item name="actionModeWebSearchDrawable">@android:drawable/ic_menu_search_holo_dark</item> </style>


    (1) ActionBar 样式 

    android:actionBarStyle 样式作用 : 定义 ActionBar 的 标题 副标题样式, 背景, 分割条, 进度条样式等;

    属性名称 : android:actionBarStyle, 样式的名称为 Widget.Holo.Light.ActionBar.Solid.Inverse, 该样式定义在  sdk/platforms/android-19/data/res/values/styles.xml 中 . 
    <item name="android:actionBarStyle">@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse</item>

    Widget.Holo.Light.ActionBar.Solid.Inverse 样式具体内容 : 
    <style name="Widget.Holo.Light.ActionBar.Solid.Inverse"> <item name="android:titleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Title.Inverse</item> <item name="android:subtitleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Subtitle.Inverse</item> <item name="android:background">@android:drawable/ab_solid_dark_holo</item> <item name="android:backgroundStacked">@android:drawable/ab_stacked_solid_dark_holo</item> <item name="android:backgroundSplit">@android:drawable/ab_bottom_solid_inverse_holo</item> <item name="android:divider">@android:drawable/list_divider_holo_dark</item> <item name="android:progressBarStyle">@android:style/Widget.Holo.ProgressBar.Horizontal</item> <item name="android:indeterminateProgressStyle">@android:style/Widget.Holo.ProgressBar</item> <item name="android:progressBarPadding">32dip</item> <item name="android:itemPadding">8dip</item> </style>

    重要的属性解析 :
    -- android:titleTextStyle : 标题样式, 可以修改标题文字相关的属性;
    -- android:subtitleTextStyle : 副标题样式;
    -- android:background : 背景, 可以修改 ActionBar 背景;


    (2) ActionBar 按钮样式

    actionButtonStyle 样式作用 : 控制 ActionBar 上的按钮样式, 如 菜单按钮等;

    ActionBar 按钮属性 : actionButtonStyle, 属性值为 @android:style/Widget.Holo.ActionButton ;
    <item name="actionButtonStyle">@android:style/Widget.Holo.ActionButton</item>

    android:style/Widget.Holo.ActionButton 具体属性 : 该样式继承了 Widget.ActionButton 样式;
    <style name="Widget.Holo.ActionButton" parent="Widget.ActionButton"> <item name="android:minWidth">@android:dimen/action_button_min_width</item> <item name="android:gravity">center</item> <item name="android:paddingStart">12dip</item> <item name="android:paddingEnd">12dip</item> <item name="android:scaleType">center</item> <item name="android:maxLines">2</item> </style>
    -- Widget.ActionButton 样式 : 
    <style name="Widget.ActionButton"> <item name="android:background">?android:attr/actionBarItemBackground</item> <item name="android:paddingStart">12dip</item> <item name="android:paddingEnd">12dip</item> <item name="android:minWidth">@android:dimen/action_button_min_width</item> <item name="android:minHeight">?android:attr/actionBarSize</item> <item name="android:gravity">center</item> <item name="android:maxLines">2</item> </style>


    (3) Tab 标签样式

    actionBarTabStyle 样式作用 : 定义 ActionBar Tab 导航时 Tab 标签样式;

    Tab 标签样式属性 : actionBarTabStyle, 样式为 @style/Widget.Holo.Light.ActionBar.TabView.Inverse, 该样式为 空, 没有定义任何属性;
    item name="actionBarTabStyle">@style/Widget.Holo.Light.ActionBar.TabView.Inverse</item>


    (4) 其它样式

    actionBarDivider 样式 : ActionBar 各项目之间的分隔符, 指定了一个 drawable 资源;
    <item name="actionBarDivider">@android:drawable/list_divider_holo_dark</item>

    菜单文字颜色 : actionMenuTextColor, 指定菜单中文字的颜色;
    <item name="actionMenuTextColor">?android:attr/textColorPrimaryInverse</item>

    actionBarTabBarStyle 样式 : 定义 ActionBar Tab 导航中 Tab 的分割条, 指定一个 drawable 资源;
    <item name="actionBarTabBarStyle">@style/Widget.Holo.Light.ActionBar.TabBar.Inverse</item>

    actionDropDownStyle 样式 : 指定 ActionBar List 导航 下拉列表样式;
    <item name="actionDropDownStyle">@android:style/Widget.Holo.Spinner.DropDown.ActionBar</item>


    三. 自定义 ActionBar 样式

    默认的 ActionBar 样式 : 



    1. 自定义标题样式


    (1) 样式解析 

    查找标题样式定义位置 : 
    -- 样式的继承关系 : AppTheme 是直接使用的样式, AppTheme 继承了 AppBaseTheme, AppBaseTheme 继承了 android:Theme.Holo.Light.DarkActionBar 样式;
    -- 标题样式位置 : android:titleTextStyle 样式在 android:actionBarStyle 中定义, android:actionBarStyle 在 android:Theme.Holo.Light.DarkActionBar 中定义;
    -- 层次关系 : AppTheme 与 AppBaseTheme android:Theme.Holo.Light.DarkActionBar 是继承关系, 是同一层次的, 包含 android:actionBarStyle 样式, android:actionBarStyle 样式 包含 android:titleTextStyle 样式;

    在 AppTheme 中覆盖 标题样式方法 : 
    -- 需要实现一个 android:actionBarStyle 子样式 : 因为 AppTheme 层次高于 android:titleTextStyle 两层, 不能直接在 AppTheme 中定义该样式进行覆盖, 需要实现一个 android:actionBarStyle 子样式, 在该子样式中重新定义 android:titleTextStyle 样式, 即可覆盖掉标题样式;
    -- 实现一个 android:titleTextStyle 子样式 : 该样式 也需要继承原样式, 覆盖一些属性;
    -- AppTheme 重新定义 android:actionBarStyle 样式 : 上面将 android:actionBarStyle 样式 和 android:titleTextStyle 样式覆盖, 这里将已经重写的标题栏样式设置给 android:actionBarStyle 即可;


    (2) 系统默认样式 

    AppTheme : 
    <!-- Application theme. --> <style name="AppTheme" parent="AppBaseTheme"> <!-- All customizations that are NOT specific to a particular API-level can go here. --> </style>

    AppBaseTheme : 
    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar"> <!-- API 14 theme customizations can go here. --> </style>

    Theme.Holo.Light.DarkActionBar 
    <style name="Theme.Holo.Light.DarkActionBar"> <item name="android:actionBarStyle">@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse</item> more ... ... </style>

    Widget.Holo.Light.ActionBar.Solid.Inverse : 
    <style name="Widget.Holo.Light.ActionBar.Solid.Inverse"> <item name="android:titleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Title.Inverse</item> <item name="android:subtitleTextStyle">@android:style/TextAppearance.Holo.Widget.ActionBar.Subtitle.Inverse</item> <item name="android:background">@android:drawable/ab_solid_dark_holo</item> <item name="android:backgroundStacked">@android:drawable/ab_stacked_solid_dark_holo</item> <item name="android:backgroundSplit">@android:drawable/ab_bottom_solid_inverse_holo</item> <item name="android:divider">@android:drawable/list_divider_holo_dark</item> <item name="android:progressBarStyle">@android:style/Widget.Holo.ProgressBar.Horizontal</item> <item name="android:indeterminateProgressStyle">@android:style/Widget.Holo.ProgressBar</item> <item name="android:progressBarPadding">32dip</item> <item name="android:itemPadding">8dip</item> </style>



    (3) 样式定义

    重写 android:titleTextStyle 样式 
    <!-- 重写 android:titleTextStyle 样式, 继承 @android:style/TextAppearance.Holo.Widget.ActionBar.Title.Inverse 样式 --> <style name="OctopusActionBarTittle" parent="@android:style/TextAppearance.Holo.Widget.ActionBar.Title.Inverse"> <item name="android:textColor">@android:color/holo_green_dark</item> <item name="android:textStyle">italic</item> <item name="android:textSize">25sp</item> </style>

    重写 android:actionBarStyle 样式 : 
    <!-- 重写 android:actionBarStyle 样式 集成 @android:style/Widget.Holo.Light.ActionBar.Solid.Inverse 样式 --> <style name="OctopusActionBarStyle" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse"> <item name="android:titleTextStyle">@style/OctopusActionBarTittle</item></style>

    覆盖 android:actionBarStyle 样式 : 
    <!-- Application theme. --> <style name="AppTheme" parent="AppBaseTheme"> <!-- 覆盖 android:actionBarStyle 样式 --> <item name="android:actionBarStyle">@style/OctopusActionBarStyle</item> </style>


    (4) 代码示例

    /res/values/styles.xml 代码 : 
    <resources xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Base application theme, dependent on API level. This theme is replaced by AppBaseTheme from res/values-vXX/styles.xml on newer devices. --> <style name="AppBaseTheme" parent="android:Theme.Light"> <!-- Theme customizations available in newer API levels can go in res/values-vXX/styles.xml, while customizations related to backward-compatibility can go here. --> </style> <!-- Application theme. --> <style name="AppTheme" parent="AppBaseTheme"> <!-- 覆盖 android:actionBarStyle 样式 --> <item name="android:actionBarStyle">@style/OctopusActionBarStyle</item> </style> <!-- 重写 android:actionBarStyle 样式 集成 @android:style/Widget.Holo.Light.ActionBar.Solid.Inverse 样式 --> <style name="OctopusActionBarStyle" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse"> <item name="android:titleTextStyle">@style/OctopusActionBarTittle</item></style> <!-- 重写 android:titleTextStyle 样式, 继承 @android:style/TextAppearance.Holo.Widget.ActionBar.Title.Inverse 样式 --> <style name="OctopusActionBarTittle" parent="@android:style/TextAppearance.Holo.Widget.ActionBar.Title.Inverse"> <item name="android:textColor">@android:color/holo_green_dark</item> <item name="android:textStyle">italic</item> <item name="android:textSize">25sp</item> </style></resources>

    界面效果 : 



    2. 自定义菜单文字样式

    (1) 系统默认样式

    默认样式下的界面显示 : 



    (2) 自定义菜单

    自定义菜单样式 : 
    <!-- 自定义的菜单样式 --> <style name="OctopusMenuTittleStyle" parent="@android:style/TextAppearance.Holo.Widget.ActionBar.Title.Inverse"> <item name="android:textColor">@android:color/white</item> <item name="android:textStyle">bold</item> <item name="android:textSize">20sp</item> </style>

    AppTheme 中覆盖 android:actionMenuTextAppearance 属性 : 
    <style name="AppTheme" parent="AppBaseTheme"> <!-- 覆盖 android:actionBarStyle 样式, 自定义 标题 样式 --> <item name="android:actionBarStyle">@style/OctopusActionBarStyle</item> <!-- 覆盖 android:actionMenuTextAppearance 样式, 自定义 菜单文字样式 --> <item name="android:actionMenuTextAppearance">@style/OctopusMenuTittleStyle</item> </style>


    (3) 代码示例

    完整 /res/values/styles.xml 代码 : 
    <resources xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Base application theme, dependent on API level. This theme is replaced by AppBaseTheme from res/values-vXX/styles.xml on newer devices. --> <style name="AppBaseTheme" parent="android:Theme.Light"> <!-- Theme customizations available in newer API levels can go in res/values-vXX/styles.xml, while customizations related to backward-compatibility can go here. --> </style> <!-- Application theme. --> <style name="AppTheme" parent="AppBaseTheme"> <!-- 覆盖 android:actionBarStyle 样式, 自定义 标题 样式 --> <item name="android:actionBarStyle">@style/OctopusActionBarStyle</item> <!-- 覆盖 android:actionMenuTextAppearance 样式, 自定义 菜单文字样式 --> <item name="android:actionMenuTextAppearance">@style/OctopusMenuTittleStyle</item> </style> <!-- 重写 android:actionBarStyle 样式 集成 @android:style/Widget.Holo.Light.ActionBar.Solid.Inverse 样式 --> <style name="OctopusActionBarStyle" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse"> <item name="android:titleTextStyle">@style/OctopusActionBarTittle</item></style> <!-- 重写 android:titleTextStyle 样式, 继承 @android:style/TextAppearance.Holo.Widget.ActionBar.Title.Inverse 样式 --> <style name="OctopusActionBarTittle" parent="@android:style/TextAppearance.Holo.Widget.ActionBar.Title.Inverse"> <item name="android:textColor">@android:color/holo_green_dark</item> <item name="android:textStyle">italic</item> <item name="android:textSize">25sp</item> </style> <!-- 自定义的菜单样式 --> <style name="OctopusMenuTittleStyle" parent="@android:style/TextAppearance.Holo.Widget.ActionBar.Title.Inverse"> <item name="android:textColor">@android:color/white</item> <item name="android:textStyle">bold</item> <item name="android:textSize">20sp</item> </style></resources>

    界限展示效果 : 



    3. 修改 ActionBar 背景色

    在 android:actionBarStyle 样式中修改即可 : 
    <!-- 重写 android:actionBarStyle 样式 集成 @android:style/Widget.Holo.Light.ActionBar.Solid.Inverse 样式 --> <style name="OctopusActionBarStyle" parent="@android:style/Widget.Holo.Light.ActionBar.Solid.Inverse"> <item name="android:titleTextStyle">@style/OctopusActionBarTittle</item> <item name="android:background">@android:color/darker_gray</item></style>

    界面效果 : 



    4. 自定义左侧的小箭头

    在 Activity 中添加代码 : 显示 左侧的小箭头;
    -- 显示箭头代码 : 
    /* 获取 ActionBar 对象 */ActionBar actionBar = getActionBar();/* 设置标题可点击, 并且添加 向左的小箭头 */actionBar.setDisplayHomeAsUpEnabled(true);
    -- 效果 : 箭头太小, 且不美观;


    小箭头定义位置 : 小箭头 在 Theme.Holo.Light.DarkActionBar 样式中定义;
    <item name="homeAsUpIndicator">@android:drawable/ic_ab_back_holo_dark</item>

    自定义小箭头 : 直接在 AppTheme 样式下 重写 android:homeAsUpIndicator 属性即可
    <!-- Application theme. --> <style name="AppTheme" parent="AppBaseTheme"> <!-- 覆盖 android:actionBarStyle 样式, 自定义 标题 样式 --> <item name="android:actionBarStyle">@style/OctopusActionBarStyle</item> <!-- 覆盖 android:actionMenuTextAppearance 样式, 自定义 菜单文字样式 --> <item name="android:actionMenuTextAppearance">@style/OctopusMenuTittleStyle</item> <!-- 自定义向左的小箭头 --> <item name="android:homeAsUpIndicator">@drawable/back</item> </style>
    -- 界面效果 : 

    展开全文
  • 超详细!ActionBar使用详解

    千次阅读 2019-06-04 20:34:18
    一、ActionBar介绍  在Android 3.0中除了我们重点讲解的Fragment外,Action Bar也是一个非常重要的交互元素,Action Bar取代了传统的tittle bar和menu,在程序运行中一直置于顶部,对于Android平板设备来说屏幕更...
  • actionbar详解

    2019-05-09 11:14:37
    actionbar详解(二) 用户1148531发表于向治洪订阅 187 经过前面两篇文章的学习,我想大家对ActionBar都已经有一个相对较为深刻的理解了。唯一欠缺的是,前面我们都只是学习了理论知识而已,虽然知识点已经掌握了...
  • 超详细!ActionBar 使用·详解

    千次阅读 2016-02-05 16:04:24
    一、ActionBar介绍  在Android 3.0中除了我们重点讲解的Fragment外,Action Bar也是一个非常重要的交互元素,Action Bar取代了传统的tittle bar和menu,在程序运行中一直置于顶部,对于Android平板设备来说屏幕...
  • MainActivity如下: package cc.testsimpleactionbar0; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget....import android.app....
  • 限于篇幅的原因,在上篇文章中我们只学习了ActionBar基础部分的知识,那么本篇文章我们将接着上一章的内容继续学习,探究一下ActionBar更加高级的知识。如果你还没有看过前面一篇文章的话,建议先去阅读Android ...
  • Android ActionBar应用实战,高仿微信主界面的设计

    万次阅读 多人点赞 2016-10-14 22:00:31
    微信除了功能非常强大之外,界面也是做得相当美观,它的ActionBar让人看着有一种赏心悦目的感觉。作为手机应用程序中的技术标杆,我们自然应该多多向微信学习,那么今天实战的主题,就是模仿微信主界面的实现。 首先...
  • Android ActionBar的基本用法

    万次阅读 多人点赞 2014-06-06 15:45:57
    本文翻译了这篇文章:Using the Android action bar (ActionBar) - Tutorial 1、ActionBar的简介 ActionBar位于Activity的顶部,可用来显示activity的标题、Icon、Actions和一些用于交互的View。它也可被用于应用的...
  • Android隐藏/移除ActionBar

    万次阅读 2014-09-16 04:37:35
    当使用Android中的ActionBar控件时,如果想要隐藏上面的ActionBar,可以使用如下的代码: getSupportActionBar().hide();//隐藏掉整个ActionBar,包括下面的Tabs 上面的代码会将整个ActionBar都隐藏掉,包括...
  • 一探ActionBar和ToolBar的区别

    千次阅读 2016-12-30 10:22:11
    ActionBar ActionBar是一个确定用户位置的窗口功能,并且能提供用户操作和导航的模块。使用ActionBar能够为用户提供一个熟悉的界面进行界面的切换,这个切换能够使系统更优雅是适应不同屏幕的配置。 ActionBar...
  • 什么是ActionBar 在Android3.0之后,Google对UI导航设计上进行了一系列的改革,其中有一个非常好用的新功能就是引入的ActionBar,他用于取代3.0之前的标题栏,并提供更为丰富的导航效果。 Action bar是一个标识应用...
  • 对于已经被不大好用的Actionbar折磨的开发者来说,Toolbar的出现确实是一个好消息,Toolbar是应用的内容的标准工具栏,可以说是Actionbar的升级版,两者不是独立关系,要使用Toolbar还是得跟ActionBar有关系的。...
  • 我在程序中使用 ActionBarSherlock,下面的代码用来隐藏 ActionBar 的标题。 @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActionBar actionBar = ...
  • 修改ActionBar上各个元素的间距问题

    千次阅读 2017-09-26 10:49:48
    终于弄清楚了ActionBar上的各种间距值怎么调整,分享一下。 先简单介绍一下ActionBar的构成,如下图所示,(懒得自己画了,借用网上找的一张) 下边是一个简单的ActionBar的应用,借用这个图介绍一下各个值...
  • setHomeButtonEnabled这个小于4.0版本的默认值为true的。但是在4.0及其以上是false,...没有向左的小图标。... actionBar.setDisplayHomeAsUpEnabled(true) // 给左上角图标的左边加上一个返回的图标 。对应ActionBar.
  • 微信6.0 ActionBar样式

    千次阅读 2016-06-19 22:54:29
    微信6.0的ActionBar比较简洁只有一个搜索框和一个溢出(overflow)菜单。这个溢出菜单可以看到不是默认的,而是一个“+”号图标。 并且溢出菜单中点击,里面的隐藏菜单图标可以显示出来。(系统默认是不显示的) 文章...
  • Android 实现ActionBar定制

    万次阅读 多人点赞 2014-06-18 17:57:08
    Android开发 自定义ActionBar
1 2 3 4 5 ... 20
收藏数 27,917
精华内容 11,166
关键字:

actionbar