当前位置: 代码迷 >> Android >> Android Theme and Menu 正题菜单相关
  详细解决方案

Android Theme and Menu 正题菜单相关

热度:245   发布时间:2016-04-27 22:08:01.0
Android Theme and Menu 主题菜单相关

出自 微凉一季的博客

Demo

学了一下Chris Banes大神的项目。总结一下theme相关的小知识点。先看个定义主题的不错的小case:
在values目录下建立两个命名为themes的文件:

themes.xml

<resources xmlns:android="http://schemas.android.com/apk/res/android">    <style name="Platform.Theme.AnDream" parent="Theme.AppCompat.Light.NoActionBar">        <item name="android:windowActionModeOverlay">true</item>    </style>    <style name="Platform.Theme.AnDream.Dark" parent="Theme.AppCompat.NoActionBar">        <item name="android:windowActionModeOverlay">true</item>    </style>    <style name="Base.Theme.AnDream" parent="Platform.Theme.AnDream">        <item name="android:windowContentOverlay">@null</item>    </style>    <style name="Base.Theme.AnDream.Dark" parent="Platform.Theme.AnDream.Dark">        <item name="android:windowContentOverlay">@null</item>    </style>    <style name="Theme.AnDream" parent="Base.Theme.AnDream">        <item name="android:textColorHighlight">@color/primary_color_translucent</item>        <item name="android:progressBarStyleHorizontal">@style/Widget.AnDream.ProgressBar</item>        <item name="android:ratingBarStyle">@style/Widget.AnDream.RatingBar</item>        // 这个是自定义主题的属性,在attrs里面        <item name="grey_shade">@color/light_gray</item>        <item name="windowActionModeOverlay">true</item>        <item name="colorPrimary">@color/primary_color</item>        <item name="colorPrimaryDark">@color/primary_color_dark</item>        <item name="colorAccent">@color/accent_color</item>    </style>    <style name="Theme.AnDream.Images" parent="Base.Theme.AnDream.Dark">        <item name="android:windowBackground">@android:color/black</item>    </style>    <style name="Theme.AnDream.Framed" parent="Theme.AnDream">        <item name="windowActionBarOverlay">false</item>    </style></resources>

themes.xml(v21):

<resources>    //这里体会一下 设置状态栏透明,设置windowDrawsSystemBarBackgrounds true    <style name="Platform.Theme.AnDream" parent="Theme.AppCompat.Light.NoActionBar">        <item name="android:windowDrawsSystemBarBackgrounds">true</item>        <item name="android:statusBarColor">@android:color/transparent</item>    </style>    <style name="Platform.Theme.AnDream.Dark" parent="Theme.AppCompat.NoActionBar">        <item name="android:windowDrawsSystemBarBackgrounds">true</item>        <item name="android:statusBarColor">@android:color/transparent</item>    </style></resources>

分析

层次比较清晰。

  • 根据平台分别兼容holo和design的Platform.Theme.AnDream和Platform.Theme.AnDream.Dark
  • 子base主题:Base.Theme.AnDream和Base.Theme.AnDream.Dark
  • 然后程序用的主题Theme.AnDream。以及继承自Base.Theme.AnDream.Dark的Theme.AnDream.Images
  • 最后一个是程序主题Theme.AnDream的一个扩展Theme.AnDream.Framed。

层次非常清晰,是个不错的建主题的样例,基本各种需要的主题就都有了。

主题的源头是系统的Theme.AppCompat.Light.NoActionBar和Theme.AppCompat.NoActionBar。兼容包里没有ActionBar的浅色和深色主题,用这组主题方便我们后续自由的使用toolbar。

另外点进去看到appcompat源码里的:

<style name="Theme.AppCompat.Light.NoActionBar">    <item name="windowActionBar">false</item>    <item name="android:windowNoTitle">true</item></style>

demo里意义比较模糊的属性有:

overlays 是覆盖物的意思。

  • <item name="android:windowActionModeOverlay">true</item>

    and the actionmode will be shown over the action bar instead of pushing it down.It basically lets AppCompat know that you have a toolbar located in the top of the screen and that it should draw the ActionMode on top of it.
    ActionMode显示在顶栏,而不是屏幕中的菜单。告诉appcompat你有个toolbar在屏幕顶上,它应该把ActionMode画到toolbar上面。

  • <item name="android:windowContentOverlay">@null</item>
    定义contentoverlay的背景的,ContentOverlay背景为null 和actionbar下面的阴影有关

  • <item name="android:textColorHighlight">@color/primary_color_translucent</item>
    高亮字体颜色
  • <item name="android:windowBackground">@android:color/black</item>
    屏幕背景色
  • <item name="android:windowDrawsSystemBarBackgrounds">true</item>
    需要绘制系统操作栏背景
  • <item name="android:statusBarColor">@android:color/transparent</item>设置状态栏透明

另外菜单的写法例如:

<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android">    <item android:id="@+id/new_game"          android:icon="@drawable/ic_new_game"          android:title="@string/new_game"          android:showAsAction="ifRoom"/>    <item android:id="@+id/help"          android:icon="@drawable/ic_help"          android:title="@string/help" /></menu>
  • android:icon
    引用一个要用作项目图标的 Drawable 类。
  • android:title
    引用一个要用作项目标题的字符串。
  • android:showAsAction
    指定此项应作为操作项目显示在操作栏中的时间和方式。

toolbar右边的三个点是 操作栏右侧的操作溢出菜单,与手机物理菜单按键作用一样
需要支持快速访问的重要操作,可以在相应的 中添加 android:showAsAction=”ifRoom” ,从而将此项提升到操作栏中。

android:showAsAction总共有五个属性。

  • never:永远不会显示。只会在溢出列表中显示。
  • ifRoom:会显示在Item中,但是如果已经有4个或者4个以上的Item时会隐藏在溢出列表中。
  • always:无论是否溢出,总会显示。
  • withText:Title会显示。
  • collapseActionView:可拓展的Item。

小拓展:

Android 2.3.x 及更低版本的系统,则当用户首次打开选项菜单时,系统会调用 onCreateOptionsMenu() 来创建该菜单。如果您开发的应用是用于 Android 3.0 及更高版本的系统,则系统将在启动 Activity 时调用 onCreateOptionsMenu(),以便向操作栏显示项目。

在 Activity 生命周期中发生的事件修改选项菜单,则可通过 onPrepareOptionsMenu() 方法执行此操作。
在 Android 2.3.x 及更低版本中,每当用户打开选项菜单时(按“菜单”按钮),系统均会调用 onPrepareOptionsMenu()。
在 Android 3.0 及更高版本中,当菜单项显示在操作栏中时,选项菜单被视为始终处于打开状态。发生事件时,如果您要执行菜单更新,则必须调用 invalidateOptionsMenu() 来请求系统调用 onPrepareOptionsMenu()。

要想长按(或者选中复选框或视图内的类似 UI 组件)显示出来上下文操作模式,如网易新闻长按顶部出现的复制粘贴等。有的控件webview会默认实现。
为单个视图启用上下文操作模式
如果希望仅当用户选择特定视图时才调用上下文操作模式,则应:
实现 ActionMode.Callback 接口。在其回调方法中,您既可以为上下文操作栏指定操作,又可以响应操作项目的点击事件,还可以处理操作模式的其他生命周期事件。
当需要显示操作栏时(例如,用户长按视图),请调用 startActionMode()。

private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {    // Called when the action mode is created; startActionMode() was called    @Override    public boolean onCreateActionMode(ActionMode mode, Menu menu) {        // Inflate a menu resource providing context menu items        MenuInflater inflater = mode.getMenuInflater();        inflater.inflate(R.menu.context_menu, menu);        return true;    }    // Called each time the action mode is shown. Always called after onCreateActionMode, but    // may be called multiple times if the mode is invalidated.    @Override    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {        return false; // Return false if nothing is done    }    // Called when the user selects a contextual menu item    @Override    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {        switch (item.getItemId()) {            case R.id.menu_share:                shareCurrentItem();                mode.finish(); // Action picked, so close the CAB                return true;            default:                return false;        }    }    // Called when the user exits the action mode    @Override    public void onDestroyActionMode(ActionMode mode) {        mActionMode = null;    }};

更多资料参考:
http://developer.android.com/intl/zh-cn/guide/topics/ui/menus.html#context-menu
http://stackoverflow.com/questions/26443403/toolbar-and-contextual-actionbar-with-appcompat-v7/26450875#26450875
http://blog.csdn.net/eclipsexys/article/details/8688538
http://blog.csdn.net/jflex/article/details/7854573

  相关解决方案