Android Theme and Menu 主题菜单相关

标签: themes
1912人阅读 评论(0) 收藏 举报
分类:

出自 微凉一季的博客

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

1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:257391次
    • 积分:3487
    • 等级:
    • 排名:第9472名
    • 原创:76篇
    • 转载:1篇
    • 译文:1篇
    • 评论:35条
    互动交流
    为了让这个id看起来像是个做技术的,我把这个模块之前情怀的流露忍痛去掉了。要做个正经的人!
    最新评论