Android ActionBar 实现原理

一,启用ActionBar

是否启用ActionBar,是由window的feature判断的, 如下:

    private void initWindowDecorActionBar() {
        Window window = getWindow();


        // Initializing the window decor can change window feature flags.
        // Make sure that we have the correct set before performing the test below.
        window.getDecorView();


        if (isChild() || !window.hasFeature(Window.FEATURE_ACTION_BAR) || mActionBar != null) {
            return;
        }


        mActionBar = new WindowDecorActionBar(this);
        mActionBar.setDefaultDisplayHomeAsUpEnabled(mEnableDefaultActionBarUp);


        mWindow.setDefaultIcon(mActivityInfo.getIconResource());
        mWindow.setDefaultLogo(mActivityInfo.getLogoResource());
    }

Window.FEATURE_ACTION_BAR feature的申请是在 PhoneWindow.generateLayout 方法中完成的。申请的代码如下:

        if (a.getBoolean(R.styleable.Window_windowNoTitle, false)) {
            requestFeature(
FEATURE_NO_TITLE);
        } else if (a.getBoolean(R.styleable.Window_windowActionBar, false)) {
            // Don't allow an action bar if there is no title.
            requestFeature(FEATURE_ACTION_BAR);
        }

由此可见,是否申请actionbar,由windowActionBar属性的值来判断。这个属性在不同的 Theme 下的值不一样。在高版本的Android中,这个属性都是true。


用户可以在Activity.onCreate中,调用requestFeature(FEATURE_ACTION_BAR); 来手动启用ActionBar。

  1. @Override  
  2. public void onCreate(Bundle savedInstanceState) {  
  3.   super.onCreate(savedInstanceState);  
  4.  
  5.   getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY);  
  6.  
  7.   setContentView(R.layout.main);  
  8. }  

如果用户想用Toolbar代替默认的ActionBar,可以用如下代码:

<style name="AppTheme.Base" parent="Theme.AppCompat"> 

<item name="windowActionBar">false</item> 

<item name="windowNoTitle">true</item> 

</style>

private void setToolbar(){ 

Toolbar toolbar= (Toolbar) findViewById(R.id.toolbar); 

//设置APP图标 

toolbar.setLogo(R.mipmap.ic_launcher); 

//设置title 

toolbar.setTitle("欢迎页"); 

//设置副标题 zxcv 

toolbar.setSubtitle("副标题"); 

setSupportActionBar(toolbar); //设置toolabar 

//设置导航图标一定要设置在setsupportactionbar后面才有用不然他会显示小箭头 

toolbar.setNavigationIcon(R.mipmap.ic_launcher); 

toolbar.setOnMenuItemClickListener(onMenuItemClick); 

}

二,ActionBar的接口和实现

第一种实现

public class WindowDecorActionBar extendsActionBar

    public WindowDecorActionBar(Activity activity) {
        mActivity = activity;
        Window window = activity.getWindow();
        View decor = window.getDecorView();
        boolean overlayMode = mActivity.getWindow().hasFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
       
init(decor);
        if (!overlayMode) {
            mContentView = decor.findViewById(android.R.id.content);
        }
    }

    private void init(View decor) {
        mOverlayLayout = (
ActionBarOverlayLayout) decor.findViewById(    actionbar的实现包含在对应的layout文件中
                com.android.internal.R.id.decor_content_parent);


第二种实现

    public void setActionBar(@NullableToolbar toolbar) {
        ToolbarActionBar tbab = new ToolbarActionBar(toolbar, getTitle(), this);  第二种实现
        mActionBar = tbab;
        mWindow.setCallback(tbab.getWrappedWindowCallback());
        mActionBar.invalidateOptionsMenu();
    }

public class ToolbarActionBar extendsActionBar

第二种实现中,toolbar需要定义在整个layout的最上面


三,Toolbar中对menu的特殊处理

ToolbarActionBar中,定义了一个Window.Callback接口,监听onPreparePanel

public class WindowCallbackWrapper implements Window.Callback {

    private class ToolbarCallbackWrapper extends WindowCallbackWrapper {
        public ToolbarCallbackWrapper(Window.Callback wrapped) {    参数为Activity类对象,它实现了Window.Callback 接口,即ToolbarCallbackWrapper 只是包装了Activity的实现,并覆盖了onPreparePanel
            super(wrapped);
        }

        @Override
        public boolean onPreparePanel(int featureId, View view, Menu menu) {
            final boolean result = super.onPreparePanel(featureId, view, menu);
            if (result && !mToolbarMenuPrepared) {
                mDecorToolbar.setMenuPrepared();
                mToolbarMenuPrepared = true;
            }
            return result;
        }
    }


四,Toolbar的使用说明

http://www.cnblogs.com/huangjianboke/p/5386860.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值