/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.widget; import android.annotation.NonNull; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; import android.os.Parcel; import android.os.Parcelable; import android.text.TextUtils; import android.util.AttributeSet; import android.view.Gravity; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewDebug; import android.view.ViewGroup; import com.android.internal.R; import java.util.ArrayList; import java.util.List; /** * A standard toolbar for use within application content. * *
A Toolbar is a generalization of {@link android.app.ActionBar action bars} for use * within application layouts. While an action bar is traditionally part of an * {@link android.app.Activity Activity's} opaque window decor controlled by the framework, * a Toolbar may be placed at any arbitrary level of nesting within a view hierarchy. * An application may choose to designate a Toolbar as the action bar for an Activity * using the {@link android.app.Activity#setActionBar(Toolbar) setActionBar()} method.
* *Toolbar supports a more focused feature set than ActionBar. From start to end, a toolbar * may contain a combination of the following optional elements: * *
In modern Android UIs developers should lean more on a visually distinct color scheme for * toolbars than on their application icon. The use of application icon plus title as a standard * layout is discouraged on API 21 devices and newer.
*/ public class Toolbar extends ViewGroup { private ActionMenuView mMenuView; private TextView mTitleTextView; private TextView mSubtitleTextView; private ImageButton mNavButtonView; private ImageView mLogoView; private int mTitleTextAppearance; private int mSubtitleTextAppearance; private int mTitleMarginStart; private int mTitleMarginEnd; private int mTitleMarginTop; private int mTitleMarginBottom; private final RtlSpacingHelper mContentInsets = new RtlSpacingHelper(); private int mGravity = Gravity.START | Gravity.CENTER_VERTICAL; private CharSequence mTitleText; private CharSequence mSubtitleText; // Clear me after use. private final ArrayListThis drawable should generally take the place of title text. The logo cannot be * clicked. Apps using a logo should also supply a description using * {@link #setLogoDescription(int)}.
* * @param resId ID of a drawable resource */ public void setLogo(int resId) { setLogo(getContext().getDrawable(resId)); } /** * Set a logo drawable. * *This drawable should generally take the place of title text. The logo cannot be * clicked. Apps using a logo should also supply a description using * {@link #setLogoDescription(int)}.
* * @param drawable Drawable to use as a logo */ public void setLogo(Drawable drawable) { if (drawable != null) { if (mLogoView == null) { mLogoView = new ImageView(getContext()); } if (mLogoView.getParent() == null) { addSystemView(mLogoView); } } else if (mLogoView != null && mLogoView.getParent() != null) { removeView(mLogoView); } if (mLogoView != null) { mLogoView.setImageDrawable(drawable); } } /** * Return the current logo drawable. * * @return The current logo drawable * @see #setLogo(int) * @see #setLogo(android.graphics.drawable.Drawable) */ public Drawable getLogo() { return mLogoView != null ? mLogoView.getDrawable() : null; } /** * Set a description of the toolbar's logo. * *This description will be used for accessibility or other similar descriptions * of the UI.
* * @param resId String resource id */ public void setLogoDescription(int resId) { setLogoDescription(getContext().getText(resId)); } /** * Set a description of the toolbar's logo. * *This description will be used for accessibility or other similar descriptions * of the UI.
* * @param description Description to set */ public void setLogoDescription(CharSequence description) { if (!TextUtils.isEmpty(description) && mLogoView == null) { mLogoView = new ImageView(getContext()); } if (mLogoView != null) { mLogoView.setContentDescription(description); } } /** * Return the description of the toolbar's logo. * * @return A description of the logo */ public CharSequence getLogoDescription() { return mLogoView != null ? mLogoView.getContentDescription() : null; } /** * Return the current title displayed in the toolbar. * * @return The current title */ public CharSequence getTitle() { return mTitleText; } /** * Set the title of this toolbar. * *A title should be used as the anchor for a section of content. It should * describe or name the content being viewed.
* * @param resId Resource ID of a string to set as the title */ public void setTitle(int resId) { setTitle(getContext().getText(resId)); } /** * Set the title of this toolbar. * *A title should be used as the anchor for a section of content. It should * describe or name the content being viewed.
* * @param title Title to set */ public void setTitle(CharSequence title) { if (!TextUtils.isEmpty(title)) { if (mTitleTextView == null) { final Context context = getContext(); mTitleTextView = new TextView(context); mTitleTextView.setTextAppearance(context, mTitleTextAppearance); } if (mTitleTextView.getParent() == null) { addSystemView(mTitleTextView); } } else if (mTitleTextView != null && mTitleTextView.getParent() != null) { removeView(mTitleTextView); } if (mTitleTextView != null) { mTitleTextView.setText(title); } mTitleText = title; } /** * Return the subtitle of this toolbar. * * @return The current subtitle */ public CharSequence getSubtitle() { return mSubtitleText; } /** * Set the subtitle of this toolbar. * *Subtitles should express extended information about the current content.
* * @param resId String resource ID */ public void setSubtitle(int resId) { setSubtitle(getContext().getText(resId)); } /** * Set the subtitle of this toolbar. * *Subtitles should express extended information about the current content.
* * @param subtitle Subtitle to set */ public void setSubtitle(CharSequence subtitle) { if (!TextUtils.isEmpty(subtitle)) { if (mSubtitleTextView == null) { final Context context = getContext(); mSubtitleTextView = new TextView(context); mSubtitleTextView.setTextAppearance(context, mSubtitleTextAppearance); } if (mSubtitleTextView.getParent() == null) { addSystemView(mSubtitleTextView); } } else if (mSubtitleTextView != null && mSubtitleTextView.getParent() != null) { removeView(mSubtitleTextView); } if (mSubtitleTextView != null) { mSubtitleTextView.setText(subtitle); } mSubtitleText = subtitle; } /** * Set the icon to use for the toolbar's navigation button. * *The navigation button appears at the start of the toolbar if present. Setting an icon * will make the navigation button visible.
* *If you use a navigation icon you should also set a description for its action using * {@link #setNavigationDescription(int)}. This is used for accessibility and tooltips.
* * @param resId Resource ID of a drawable to set */ public void setNavigationIcon(int resId) { setNavigationIcon(getContext().getDrawable(resId)); } /** * Set the icon to use for the toolbar's navigation button. * *The navigation button appears at the start of the toolbar if present. Setting an icon * will make the navigation button visible.
* *If you use a navigation icon you should also set a description for its action using * {@link #setNavigationDescription(int)}. This is used for accessibility and tooltips.
* * @param icon Drawable to set */ public void setNavigationIcon(Drawable icon) { if (icon != null) { ensureNavButtonView(); if (mNavButtonView.getParent() == null) { addSystemView(mNavButtonView); } } else if (mNavButtonView != null && mNavButtonView.getParent() != null) { removeView(mNavButtonView); } if (mNavButtonView != null) { mNavButtonView.setImageDrawable(icon); } } /** * Return the current drawable used as the navigation icon. * * @return The navigation icon drawable */ public Drawable getNavigationIcon() { return mNavButtonView != null ? mNavButtonView.getDrawable() : null; } /** * Set a description for the navigation button. * *This description string is used for accessibility, tooltips and other facilities * to improve discoverability.
* * @param resId Resource ID of a string to set */ public void setNavigationDescription(int resId) { setNavigationDescription(getContext().getText(resId)); } /** * Set a description for the navigation button. * *This description string is used for accessibility, tooltips and other facilities * to improve discoverability.
* * @param description String to set as the description */ public void setNavigationDescription(CharSequence description) { if (!TextUtils.isEmpty(description)) { ensureNavButtonView(); } if (mNavButtonView != null) { mNavButtonView.setContentDescription(description); } } /** * Set a listener to respond to navigation events. * *This listener will be called whenever the user clicks the navigation button * at the start of the toolbar. An icon must be set for the navigation button to appear.
* * @param listener Listener to set * @see #setNavigationIcon(android.graphics.drawable.Drawable) */ public void setNavigationOnClickListener(OnClickListener listener) { ensureNavButtonView(); mNavButtonView.setOnClickListener(listener); } /** * Return the Menu shown in the toolbar. * *Applications that wish to populate the toolbar's menu can do so from here. To use * an XML menu resource, use {@link #inflateMenu(int)}.
* * @return The toolbar's Menu */ public Menu getMenu() { if (mMenuView == null) { mMenuView = new ActionMenuView(getContext()); mMenuView.setOnMenuItemClickListener(mMenuViewItemClickListener); addSystemView(mMenuView); } return mMenuView.getMenu(); } private MenuInflater getMenuInflater() { return new MenuInflater(getContext()); } /** * Inflate a menu resource into this toolbar. * *Inflate an XML menu resource into this toolbar. Existing items in the menu will not * be modified or removed.
* * @param resId ID of a menu resource to inflate */ public void inflateMenu(int resId) { getMenuInflater().inflate(resId, getMenu()); } /** * Set a listener to respond to menu item click events. * *This listener will be invoked whenever a user selects a menu item from * the action buttons presented at the end of the toolbar or the associated overflow.
* * @param listener Listener to set */ public void setOnMenuItemClickListener(OnMenuItemClickListener listener) { mOnMenuItemClickListener = listener; } /** * Set the content insets for this toolbar relative to layout direction. * *The content inset affects the valid area for Toolbar content other than * the navigation button and menu. Insets define the minimum margin for these components * and can be used to effectively align Toolbar content along well-known gridlines.
* * @param contentInsetStart Content inset for the toolbar starting edge * @param contentInsetEnd Content inset for the toolbar ending edge * * @see #setContentInsetsAbsolute(int, int) * @see #getContentInsetStart() * @see #getContentInsetEnd() * @see #getContentInsetLeft() * @see #getContentInsetRight() */ public void setContentInsetsRelative(int contentInsetStart, int contentInsetEnd) { mContentInsets.setRelative(contentInsetStart, contentInsetEnd); } /** * Get the starting content inset for this toolbar. * *The content inset affects the valid area for Toolbar content other than * the navigation button and menu. Insets define the minimum margin for these components * and can be used to effectively align Toolbar content along well-known gridlines.
* * @return The starting content inset for this toolbar * * @see #setContentInsetsRelative(int, int) * @see #setContentInsetsAbsolute(int, int) * @see #getContentInsetEnd() * @see #getContentInsetLeft() * @see #getContentInsetRight() */ public int getContentInsetStart() { return mContentInsets.getStart(); } /** * Get the ending content inset for this toolbar. * *The content inset affects the valid area for Toolbar content other than * the navigation button and menu. Insets define the minimum margin for these components * and can be used to effectively align Toolbar content along well-known gridlines.
* * @return The ending content inset for this toolbar * * @see #setContentInsetsRelative(int, int) * @see #setContentInsetsAbsolute(int, int) * @see #getContentInsetStart() * @see #getContentInsetLeft() * @see #getContentInsetRight() */ public int getContentInsetEnd() { return mContentInsets.getEnd(); } /** * Set the content insets for this toolbar. * *The content inset affects the valid area for Toolbar content other than * the navigation button and menu. Insets define the minimum margin for these components * and can be used to effectively align Toolbar content along well-known gridlines.
* * @param contentInsetLeft Content inset for the toolbar's left edge * @param contentInsetRight Content inset for the toolbar's right edge * * @see #setContentInsetsAbsolute(int, int) * @see #getContentInsetStart() * @see #getContentInsetEnd() * @see #getContentInsetLeft() * @see #getContentInsetRight() */ public void setContentInsetsAbsolute(int contentInsetLeft, int contentInsetRight) { mContentInsets.setAbsolute(contentInsetLeft, contentInsetRight); } /** * Get the left content inset for this toolbar. * *The content inset affects the valid area for Toolbar content other than * the navigation button and menu. Insets define the minimum margin for these components * and can be used to effectively align Toolbar content along well-known gridlines.
* * @return The left content inset for this toolbar * * @see #setContentInsetsRelative(int, int) * @see #setContentInsetsAbsolute(int, int) * @see #getContentInsetStart() * @see #getContentInsetEnd() * @see #getContentInsetRight() */ public int getContentInsetLeft() { return mContentInsets.getLeft(); } /** * Get the right content inset for this toolbar. * *The content inset affects the valid area for Toolbar content other than * the navigation button and menu. Insets define the minimum margin for these components * and can be used to effectively align Toolbar content along well-known gridlines.
* * @return The right content inset for this toolbar * * @see #setContentInsetsRelative(int, int) * @see #setContentInsetsAbsolute(int, int) * @see #getContentInsetStart() * @see #getContentInsetEnd() * @see #getContentInsetLeft() */ public int getContentInsetRight() { return mContentInsets.getRight(); } private void ensureNavButtonView() { if (mNavButtonView == null) { mNavButtonView = new ImageButton(getContext(), null, R.attr.borderlessButtonStyle); } } private void addSystemView(View v) { final LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); lp.mViewType = LayoutParams.SYSTEM; addView(v, lp); } @Override protected Parcelable onSaveInstanceState() { SavedState state = new SavedState(super.onSaveInstanceState()); return state; } @Override protected void onRestoreInstanceState(Parcelable state) { final SavedState ss = (SavedState) state; super.onRestoreInstanceState(ss.getSuperState()); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int width = 0; int height = 0; int childState = 0; // System views measure first. int navWidth = 0; if (shouldLayout(mNavButtonView)) { measureChildWithMargins(mNavButtonView, widthMeasureSpec, width, heightMeasureSpec, 0); navWidth = mNavButtonView.getMeasuredWidth() + getHorizontalMargins(mNavButtonView); height = Math.max(height, mNavButtonView.getMeasuredHeight() + getVerticalMargins(mNavButtonView)); childState = combineMeasuredStates(childState, mNavButtonView.getMeasuredState()); } width += Math.max(getContentInsetStart(), navWidth); int menuWidth = 0; if (shouldLayout(mMenuView)) { measureChildWithMargins(mMenuView, widthMeasureSpec, width, heightMeasureSpec, 0); menuWidth = mMenuView.getMeasuredWidth() + getHorizontalMargins(mMenuView); height = Math.max(height, mMenuView.getMeasuredHeight() + getVerticalMargins(mMenuView)); childState = combineMeasuredStates(childState, mMenuView.getMeasuredState()); } width += Math.max(getContentInsetEnd(), menuWidth); if (shouldLayout(mLogoView)) { measureChildWithMargins(mLogoView, widthMeasureSpec, width, heightMeasureSpec, 0); width += mLogoView.getMeasuredWidth() + getHorizontalMargins(mLogoView); height = Math.max(height, mLogoView.getMeasuredHeight() + getVerticalMargins(mLogoView)); childState = combineMeasuredStates(childState, mLogoView.getMeasuredState()); } int titleWidth = 0; int titleHeight = 0; final int titleVertMargins = mTitleMarginTop + mTitleMarginBottom; final int titleHorizMargins = mTitleMarginStart + mTitleMarginEnd; if (shouldLayout(mTitleTextView)) { measureChildWithMargins(mTitleTextView, widthMeasureSpec, width + titleHorizMargins, heightMeasureSpec, titleVertMargins); titleWidth = mTitleTextView.getMeasuredWidth() + getHorizontalMargins(mTitleTextView); titleHeight = mTitleTextView.getMeasuredHeight() + getVerticalMargins(mTitleTextView); childState = combineMeasuredStates(childState, mTitleTextView.getMeasuredState()); } if (shouldLayout(mSubtitleTextView)) { measureChildWithMargins(mSubtitleTextView, widthMeasureSpec, width + titleHorizMargins, heightMeasureSpec, titleHeight + titleVertMargins); titleWidth = Math.max(titleWidth, mSubtitleTextView.getMeasuredWidth() + getHorizontalMargins(mSubtitleTextView)); titleHeight += mSubtitleTextView.getMeasuredHeight() + getVerticalMargins(mSubtitleTextView); childState = combineMeasuredStates(childState, mSubtitleTextView.getMeasuredState()); } width += titleWidth; height = Math.max(height, titleHeight); final int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { final View child = getChildAt(i); final LayoutParams lp = (LayoutParams) child.getLayoutParams(); if (lp.mViewType == LayoutParams.SYSTEM || !shouldLayout(child)) { // We already got all system views above. Skip them and GONE views. continue; } measureChildWithMargins(child, widthMeasureSpec, width, heightMeasureSpec, 0); width += child.getMeasuredWidth() + getHorizontalMargins(child); height = Math.max(height, child.getMeasuredHeight() + getVerticalMargins(child)); childState = combineMeasuredStates(childState, child.getMeasuredState()); } // Measurement already took padding into account for available space for the children, // add it in for the final size. width += getPaddingLeft() + getPaddingRight(); height += getPaddingTop() + getPaddingBottom(); final int measuredWidth = resolveSizeAndState( Math.max(width, getSuggestedMinimumWidth()), widthMeasureSpec, childState & MEASURED_STATE_MASK); final int measuredHeight = resolveSizeAndState( Math.max(height, getSuggestedMinimumHeight()), heightMeasureSpec, childState << MEASURED_HEIGHT_STATE_SHIFT); setMeasuredDimension(measuredWidth, measuredHeight); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { final boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; final int width = getWidth(); final int height = getHeight(); final int paddingLeft = getPaddingLeft(); final int paddingRight = getPaddingRight(); final int paddingTop = getPaddingTop(); final int paddingBottom = getPaddingBottom(); int left = paddingLeft; int right = width - paddingRight; if (shouldLayout(mNavButtonView)) { if (isRtl) { right = layoutChildRight(mNavButtonView, right); } else { left = layoutChildLeft(mNavButtonView, left); } } if (shouldLayout(mMenuView)) { if (isRtl) { left = layoutChildLeft(mMenuView, left); } else { right = layoutChildRight(mMenuView, right); } } left = Math.max(left, getContentInsetLeft()); right = Math.min(right, width - paddingRight - getContentInsetRight()); if (shouldLayout(mLogoView)) { if (isRtl) { right = layoutChildRight(mLogoView, right); } else { left = layoutChildLeft(mLogoView, left); } } final boolean layoutTitle = shouldLayout(mTitleTextView); final boolean layoutSubtitle = shouldLayout(mSubtitleTextView); int titleHeight = 0; if (layoutTitle) { final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams(); titleHeight += lp.topMargin + mTitleTextView.getMeasuredHeight() + lp.bottomMargin; } if (layoutSubtitle) { final LayoutParams lp = (LayoutParams) mSubtitleTextView.getLayoutParams(); titleHeight += lp.bottomMargin + mTitleTextView.getMeasuredHeight() + lp.bottomMargin; } if (layoutTitle || layoutSubtitle) { int titleTop; switch (mGravity & Gravity.VERTICAL_GRAVITY_MASK) { case Gravity.TOP: titleTop = getPaddingTop(); break; default: case Gravity.CENTER_VERTICAL: final View child = layoutTitle ? mTitleTextView : mSubtitleTextView; final LayoutParams lp = (LayoutParams) child.getLayoutParams(); final int space = height - paddingTop - paddingBottom; int spaceAbove = (space - titleHeight) / 2; if (spaceAbove < lp.topMargin + mTitleMarginTop) { spaceAbove = lp.topMargin + mTitleMarginTop; } else { final int spaceBelow = height - paddingBottom - titleHeight - spaceAbove - paddingTop; if (spaceBelow < lp.bottomMargin + mTitleMarginBottom) { spaceAbove = Math.max(0, spaceAbove - (lp.bottomMargin + mTitleMarginBottom - spaceBelow)); } } titleTop = paddingTop + spaceAbove; break; case Gravity.BOTTOM: titleTop = height - paddingBottom - titleHeight; break; } if (isRtl) { int titleRight = right; int subtitleRight = right; titleTop += mTitleMarginTop; if (layoutTitle) { final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams(); titleRight -= lp.rightMargin + mTitleMarginStart; titleTop += lp.topMargin; final int titleLeft = titleRight - mTitleTextView.getMeasuredWidth(); final int titleBottom = titleTop + mTitleTextView.getMeasuredHeight(); mTitleTextView.layout(titleLeft, titleTop, titleRight, titleBottom); titleRight = titleLeft - lp.leftMargin - mTitleMarginEnd; titleTop = titleBottom + lp.bottomMargin; } if (layoutSubtitle) { final LayoutParams lp = (LayoutParams) mSubtitleTextView.getLayoutParams(); subtitleRight -= lp.rightMargin + mTitleMarginStart; titleTop += lp.topMargin; final int subtitleLeft = subtitleRight - mSubtitleTextView.getMeasuredWidth(); final int subtitleBottom = titleTop + mSubtitleTextView.getMeasuredHeight(); mSubtitleTextView.layout(subtitleLeft, titleTop, subtitleRight, subtitleBottom); subtitleRight = subtitleRight - lp.leftMargin - mTitleMarginEnd; titleTop = subtitleBottom + lp.bottomMargin; } right = Math.max(titleRight, subtitleRight); } else { int titleLeft = left; int subtitleLeft = left; titleTop += mTitleMarginTop; if (layoutTitle) { final LayoutParams lp = (LayoutParams) mTitleTextView.getLayoutParams(); titleLeft += lp.leftMargin + mTitleMarginStart; titleTop += lp.topMargin; final int titleRight = titleLeft + mTitleTextView.getMeasuredWidth(); final int titleBottom = titleTop + mTitleTextView.getMeasuredHeight(); mTitleTextView.layout(titleLeft, titleTop, titleRight, titleBottom); titleLeft = titleRight + lp.rightMargin + mTitleMarginEnd; titleTop = titleBottom + lp.bottomMargin; } if (layoutSubtitle) { final LayoutParams lp = (LayoutParams) mSubtitleTextView.getLayoutParams(); subtitleLeft += lp.leftMargin + mTitleMarginStart; titleTop += lp.topMargin; final int subtitleRight = subtitleLeft + mSubtitleTextView.getMeasuredWidth(); final int subtitleBottom = titleTop + mSubtitleTextView.getMeasuredHeight(); mSubtitleTextView.layout(subtitleLeft, titleTop, subtitleRight, subtitleBottom); subtitleLeft = subtitleRight + lp.rightMargin + mTitleMarginEnd; titleTop = subtitleBottom + lp.bottomMargin; } left = Math.max(titleLeft, subtitleLeft); } } // Get all remaining children sorted for layout. This is all prepared // such that absolute layout direction can be used below. addCustomViewsWithGravity(mTempViews, Gravity.LEFT); final int leftViewsCount = mTempViews.size(); for (int i = 0; i < leftViewsCount; i++) { left = layoutChildLeft(mTempViews.get(i), left); } addCustomViewsWithGravity(mTempViews, Gravity.RIGHT); final int rightViewsCount = mTempViews.size(); for (int i = 0; i < rightViewsCount; i++) { right = layoutChildRight(mTempViews.get(i), right); } // Centered views try to center with respect to the whole bar, but views pinned // to the left or right can push the mass of centered views to one side or the other. addCustomViewsWithGravity(mTempViews, Gravity.CENTER); final int centerViewsWidth = getViewListMeasuredWidth(mTempViews); final int parentCenter = paddingLeft + (width - paddingLeft - paddingRight) / 2; final int halfCenterViewsWidth = centerViewsWidth / 2; int centerLeft = parentCenter - halfCenterViewsWidth; final int centerRight = centerLeft + centerViewsWidth; if (centerLeft < left) { centerLeft = left; } else if (centerRight > right) { centerLeft -= centerRight - right; } final int centerViewsCount = mTempViews.size(); for (int i = 0; i < centerViewsCount; i++) { centerLeft = layoutChildLeft(mTempViews.get(i), centerLeft); } mTempViews.clear(); } private int getViewListMeasuredWidth(Listtrue
if the event was handled, false
otherwise.
*/
public boolean onMenuItemClick(MenuItem item);
}
/**
* Layout information for child views of Toolbars.
*
* @attr ref android.R.styleable#Toolbar_LayoutParams_layout_gravity
*/
public static class LayoutParams extends MarginLayoutParams {
/**
* Gravity for the view associated with these LayoutParams.
*
* @see android.view.Gravity
*/
@ViewDebug.ExportedProperty(category = "layout", mapping = {
@ViewDebug.IntToString(from = -1, to = "NONE"),
@ViewDebug.IntToString(from = Gravity.NO_GRAVITY, to = "NONE"),
@ViewDebug.IntToString(from = Gravity.TOP, to = "TOP"),
@ViewDebug.IntToString(from = Gravity.BOTTOM, to = "BOTTOM"),
@ViewDebug.IntToString(from = Gravity.LEFT, to = "LEFT"),
@ViewDebug.IntToString(from = Gravity.RIGHT, to = "RIGHT"),
@ViewDebug.IntToString(from = Gravity.START, to = "START"),
@ViewDebug.IntToString(from = Gravity.END, to = "END"),
@ViewDebug.IntToString(from = Gravity.CENTER_VERTICAL, to = "CENTER_VERTICAL"),
@ViewDebug.IntToString(from = Gravity.FILL_VERTICAL, to = "FILL_VERTICAL"),
@ViewDebug.IntToString(from = Gravity.CENTER_HORIZONTAL, to = "CENTER_HORIZONTAL"),
@ViewDebug.IntToString(from = Gravity.FILL_HORIZONTAL, to = "FILL_HORIZONTAL"),
@ViewDebug.IntToString(from = Gravity.CENTER, to = "CENTER"),
@ViewDebug.IntToString(from = Gravity.FILL, to = "FILL")
})
public int gravity = Gravity.NO_GRAVITY;
static final int CUSTOM = 0;
static final int SYSTEM = 1;
int mViewType = CUSTOM;
public LayoutParams(@NonNull Context c, AttributeSet attrs) {
super(c, attrs);
TypedArray a = c.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.Toolbar_LayoutParams);
gravity = a.getInt(
com.android.internal.R.styleable.Toolbar_LayoutParams_layout_gravity,
Gravity.NO_GRAVITY);
a.recycle();
}
public LayoutParams(int width, int height) {
super(width, height);
this.gravity = Gravity.CENTER_VERTICAL | Gravity.START;
}
public LayoutParams(int width, int height, int gravity) {
super(width, height);
this.gravity = gravity;
}
public LayoutParams(int gravity) {
this(WRAP_CONTENT, MATCH_PARENT, gravity);
}
public LayoutParams(LayoutParams source) {
super(source);
this.gravity = source.gravity;
}
public LayoutParams(MarginLayoutParams source) {
super(source);
}
public LayoutParams(ViewGroup.LayoutParams source) {
super(source);
}
}
static class SavedState extends BaseSavedState {
public SavedState(Parcel source) {
super(source);
}
public SavedState(Parcelable superState) {
super(superState);
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
}
public static final Creator