FileDocCategorySizeDatePackage
FragmentBreadCrumbs.javaAPI DocAndroid 5.1 API14699Thu Mar 12 22:22:10 GMT 2015android.app

FragmentBreadCrumbs

public class FragmentBreadCrumbs extends android.view.ViewGroup implements FragmentManager.OnBackStackChangedListener
Helper class for showing "bread crumbs" representing the fragment stack in an activity. This is intended to be used with {@link ActionBar#setCustomView(View) ActionBar.setCustomView(View)} to place the bread crumbs in the action bar.

The default style for this view is {@link android.R.style#Widget_FragmentBreadCrumbs}.

deprecated
This widget is no longer supported.

Fields Summary
Activity
mActivity
android.view.LayoutInflater
mInflater
android.widget.LinearLayout
mContainer
int
mMaxVisible
BackStackRecord
mTopEntry
BackStackRecord
mParentEntry
private OnClickListener
mParentClickListener
Listener to inform when a parent entry is clicked
private OnBreadCrumbClickListener
mOnBreadCrumbClickListener
private int
mGravity
private int
mLayoutResId
private int
mTextColor
private static final int
DEFAULT_GRAVITY
private OnClickListener
mOnClickListener
Constructors Summary
public FragmentBreadCrumbs(android.content.Context context)


                 
       
                                                                                     
             
    
    
       
        this(context, null);
    
public FragmentBreadCrumbs(android.content.Context context, android.util.AttributeSet attrs)

        this(context, attrs, com.android.internal.R.attr.fragmentBreadCrumbsStyle);
    
public FragmentBreadCrumbs(android.content.Context context, android.util.AttributeSet attrs, int defStyleAttr)

        this(context, attrs, defStyleAttr, 0);
    
public FragmentBreadCrumbs(android.content.Context context, android.util.AttributeSet attrs, int defStyleAttr, int defStyleRes)

hide

        super(context, attrs, defStyleAttr, defStyleRes);

        final TypedArray a = context.obtainStyledAttributes(attrs,
                com.android.internal.R.styleable.FragmentBreadCrumbs, defStyleAttr, defStyleRes);

        mGravity = a.getInt(com.android.internal.R.styleable.FragmentBreadCrumbs_gravity,
                DEFAULT_GRAVITY);
        mLayoutResId = a.getResourceId(
                com.android.internal.R.styleable.FragmentBreadCrumbs_itemLayout,
                com.android.internal.R.layout.fragment_bread_crumb_item);
        mTextColor = a.getColor(
                com.android.internal.R.styleable.FragmentBreadCrumbs_itemColor,
                0);

        a.recycle();
    
Methods Summary
private BackStackRecordcreateBackStackEntry(java.lang.CharSequence title, java.lang.CharSequence shortTitle)

        if (title == null) return null;

        final BackStackRecord entry = new BackStackRecord(
                (FragmentManagerImpl) mActivity.getFragmentManager());
        entry.setBreadCrumbTitle(title);
        entry.setBreadCrumbShortTitle(shortTitle);
        return entry;
    
private android.app.FragmentManager.BackStackEntrygetPreEntry(int index)
Returns the pre-entry corresponding to the index. If there is a parent and a top entry set, parent has an index of zero and top entry has an index of 1. Returns null if the specified index doesn't exist or is null.

param
index should not be more than {@link #getPreEntryCount()} - 1

        // If there's a parent entry, then return that for zero'th item, else top entry.
        if (mParentEntry != null) {
            return index == 0 ? mParentEntry : mTopEntry;
        } else {
            return mTopEntry;
        }
    
private intgetPreEntryCount()
Returns the number of entries before the backstack, including the title of the current fragment and any custom parent title that was set.

        return (mTopEntry != null ? 1 : 0) + (mParentEntry != null ? 1 : 0);
    
public voidonBackStackChanged()

        updateCrumbs();
    
protected voidonLayout(boolean changed, int l, int t, int r, int b)

        // Eventually we should implement our own layout of the views, rather than relying on
        // a single linear layout.
        final int childCount = getChildCount();
        if (childCount == 0) {
            return;
        }

        final View child = getChildAt(0);

        final int childTop = mPaddingTop;
        final int childBottom = mPaddingTop + child.getMeasuredHeight() - mPaddingBottom;

        int childLeft;
        int childRight;

        final int layoutDirection = getLayoutDirection();
        final int horizontalGravity = mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK;
        switch (Gravity.getAbsoluteGravity(horizontalGravity, layoutDirection)) {
            case Gravity.RIGHT:
                childRight = mRight - mLeft - mPaddingRight;
                childLeft = childRight - child.getMeasuredWidth();
                break;

            case Gravity.CENTER_HORIZONTAL:
                childLeft = mPaddingLeft + (mRight - mLeft - child.getMeasuredWidth()) / 2;
                childRight = childLeft + child.getMeasuredWidth();
                break;

            case Gravity.LEFT:
            default:
                childLeft = mPaddingLeft;
                childRight = childLeft + child.getMeasuredWidth();
                break;
        }

        if (childLeft < mPaddingLeft) {
            childLeft = mPaddingLeft;
        }

        if (childRight > mRight - mLeft - mPaddingRight) {
            childRight = mRight - mLeft - mPaddingRight;
        }

        child.layout(childLeft, childTop, childRight, childBottom);
    
protected voidonMeasure(int widthMeasureSpec, int heightMeasureSpec)

        final int count = getChildCount();

        int maxHeight = 0;
        int maxWidth = 0;
        int measuredChildState = 0;

        // Find rightmost and bottom-most child
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                measureChild(child, widthMeasureSpec, heightMeasureSpec);
                maxWidth = Math.max(maxWidth, child.getMeasuredWidth());
                maxHeight = Math.max(maxHeight, child.getMeasuredHeight());
                measuredChildState = combineMeasuredStates(measuredChildState,
                        child.getMeasuredState());
            }
        }

        // Account for padding too
        maxWidth += mPaddingLeft + mPaddingRight;
        maxHeight += mPaddingTop + mPaddingBottom;

        // Check against our minimum height and width
        maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
        maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());

        setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, measuredChildState),
                resolveSizeAndState(maxHeight, heightMeasureSpec,
                        measuredChildState<<MEASURED_HEIGHT_STATE_SHIFT));
    
public voidsetActivity(Activity a)
Attach the bread crumbs to their activity. This must be called once when creating the bread crumbs.

        mActivity = a;
        mInflater = (LayoutInflater)a.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mContainer = (LinearLayout)mInflater.inflate(
                com.android.internal.R.layout.fragment_bread_crumbs,
                this, false);
        addView(mContainer);
        a.getFragmentManager().addOnBackStackChangedListener(this);
        updateCrumbs();
        setLayoutTransition(new LayoutTransition());
    
public voidsetMaxVisible(int visibleCrumbs)
The maximum number of breadcrumbs to show. Older fragment headers will be hidden from view.

param
visibleCrumbs the number of visible breadcrumbs. This should be greater than zero.

        if (visibleCrumbs < 1) {
            throw new IllegalArgumentException("visibleCrumbs must be greater than zero");
        }
        mMaxVisible = visibleCrumbs;
    
public voidsetOnBreadCrumbClickListener(android.app.FragmentBreadCrumbs$OnBreadCrumbClickListener listener)
Sets a listener for clicks on the bread crumbs. This will be called before the default click action is performed.

param
listener The new listener to set. Replaces any existing listener.

        mOnBreadCrumbClickListener = listener;
    
public voidsetParentTitle(java.lang.CharSequence title, java.lang.CharSequence shortTitle, OnClickListener listener)
Inserts an optional parent entry at the first position in the breadcrumbs. Selecting this entry will result in a call to the specified listener's {@link android.view.View.OnClickListener#onClick(View)} method.

param
title the title for the parent entry
param
shortTitle the short title for the parent entry
param
listener the {@link android.view.View.OnClickListener} to be called when clicked. A null will result in no action being taken when the parent entry is clicked.

        mParentEntry = createBackStackEntry(title, shortTitle);
        mParentClickListener = listener;
        updateCrumbs();
    
public voidsetTitle(java.lang.CharSequence title, java.lang.CharSequence shortTitle)
Set a custom title for the bread crumbs. This will be the first entry shown at the left, representing the root of the bread crumbs. If the title is null, it will not be shown.

        mTopEntry = createBackStackEntry(title, shortTitle);
        updateCrumbs();
    
voidupdateCrumbs()

        FragmentManager fm = mActivity.getFragmentManager();
        int numEntries = fm.getBackStackEntryCount();
        int numPreEntries = getPreEntryCount();
        int numViews = mContainer.getChildCount();
        for (int i = 0; i < numEntries + numPreEntries; i++) {
            BackStackEntry bse = i < numPreEntries
                    ? getPreEntry(i)
                    : fm.getBackStackEntryAt(i - numPreEntries);
            if (i < numViews) {
                View v = mContainer.getChildAt(i);
                Object tag = v.getTag();
                if (tag != bse) {
                    for (int j = i; j < numViews; j++) {
                        mContainer.removeViewAt(i);
                    }
                    numViews = i;
                }
            }
            if (i >= numViews) {
                final View item = mInflater.inflate(mLayoutResId, this, false);
                final TextView text = (TextView) item.findViewById(com.android.internal.R.id.title);
                text.setText(bse.getBreadCrumbTitle());
                text.setTag(bse);
                text.setTextColor(mTextColor);
                if (i == 0) {
                    item.findViewById(com.android.internal.R.id.left_icon).setVisibility(View.GONE);
                }
                mContainer.addView(item);
                text.setOnClickListener(mOnClickListener);
            }
        }
        int viewI = numEntries + numPreEntries;
        numViews = mContainer.getChildCount();
        while (numViews > viewI) {
            mContainer.removeViewAt(numViews - 1);
            numViews--;
        }
        // Adjust the visibility and availability of the bread crumbs and divider
        for (int i = 0; i < numViews; i++) {
            final View child = mContainer.getChildAt(i);
            // Disable the last one
            child.findViewById(com.android.internal.R.id.title).setEnabled(i < numViews - 1);
            if (mMaxVisible > 0) {
                // Make only the last mMaxVisible crumbs visible
                child.setVisibility(i < numViews - mMaxVisible ? View.GONE : View.VISIBLE);
                final View leftIcon = child.findViewById(com.android.internal.R.id.left_icon);
                // Remove the divider for all but the last mMaxVisible - 1
                leftIcon.setVisibility(i > numViews - mMaxVisible && i != 0 ? View.VISIBLE
                        : View.GONE);
            }
        }