Toolbar 中 style 的自定義及加載過程

304501989 7年前發布 | 9K 次閱讀 安卓開發 Android開發 移動開發

不久前,公司里設計師大大躊躇滿志的說我們的app要改版。首當其沖的就是主題色的改變,由紅色改為白色。并且界面改為扁平風格。那么意味著需要對所有界面里的ActionBar或者ToolBar都要進行主題樣式與elevation的修改。最后的結果如下圖:

最簡便的方法自然是定義style來更換,如果都在Java代碼里去改的話工作量變多不說且都是重復的勞動。也不利于代碼的維護。

一.定義Style

1.ActionBar的Style定義

4.4及以下版本style.xml:

<style name="AppTheme.ActionBar" parent="AppTheme">
    <!--ActionBar是否懸浮覆蓋在你的布局上-->
    <item name="windowActionBarOverlay">false</item>
    <!--定義ActionBar窗體的背景-->
    <item name="android:windowContentOverlay">@null</item>
    <!--定義ActionBar的樣式-->
    <item name="actionBarStyle">@style/AppTheme.ActionBarStyle</item>
    <!--定義Actionbar上Menu的字體樣式-->
    <item name="actionMenuTextAppearance">@style/AppTheme.MyActionBarMenuTextStyle</item>
    <!--定義Actionbar上Menu的字體顏色-->
    <item name="actionMenuTextColor">@color/wechat_color</item>
    <!--定義Actionbar上回退按鈕的圖片-->
    <item name="homeAsUpIndicator">@drawable/icon_back_black</item>
</style>

<style name="AppTheme.ActionBarStyle" parent="Widget.AppCompat.Light.ActionBar">
    <!--定義Actionbar上Title的樣式-->
    <item name="titleTextStyle">@style/AppTheme.ActionBarTitleTextStyle</item>
    <!--定義Actionbar的背景,R.drawable.bg_frame是最底部為橫線,其余位置是透明的.9圖片 -->
    <item name="background">@drawable/bg_frame</item>
</style>

5.0及以上版本的style.xml:

<style name="AppTheme.ActionBar" parent="AppTheme">
    <!--ActionBar是否懸浮覆蓋在你的布局上-->
    <item name="windowActionBarOverlay">false</item>
    <!--定義ActionBar的樣式-->
    <item name="actionBarStyle">@style/AppTheme.ActionBarStyle</item>
    <!--定義Actionbar上Menu的字體樣式-->
    <item name="actionMenuTextAppearance">@style/AppTheme.ActionBarMenuTextStyle</item>
    <!--定義Actionbar上Menu的字體顏色-->
    <item name="actionMenuTextColor">@color/wechat_color</item>
    <!--定義Actionbar上回退按鈕的圖片-->
    <item name="homeAsUpIndicator">@drawable/icon_back_black</item>
</style>

<style name="AppTheme.ActionBarStyle" parent="@style/Widget.AppCompat.Light.ActionBar">
    <item name="titleTextStyle">@style/AppTheme.ActionBarTitleTextStyle</item>
    <item name="background">@color/colorPrimary</item>
    <item name="elevation">1dp</item>
</style>

主題色:

<style name="AppTheme" parent="Theme.AppCompat.Light">
    <!--主題色-->
    <item name="colorPrimary">@color/colorPrimary</item>
    <!--強調色-->
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <!--點綴色-->
    <item name="colorAccent">@color/colorAccent</item>
</style>

文字樣式的定義:

<style name="AppTheme.ActionBarTitleTextStyle" parent="TextAppearance.AppCompat.Widget.ActionBar.Title">
    <item name="android:textSize">16sp</item>
    <item name="android:textColor">@color/非死book_color</item>
</style>

<style name="AppTheme.ActionBarMenuTextStyle" parent="TextAppearance.AppCompat.Widget.ActionBar.Menu">
    <item name="android:textSize">12sp</item>
</style>

在Activity中引用style:

<activity
    android:name=".ActionBarActivity"
    android:theme="@style/AppTheme.ActionBar" />

注意:Android4.4版本及以下ActionBar取消elevation必須設置windowContentOverlay屬性為null,這樣背景就是默認的灰色了,所以還需要自己定義ActionBar的背景,如果在ActionBar底部需要分割線還要做一個.9的圖片設置為ActionBar的背景。

2.ToolBar的Style定義

在style.xml中定義ToolBar樣式:

<style name="AppTheme.ToolBar" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <!--定義ToolBar上Menu的字體樣式-->
    <item name="actionMenuTextAppearance">@style/AppTheme.MyActionBarMenuTextStyle</item>
    <!--定義ToolBar上Menu的字體顏色-->
    <item name="actionMenuTextColor">@color/wechat_color</item>
    <!--定義ToolBar上回退按鈕的圖片-->
    <item name="homeAsUpIndicator">@drawable/icon_back_black</item>
</style>

<!--定義ToolBar上Title的文字樣式-->
<style name="AppTheme.ToolbarTitleTextStyle" parent="TextAppearance.Widget.AppCompat.Toolbar.Title">
    <item name="android:textSize">16sp</item>
    <item name="android:textColor">@color/非死book_color</item>
</style>

在layout文件中設置ToolBar的文字樣式:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    android:orientation="vertical">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:stateListAnimator="@animator/appbar_elevation">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="?attr/actionBarSize"
            app:titleTextAppearance="@style/AppTheme.ToolbarTitleTextStyle" />
    </android.support.design.widget.AppBarLayout>
</LinearLayout>

在Activity中引用style,并且Activity繼承supportV7包中的 AppCompatActivity

<activity
    android:name=".ToolBarActivity"
    android:theme="@style/AppTheme.ToolBar" />

注意:Android4.4版本及以下因為不支持elevation屬性,所以需要添加下面的代碼才能顯示ToolBar底部的橫線。R.drawable.bg_frame是最底部為橫線,背景透明的.9圖片:

if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
    ViewCompat.setBackground(findViewById(R.id.appbar), ContextCompat.getDrawable(this, R.drawable.bg_frame));
}

在Demo中最后的效果如下圖,可以看到返回按鈕、Title、Menu上的文字大小和顏色都是style定義后的。

二.遇到的坑

  1. 定義ActionBar樣式時,4.4及以下版本手機設置了<item name="android:windowContentOverlay">@null</item>后,必須為ActionBar設置背景,否則ActionBar是默認的顏色
  2. 4.4及以下版本手機不支持elevation屬性,所以在ActionBar底部的分割線或陰影效果需要自己做圖片。
  3. Menu菜單的文字顏色必須通過actionMenuTextColor屬性設置,在actionMenuTextAppearance屬性中設置textColor無效。
  4. ToolBar的文字樣式titleTextAppearance必須在layout布局文件中引用,如果像Actionbar一樣只在style.xml中定義是無效的。
  5. AppBarLayout的背景和elevation是由stateListAnimator控制的,如果需要改變elevation高度必須自定義stateListAnimator。因為stateListAnimator是5.0版本后的屬性,4.4及以下版本手機必須重新設置AppBarLayout的background屬性。

三.源碼之下,了無秘密

修改Actionbar的樣式固然很快,但是為了知道為什么會有上面寫到的在定義style屬性時遇到的坑,所以帶著問題看看源碼,在源碼之下我們可以了解到ActionBar或ToolBar中的Style在AppCompatActivity中是如何被加載的。

注意:下面貼出的源碼不是完整的google官方代碼,只截取了關鍵部分。

首先AppCompatActivity在執行onCreate方法時創建了 AppCompatDelegate 對象,并進行了AppCompatDelegate的初始化。

AppCompatDelegate相當于一個委托,appcompat適配包中一些方法委托AppCompatDelegate來調用。

protected void onCreate(@Nullable Bundle savedInstanceState) {    
    final AppCompatDelegate delegate = getDelegate();//執行AppCompatDelegate.create();
    //初始化工作
    delegate.installViewFactory();
    delegate.onCreate(savedInstanceState);
    super.onCreate(savedInstanceState);
}

//根據Android系統版本創建AppCompatDelegate對象
private static AppCompatDelegate create(Context context, Window window, AppCompatCallback callback) {
    final int sdk = Build.VERSION.SDK_INT;
    if (BuildCompat.isAtLeastN()) {
        return new AppCompatDelegateImplN(context, window, callback);
    } else if (sdk >= 23) {
        return new AppCompatDelegateImplV23(context, window, callback);
    } else if (sdk >= 14) {
        return new AppCompatDelegateImplV14(context, window, callback);
    } else if (sdk >= 11) {
        return new AppCompatDelegateImplV11(context, window, callback);
    } else {
        return new AppCompatDelegateImplV9(context, window, callback);
    }
}

onCreate結束之后,在Activity中調用setContentView()方法后,AppCompatActivity中會執行ensureSubDecor()方法,這個方法具體做了ActionBar窗體的創建,并使ActionBar依附到屏幕的Window中去。

public void setContentView(int resId) {
    ensureSubDecor();
    ViewGroup contentParent = (ViewGroup) mSubDecor.findViewById(android.R.id.content);
    contentParent.removeAllViews();
    LayoutInflater.from(mContext).inflate(resId, contentParent);
    mOriginalWindowCallback.onContentChanged();
}

private void ensureSubDecor() {
    if (!mSubDecorInstalled) {
        mSubDecor = createSubDecor();
        onSubDecorInstalled(mSubDecor);
        mSubDecorInstalled = true;
    }
}

private ViewGroup createSubDecor() {
    //加載Activity的主題
    TypedArray a = mContext.obtainStyledAttributes(R.styleable.AppCompatTheme);
    if (!a.hasValue(R.styleable.AppCompatTheme_windowActionBar)) {
        a.recycle();
        throw new IllegalStateException(
                "You need to use a Theme.AppCompat theme (or descendant) with this activity.");
    }
    //讀取windowNoTitle屬性,判斷是否需要ActionBar
    if (a.getBoolean(R.styleable.AppCompatTheme_windowNoTitle, false)) {
        requestWindowFeature(Window.FEATURE_NO_TITLE);
    } else if (a.getBoolean(R.styleable.AppCompatTheme_windowActionBar, false)) {
        // Don't allow an action bar if there is no title.
        requestWindowFeature(FEATURE_SUPPORT_ACTION_BAR);
    }
    //讀取windowActionBarOverlay屬性
    if (a.getBoolean(R.styleable.AppCompatTheme_windowActionBarOverlay, false)) {
        requestWindowFeature(FEATURE_SUPPORT_ACTION_BAR_OVERLAY);
    }
    //讀取windowActionModeOverlay屬性
    if (a.getBoolean(R.styleable.AppCompatTheme_windowActionModeOverlay, false)) {
        requestWindowFeature(FEATURE_ACTION_MODE_OVERLAY);
    }
    //讀取android:windowIsFloating屬性
    mIsFloating = a.getBoolean(R.styleable.AppCompatTheme_android_windowIsFloating, false);
    a.recycle();

    // Now let's make sure that the Window has installed its decor by retrieving it
    mWindow.getDecorView();

    final LayoutInflater inflater = LayoutInflater.from(mContext);
    ViewGroup subDecor = null;

    if (!mWindowNoTitle) {
        //當需要ActionBar時執行下面的邏輯
        if (mIsFloating) {
            //省略
        } else if (mHasActionBar) {
            //讀取ActionBar主題
            TypedValue outValue = new TypedValue();
            mContext.getTheme().resolveAttribute(R.attr.actionBarTheme, outValue, true);
            //加載ActionBar窗體的布局文件R.layout.abc_screen_toolbar
            subDecor = (ViewGroup) LayoutInflater.from(themedContext).inflate(R.layout.abc_screen_toolbar, null);
            mDecorContentParent = (DecorContentParent) subDecor.findViewById(R.id.decor_content_parent);
            mDecorContentParent.setWindowCallback(getWindowCallback());
        }
    } else {
        //省略
    }

    //在該方法的最后會把ActionBar的窗體加載到屏幕的整個Window中去
    mWindow.setContentView(subDecor);
    return subDecor;
}

上面的代碼我們看到映射了一個名為abc_screen_toolbar.xml的布局文件,在這個xml布局文件中引用了Toolbar,并且可以看到聲明了屬性style="?attr/toolbarStyle",那么是不是這個toolBarStyle就決定了ToolBar的樣式呢?我們繼續往下看。

<android.support.v7.widget.ActionBarOverlayLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:id="@+id/decor_content_parent"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">

    <include layout="@layout/abc_screen_content_include"/>

    <android.support.v7.widget.ActionBarContainer
            android:id="@+id/action_bar_container"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            style="?attr/actionBarStyle"
            android:touchscreenBlocksFocus="true"
            android:gravity="top">

        <android.support.v7.widget.Toolbar
                android:id="@+id/action_bar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:navigationContentDescription="@string/abc_action_bar_up_description"
                style="?attr/toolbarStyle"/>

        <android.support.v7.widget.ActionBarContextView
                android:id="@+id/action_context_bar"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:visibility="gone"
                android:theme="?attr/actionBarTheme"
                style="?attr/actionModeStyle"/>

    </android.support.v7.widget.ActionBarContainer>
</android.support.v7.widget.ActionBarOverlayLayout>

接下來會執行Toolbar的構造函數,其中引用的style也是在xml布局文件里所聲明的。

public Toolbar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    final TintTypedArray a = TintTypedArray.obtainStyledAttributes(getContext(), attrs,R.styleable.Toolbar, defStyleAttr, 0);    
    //標題文字樣式
    mTitleTextAppearance = a.getResourceId(R.styleable.Toolbar_titleTextAppearance, 0);
    mSubtitleTextAppearance = a.getResourceId(R.styleable.Toolbar_subtitleTextAppearance, 0);    
    //標題
    final CharSequence title = a.getText(R.styleable.Toolbar_title);
    if (!TextUtils.isEmpty(title)) {
        setTitle(title);
    } 
    //設置返回按鈕的Icon
    final Drawable navIcon = a.getDrawable(R.styleable.Toolbar_navigationIcon);
    if (navIcon != null) {
        setNavigationIcon(navIcon);
    }
    //設置title文字顏色
    if (a.hasValue(R.styleable.Toolbar_titleTextColor)) {
        setTitleTextColor(a.getColor(R.styleable.Toolbar_titleTextColor, 0xffffffff));
    }
    //設置subtitle文字顏色
    if (a.hasValue(R.styleable.Toolbar_subtitleTextColor)) {
        setSubtitleTextColor(a.getColor(R.styleable.Toolbar_subtitleTextColor, 0xffffffff));
    }
}

Toolbar構造完成后繪制 ActionBarOverlayLayout 時,會調用ActionBarOverlayLayout中的pullChildren()與getDecorToolbar()兩個方法,在為全局變量mDecorToolbar 賦值時會創建一個Toolbar的包裝器 ToolbarWidgetWrapper

void pullChildren() {
    if (mContent == null) {
        mContent = (ContentFrameLayout) findViewById(R.id.action_bar_activity_content);
        mActionBarTop = (ActionBarContainer) findViewById(R.id.action_bar_container);
        mDecorToolbar = getDecorToolbar(findViewById(R.id.action_bar));
    }
}

private DecorToolbar getDecorToolbar(View view) {
       if (view instanceof Toolbar) {
           return ((Toolbar) view).getWrapper();
       } 
}

public DecorToolbar getWrapper() {
    if (mWrapper == null) {
        mWrapper = new ToolbarWidgetWrapper(this, true);
    }
    return mWrapper;
}

在Toolbar的包裝器 ToolbarWidgetWrapper 中,會加載actionBarStyle這個style中的屬性,如homeAsUpIndicator定義了回退鍵的圖片,titleTextStyle定義了Title的樣式。所以ActionBar的樣式最后加載的style都是在這個ToolbarWidgetWrapper中完成的。

public ToolbarWidgetWrapper(Toolbar toolbar, boolean style,int defaultNavigationContentDescription, int defaultNavigationIcon) {
    mToolbar = toolbar;
    mTitle = toolbar.getTitle();
    mSubtitle = toolbar.getSubtitle();
    mTitleSet = mTitle != null;
    mNavIcon = toolbar.getNavigationIcon();
    final TintTypedArray a = TintTypedArray.obtainStyledAttributes(toolbar.getContext(), null, R.styleable.ActionBar, R.attr.actionBarStyle, 0);
    mDefaultNavigationIcon = a.getDrawable(R.styleable.ActionBar_homeAsUpIndicator);
    if (style) {
        final CharSequence title = a.getText(R.styleable.ActionBar_title);
        if (!TextUtils.isEmpty(title)) {
            setTitle(title);
        }

        final CharSequence subtitle = a.getText(R.styleable.ActionBar_subtitle);
        if (!TextUtils.isEmpty(subtitle)) {
            setSubtitle(subtitle);
        }

        final Drawable logo = a.getDrawable(R.styleable.ActionBar_logo);
        if (logo != null) {
            setLogo(logo);
        }

        final Drawable icon = a.getDrawable(R.styleable.ActionBar_icon);
        if (icon != null) {
            setIcon(icon);
        }
        if (mNavIcon == null && mDefaultNavigationIcon != null) {
            setNavigationIcon(mDefaultNavigationIcon);
        }
        setDisplayOptions(a.getInt(R.styleable.ActionBar_displayOptions, 0));

        final int customNavId = a.getResourceId(
                R.styleable.ActionBar_customNavigationLayout, 0);
        if (customNavId != 0) {
            setCustomView(LayoutInflater.from(mToolbar.getContext()).inflate(customNavId,mToolbar, false));
            setDisplayOptions(mDisplayOpts | ActionBar.DISPLAY_SHOW_CUSTOM);
        }

        final int height = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
        if (height > 0) {
            final ViewGroup.LayoutParams lp = mToolbar.getLayoutParams();
            lp.height = height;
            mToolbar.setLayoutParams(lp);
        }

        final int contentInsetStart = a.getDimensionPixelOffset(R.styleable.ActionBar_contentInsetStart,  -1);
        final int contentInsetEnd = a.getDimensionPixelOffset(R.styleable.ActionBar_contentInsetEnd,  -1);
        if (contentInsetStart >= 0 || contentInsetEnd >= 0) {
            mToolbar.setContentInsetsRelative(Math.max(contentInsetStart, 0), Math.max(contentInsetEnd, 0));
        }

        final int titleTextStyle = a.getResourceId(R.styleable.ActionBar_titleTextStyle, 0);
        if (titleTextStyle != 0) {
            mToolbar.setTitleTextAppearance(mToolbar.getContext(), titleTextStyle);
        }

        final int subtitleTextStyle = a.getResourceId(R.styleable.ActionBar_subtitleTextStyle, 0);
        if (subtitleTextStyle != 0) {
            mToolbar.setSubtitleTextAppearance(mToolbar.getContext(), subtitleTextStyle);
        }

        final int popupTheme = a.getResourceId(R.styleable.ActionBar_popupTheme, 0);
        if (popupTheme != 0) {
            mToolbar.setPopupTheme(popupTheme);
        }
    } else {
        mDisplayOpts = detectDisplayOptions();
    }
    a.recycle();
}

最后在調用getSupportActionBar()時會進入initWindowDecorActionBar()方法。ActionBar是一個抽象類, WindowDecorActionBar 則是ActionBar的具體實現。在init過程中看到了對elevation的設置。

public void initWindowDecorActionBar() {
    ensureSubDecor();
    if (!mHasActionBar || mActionBar != null) {
        return;
    }
    if (mOriginalWindowCallback instanceof Activity) {
        mActionBar = new WindowDecorActionBar((Activity) mOriginalWindowCallback,
                mOverlayActionBar);
    }    
}

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

private void init(View decor) {
    mOverlayLayout = (ActionBarOverlayLayout) decor.findViewById(R.id.decor_content_parent);

    mDecorToolbar = getDecorToolbar(decor.findViewById(R.id.action_bar));
    mContextView = (ActionBarContextView) decor.findViewById(R.id.action_context_bar);
    mContainerView = (ActionBarContainer) decor.findViewById(R.id.action_bar_container);

    mContext = mDecorToolbar.getContext();

    final int elevation = a.getDimensionPixelSize(R.styleable.ActionBar_elevation, 0);
    if (elevation != 0) {
        setElevation(elevation);
    }
    a.recycle();
}

public void setElevation(float elevation) {
    ViewCompat.setElevation(mContainerView, elevation);
}

如果ActionBar上有Menu時,會調用ToolbarWidgetWrapper中setMenu方法,執行ActionMenuPresenter的構造函數,ActionMenuPresenter構造函數中第二個參數是每個menu item的父布局,第三個參數就對應某個menu item的布局。Menu item的xml布局中引用了 actionMenuTextAppearance actionMenuTextColor 兩個屬性,所以知道了,menu item的字體和顏色是由這兩個屬性控制的。

public void setMenu(Menu menu, MenuPresenter.Callback cb) {
    if (mActionMenuPresenter == null) {
        mActionMenuPresenter = new ActionMenuPresenter(mToolbar.getContext());
        mActionMenuPresenter.setId(R.id.action_menu_presenter);
    }
    mActionMenuPresenter.setCallback(cb);
    mToolbar.setMenu((MenuBuilder) menu, mActionMenuPresenter);
}

public ActionMenuPresenter(Context context) {
    super(context, R.layout.abc_action_menu_layout, R.layout.abc_action_menu_item_layout);
}

<android.support.v7.internal.view.menu.ActionMenuItemView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:gravity="center"
    android:focusable="true"
    android:paddingTop="4dip"
    android:paddingBottom="4dip"
    android:paddingLeft="8dip"
    android:paddingRight="8dip"
    android:textAppearance="?attr/actionMenuTextAppearance"
    android:textColor="?attr/actionMenuTextColor"
    style="?attr/actionButtonStyle"/>

為什么在style.xml中定義toolbar的style無效,只能在toolbar的布局文件中引用呢?是因為Toolbar讀取的是layout布局文件中的style,并且在構造ToolbarWidgetWrapper對象時也并不會和ActionBar一樣去讀取actionbar的屬性。因為在調用setSupportActionBar()后會構造一個ToolbarActionBar,ToolbarActionBar中又會構造一個ToolbarWidgetWrapper,而ToolbarWidgetWrapper的構造函數中第二個參數在源碼中傳入的是false,所以不會在ToolbarWidgetWrapper進行style的加載,只會在創建Toolbar時進行style的加載。

public void setSupportActionBar(Toolbar toolbar) {
    if (toolbar != null) {
        final ToolbarActionBar tbab = new ToolbarActionBar(toolbar,((Activity) mOriginalWindowCallback).getTitle(), mAppCompatWindowCallback);
    }
    invalidateOptionsMenu();
}

public ToolbarActionBar(Toolbar toolbar, CharSequence title, Window.Callback callback) {
    mDecorToolbar = new ToolbarWidgetWrapper(toolbar, false);
}

public ToolbarWidgetWrapper(Toolbar toolbar, boolean style,int defaultNavigationContentDescription, int defaultNavigationIcon) {   
    if (style) {
        //不執行
        final CharSequence title = a.getText(R.styleable.ActionBar_title);
        if (!TextUtils.isEmpty(title)) {
            setTitle(title);
        }

        final CharSequence subtitle = a.getText(R.styleable.ActionBar_subtitle);
        if (!TextUtils.isEmpty(subtitle)) {
            setSubtitle(subtitle);
        }
       ...
    } else {
        mDisplayOpts = detectDisplayOptions();
    }
    a.recycle();
}

最后:

更詳細的參考 Demo 在github中,如果有錯誤也希望大家能夠指出,覺得能幫到你的話給個Star吧。

 

項目主頁:http://www.baiduhome.net/lib/view/home/1490749004792

 本文由用戶 304501989 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!