Gallery3d 学习笔记(16)

本文深入剖析了Gallery应用中ActionBar的设计与实现,包括其显示与隐藏的控制逻辑、菜单项的定制及不同模式下的行为变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前面我们详细了解了Gallery中如何组织各种页,并且如何用工厂模式生成这些页面,并且使用栈的压入和弹出实现页面的切换,下面我们就直接看看细节问题,首先是最上面的ActionBar


public class AbstractGalleryActivity extends Activity implements GalleryContext {
    private static final String TAG = "AbstractGalleryActivity";
    private GLRootView mGLRootView;
    private StateManager mStateManager;
    private GalleryActionBar mActionBar;                        //ActionBar出现在了这里
    private OrientationManager mOrientationManager;


而且提供一个接口给各部门调用,所有想控制ActionBar的页面都可以调用这个接口取得ActionBar

    public GalleryActionBar getGalleryActionBar() {
        if (mActionBar == null) {
            mActionBar = new GalleryActionBar(this);
        }
        else {
            mActionBar.updateGalleryActionBar(this);
        }
        
        return mActionBar;
    }


说句实话,我觉得ActionBar ,至少图库的ActionBar不那么美观。


我们可以将它去掉,比如我们在某些时候就将它隐藏起来了,ActivityState中

 void resume() {
        if (IS_TESTABLE) {
            android.util.Log.startPerfTracking("[" + TAG + "] "
                    + "resume");
        }
        AbstractGalleryActivity activity = mActivity;
        ActionBar actionBar = activity.getActionBar();
        if (actionBar != null) {
            if ((mFlags & FLAG_HIDE_ACTION_BAR) != 0) {
                actionBar.hide();              //隐藏ActionBar
            } else {
                actionBar.show();
            }
            int stateCount = mActivity.getStateManager().getStateCount();
            mActivity.getGalleryActionBar().setDisplayOptions(stateCount > 1, true);
            // Default behavior, this can be overridden in ActivityState's onResume.
            actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
        }

我们也可以把左上角的难看的图标去掉,在Styles.xml中的

Holo.ActionBar中的单项修改一下

<item name="android:displayOptions" >useLogo | showHome</item>

改为

<item name="android:displayOptions" >none</item>

即可去掉所有状态下的图标


图标显示位置之后是一个丑陋的下拉菜单,是哪里写的呢?


首先找到菜单,GalleryActionBar.java有这个5五个菜单ActionItem

    private static final ActionItem[] sClusterItems = new ActionItem[] {
        new ActionItem(FilterUtils.CLUSTER_BY_ALBUM, true, false, R.string.albums,
                R.string.group_by_album),
        new ActionItem(FilterUtils.CLUSTER_BY_LOCATION, true, false,
                R.string.locations, R.string.location, R.string.group_by_location),
        new ActionItem(FilterUtils.CLUSTER_BY_TIME, true, false, R.string.times,
                R.string.time, R.string.group_by_time),
        new ActionItem(FilterUtils.CLUSTER_BY_FACE, true, false, R.string.people,
                R.string.group_by_faces),
        new ActionItem(FilterUtils.CLUSTER_BY_TAG, true, false, R.string.tags,
                R.string.group_by_tags)
    };


要继续关联到ActionBar中去的呢?来看几个重要的函数

    public void enableClusterMenu(int action, ClusterRunner runner) {
        if (mActionBar != null) {
            // Don't set cluster runner until action bar is ready.
            mClusterRunner = null;
            mActionBar.setListNavigationCallbacks(mAdapter, this);
            mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
            setSelectedAction(action);
            mClusterRunner = runner;
        }
    }

    // The only use case not to hideMenu in this method is to ensure
    // all elements disappear at the same time when exiting gallery.
    // hideMenu should always be true in all other cases.
    public void disableClusterMenu(boolean hideMenu) {
        if (mActionBar != null) {
            mClusterRunner = null;
            if (hideMenu) {
                mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
            }
        }
    }

    public void enableAlbumModeMenu(int selected, OnAlbumModeSelectedListener listener) {
        if (mActionBar != null) {
            if (mAlbumModeAdapter == null) {
                // Initialize the album mode options if they haven't been already
                Resources res = mActivity.getResources();
                mAlbumModes = new CharSequence[] {
                        res.getString(R.string.switch_photo_filmstrip),
                        res.getString(R.string.switch_photo_grid)};
                mAlbumModeAdapter = new AlbumModeAdapter();
            }
            mAlbumModeListener = null;
            mLastAlbumModeSelected = selected;
            mActionBar.setListNavigationCallbacks(mAlbumModeAdapter, this);
            mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
            mActionBar.setSelectedNavigationItem(selected);
            mAlbumModeListener = listener;
        }
    }

    public void disableAlbumModeMenu(boolean hideMenu) {
        if (mActionBar != null) {
            mAlbumModeListener = null;
            if (hideMenu) {
                mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
            }
        }
    }


这里面内容比较多。


首先 这几个函数是使用下拉菜单和禁用下拉菜单的调用接口。为什么有两套开和关的代码?

一套是普通情况预览的模式,一套是相册模式预览的模式(进入相册后会发现ActionBar的下拉菜单变化了,变成了网格视图和幻灯片视图,这就是相册模式)


接着,大家可以看到谷歌设计的是

mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
是下拉列表的风格,我一直很奇怪,为什么谷歌喜欢这种丑陋的风格,难道就是因为空间可以放无数的内容么?


其实明明设计框架的时候,是有更加漂亮的风格

NAVIGATION_MODE_TABS

如果我们直接将风格给为TABS,那么界面会变成TABS效果么?


当然不行,还有很多地方要修改,比如LIST风格需要选择其中任何一个的的时候需要回调一些函数,来显示不同的界面对吧?


那么设置不同的回调函数就需要修改。

mActionBar.setListNavigationCallbacks(mAdapter, this);

这里面有个适配器,下面大家要回忆设计模式的适配器模式了。


什么是适配器,说白了就是一个插头,不管什么电器,只要是符合标准的两项插头或者三项插头都可以插入交流电源使用。


接着刚才的说,你电器换了一个,这个电器是三项的插头,你是不是要去找三项的插电板去插入?


内容很多,下节课继续讲,先喝口水。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值