Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2010 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | package android.app; |
| 18 | |
Dianne Hackborn | 8eb2e24 | 2010-11-01 12:31:24 -0700 | [diff] [blame] | 19 | import android.animation.LayoutTransition; |
Amith Yamasani | dcfb9f7 | 2010-09-21 14:22:09 -0700 | [diff] [blame] | 20 | import android.app.FragmentManager.BackStackEntry; |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 21 | import android.content.Context; |
Fabrice Di Meglio | 3cc10f4 | 2012-10-10 19:11:47 -0700 | [diff] [blame] | 22 | import android.content.res.TypedArray; |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 23 | import android.util.AttributeSet; |
Fabrice Di Meglio | 3cc10f4 | 2012-10-10 19:11:47 -0700 | [diff] [blame] | 24 | import android.view.Gravity; |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 25 | import android.view.LayoutInflater; |
| 26 | import android.view.View; |
| 27 | import android.view.ViewGroup; |
| 28 | import android.widget.LinearLayout; |
| 29 | import android.widget.TextView; |
| 30 | |
| 31 | /** |
| 32 | * Helper class for showing "bread crumbs" representing the fragment |
| 33 | * stack in an activity. This is intended to be used with |
Adam Powell | 1264c33 | 2011-01-20 12:08:13 -0800 | [diff] [blame] | 34 | * {@link ActionBar#setCustomView(View) |
| 35 | * ActionBar.setCustomView(View)} to place the bread crumbs in |
| 36 | * the action bar. |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 37 | * |
| 38 | * <p>The default style for this view is |
| 39 | * {@link android.R.style#Widget_FragmentBreadCrumbs}. |
| 40 | */ |
| 41 | public class FragmentBreadCrumbs extends ViewGroup |
| 42 | implements FragmentManager.OnBackStackChangedListener { |
| 43 | Activity mActivity; |
| 44 | LayoutInflater mInflater; |
| 45 | LinearLayout mContainer; |
Amith Yamasani | 3c9f519 | 2010-12-08 16:48:31 -0800 | [diff] [blame] | 46 | int mMaxVisible = -1; |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 47 | |
| 48 | // Hahah |
| 49 | BackStackRecord mTopEntry; |
Amith Yamasani | c9ecb73 | 2010-12-14 14:23:21 -0800 | [diff] [blame] | 50 | BackStackRecord mParentEntry; |
| 51 | |
| 52 | /** Listener to inform when a parent entry is clicked */ |
| 53 | private OnClickListener mParentClickListener; |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 54 | |
Dianne Hackborn | d94df45 | 2011-02-16 18:53:31 -0800 | [diff] [blame] | 55 | private OnBreadCrumbClickListener mOnBreadCrumbClickListener; |
Fabrice Di Meglio | 3cc10f4 | 2012-10-10 19:11:47 -0700 | [diff] [blame] | 56 | |
| 57 | private int mGravity; |
| 58 | |
| 59 | private static final int DEFAULT_GRAVITY = Gravity.START | Gravity.CENTER_VERTICAL; |
| 60 | |
Dianne Hackborn | d94df45 | 2011-02-16 18:53:31 -0800 | [diff] [blame] | 61 | /** |
| 62 | * Interface to intercept clicks on the bread crumbs. |
| 63 | */ |
| 64 | public interface OnBreadCrumbClickListener { |
| 65 | /** |
| 66 | * Called when a bread crumb is clicked. |
| 67 | * |
| 68 | * @param backStack The BackStackEntry whose bread crumb was clicked. |
| 69 | * May be null, if this bread crumb is for the root of the back stack. |
| 70 | * @param flags Additional information about the entry. Currently |
| 71 | * always 0. |
| 72 | * |
| 73 | * @return Return true to consume this click. Return to false to allow |
| 74 | * the default action (popping back stack to this entry) to occur. |
| 75 | */ |
| 76 | public boolean onBreadCrumbClick(BackStackEntry backStack, int flags); |
| 77 | } |
| 78 | |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 79 | public FragmentBreadCrumbs(Context context) { |
| 80 | this(context, null); |
| 81 | } |
| 82 | |
| 83 | public FragmentBreadCrumbs(Context context, AttributeSet attrs) { |
Alan Viverette | aaca5d8 | 2013-09-10 15:04:10 -0700 | [diff] [blame] | 84 | this(context, attrs, com.android.internal.R.attr.fragmentBreadCrumbsStyle); |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 85 | } |
| 86 | |
Alan Viverette | 617feb9 | 2013-09-09 18:09:13 -0700 | [diff] [blame] | 87 | public FragmentBreadCrumbs(Context context, AttributeSet attrs, int defStyleAttr) { |
| 88 | this(context, attrs, defStyleAttr, 0); |
| 89 | } |
Fabrice Di Meglio | 3cc10f4 | 2012-10-10 19:11:47 -0700 | [diff] [blame] | 90 | |
Alan Viverette | 617feb9 | 2013-09-09 18:09:13 -0700 | [diff] [blame] | 91 | public FragmentBreadCrumbs( |
| 92 | Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { |
| 93 | super(context, attrs, defStyleAttr, defStyleRes); |
| 94 | |
| 95 | final TypedArray a = context.obtainStyledAttributes(attrs, |
| 96 | com.android.internal.R.styleable.FragmentBreadCrumbs, defStyleAttr, defStyleRes); |
Fabrice Di Meglio | 3cc10f4 | 2012-10-10 19:11:47 -0700 | [diff] [blame] | 97 | |
| 98 | mGravity = a.getInt(com.android.internal.R.styleable.FragmentBreadCrumbs_gravity, |
| 99 | DEFAULT_GRAVITY); |
| 100 | |
| 101 | a.recycle(); |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 102 | } |
| 103 | |
| 104 | /** |
| 105 | * Attach the bread crumbs to their activity. This must be called once |
| 106 | * when creating the bread crumbs. |
| 107 | */ |
| 108 | public void setActivity(Activity a) { |
| 109 | mActivity = a; |
| 110 | mInflater = (LayoutInflater)a.getSystemService(Context.LAYOUT_INFLATER_SERVICE); |
| 111 | mContainer = (LinearLayout)mInflater.inflate( |
| 112 | com.android.internal.R.layout.fragment_bread_crumbs, |
| 113 | this, false); |
| 114 | addView(mContainer); |
| 115 | a.getFragmentManager().addOnBackStackChangedListener(this); |
| 116 | updateCrumbs(); |
Dianne Hackborn | 8eb2e24 | 2010-11-01 12:31:24 -0700 | [diff] [blame] | 117 | setLayoutTransition(new LayoutTransition()); |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 118 | } |
| 119 | |
| 120 | /** |
Amith Yamasani | c9ecb73 | 2010-12-14 14:23:21 -0800 | [diff] [blame] | 121 | * The maximum number of breadcrumbs to show. Older fragment headers will be hidden from view. |
| 122 | * @param visibleCrumbs the number of visible breadcrumbs. This should be greater than zero. |
Amith Yamasani | 3c9f519 | 2010-12-08 16:48:31 -0800 | [diff] [blame] | 123 | */ |
| 124 | public void setMaxVisible(int visibleCrumbs) { |
Amith Yamasani | c9ecb73 | 2010-12-14 14:23:21 -0800 | [diff] [blame] | 125 | if (visibleCrumbs < 1) { |
| 126 | throw new IllegalArgumentException("visibleCrumbs must be greater than zero"); |
| 127 | } |
Amith Yamasani | 3c9f519 | 2010-12-08 16:48:31 -0800 | [diff] [blame] | 128 | mMaxVisible = visibleCrumbs; |
| 129 | } |
| 130 | |
| 131 | /** |
Amith Yamasani | c9ecb73 | 2010-12-14 14:23:21 -0800 | [diff] [blame] | 132 | * Inserts an optional parent entry at the first position in the breadcrumbs. Selecting this |
| 133 | * entry will result in a call to the specified listener's |
| 134 | * {@link android.view.View.OnClickListener#onClick(View)} |
| 135 | * method. |
| 136 | * |
| 137 | * @param title the title for the parent entry |
| 138 | * @param shortTitle the short title for the parent entry |
| 139 | * @param listener the {@link android.view.View.OnClickListener} to be called when clicked. |
| 140 | * A null will result in no action being taken when the parent entry is clicked. |
| 141 | */ |
| 142 | public void setParentTitle(CharSequence title, CharSequence shortTitle, |
| 143 | OnClickListener listener) { |
| 144 | mParentEntry = createBackStackEntry(title, shortTitle); |
| 145 | mParentClickListener = listener; |
| 146 | updateCrumbs(); |
| 147 | } |
| 148 | |
Dianne Hackborn | d94df45 | 2011-02-16 18:53:31 -0800 | [diff] [blame] | 149 | /** |
| 150 | * Sets a listener for clicks on the bread crumbs. This will be called before |
| 151 | * the default click action is performed. |
| 152 | * |
| 153 | * @param listener The new listener to set. Replaces any existing listener. |
| 154 | */ |
| 155 | public void setOnBreadCrumbClickListener(OnBreadCrumbClickListener listener) { |
| 156 | mOnBreadCrumbClickListener = listener; |
| 157 | } |
| 158 | |
Amith Yamasani | c9ecb73 | 2010-12-14 14:23:21 -0800 | [diff] [blame] | 159 | private BackStackRecord createBackStackEntry(CharSequence title, CharSequence shortTitle) { |
| 160 | if (title == null) return null; |
| 161 | |
| 162 | final BackStackRecord entry = new BackStackRecord( |
| 163 | (FragmentManagerImpl) mActivity.getFragmentManager()); |
| 164 | entry.setBreadCrumbTitle(title); |
| 165 | entry.setBreadCrumbShortTitle(shortTitle); |
| 166 | return entry; |
| 167 | } |
| 168 | |
| 169 | /** |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 170 | * Set a custom title for the bread crumbs. This will be the first entry |
| 171 | * shown at the left, representing the root of the bread crumbs. If the |
| 172 | * title is null, it will not be shown. |
| 173 | */ |
| 174 | public void setTitle(CharSequence title, CharSequence shortTitle) { |
Amith Yamasani | c9ecb73 | 2010-12-14 14:23:21 -0800 | [diff] [blame] | 175 | mTopEntry = createBackStackEntry(title, shortTitle); |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 176 | updateCrumbs(); |
| 177 | } |
| 178 | |
| 179 | @Override |
| 180 | protected void onLayout(boolean changed, int l, int t, int r, int b) { |
Fabrice Di Meglio | 3cc10f4 | 2012-10-10 19:11:47 -0700 | [diff] [blame] | 181 | // Eventually we should implement our own layout of the views, rather than relying on |
| 182 | // a single linear layout. |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 183 | final int childCount = getChildCount(); |
Fabrice Di Meglio | 3cc10f4 | 2012-10-10 19:11:47 -0700 | [diff] [blame] | 184 | if (childCount == 0) { |
| 185 | return; |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 186 | } |
Fabrice Di Meglio | 3cc10f4 | 2012-10-10 19:11:47 -0700 | [diff] [blame] | 187 | |
| 188 | final View child = getChildAt(0); |
| 189 | |
| 190 | final int childTop = mPaddingTop; |
| 191 | final int childBottom = mPaddingTop + child.getMeasuredHeight() - mPaddingBottom; |
| 192 | |
| 193 | int childLeft; |
| 194 | int childRight; |
| 195 | |
| 196 | final int layoutDirection = getLayoutDirection(); |
| 197 | final int horizontalGravity = mGravity & Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK; |
| 198 | switch (Gravity.getAbsoluteGravity(horizontalGravity, layoutDirection)) { |
| 199 | case Gravity.RIGHT: |
| 200 | childRight = mRight - mLeft - mPaddingRight; |
| 201 | childLeft = childRight - child.getMeasuredWidth(); |
| 202 | break; |
| 203 | |
| 204 | case Gravity.CENTER_HORIZONTAL: |
| 205 | childLeft = mPaddingLeft + (mRight - mLeft - child.getMeasuredWidth()) / 2; |
| 206 | childRight = childLeft + child.getMeasuredWidth(); |
| 207 | break; |
| 208 | |
| 209 | case Gravity.LEFT: |
| 210 | default: |
| 211 | childLeft = mPaddingLeft; |
| 212 | childRight = childLeft + child.getMeasuredWidth(); |
| 213 | break; |
| 214 | } |
| 215 | |
| 216 | if (childLeft < mPaddingLeft) { |
| 217 | childLeft = mPaddingLeft; |
| 218 | } |
| 219 | |
| 220 | if (childRight > mRight - mLeft - mPaddingRight) { |
| 221 | childRight = mRight - mLeft - mPaddingRight; |
| 222 | } |
| 223 | |
| 224 | child.layout(childLeft, childTop, childRight, childBottom); |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 225 | } |
| 226 | |
| 227 | @Override |
| 228 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { |
| 229 | final int count = getChildCount(); |
| 230 | |
| 231 | int maxHeight = 0; |
| 232 | int maxWidth = 0; |
Dianne Hackborn | 189ee18 | 2010-12-02 21:48:53 -0800 | [diff] [blame] | 233 | int measuredChildState = 0; |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 234 | |
| 235 | // Find rightmost and bottom-most child |
| 236 | for (int i = 0; i < count; i++) { |
| 237 | final View child = getChildAt(i); |
| 238 | if (child.getVisibility() != GONE) { |
| 239 | measureChild(child, widthMeasureSpec, heightMeasureSpec); |
| 240 | maxWidth = Math.max(maxWidth, child.getMeasuredWidth()); |
| 241 | maxHeight = Math.max(maxHeight, child.getMeasuredHeight()); |
Dianne Hackborn | 189ee18 | 2010-12-02 21:48:53 -0800 | [diff] [blame] | 242 | measuredChildState = combineMeasuredStates(measuredChildState, |
| 243 | child.getMeasuredState()); |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 244 | } |
| 245 | } |
| 246 | |
| 247 | // Account for padding too |
| 248 | maxWidth += mPaddingLeft + mPaddingRight; |
| 249 | maxHeight += mPaddingTop + mPaddingBottom; |
| 250 | |
| 251 | // Check against our minimum height and width |
| 252 | maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight()); |
| 253 | maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth()); |
| 254 | |
Dianne Hackborn | 189ee18 | 2010-12-02 21:48:53 -0800 | [diff] [blame] | 255 | setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, measuredChildState), |
| 256 | resolveSizeAndState(maxHeight, heightMeasureSpec, |
| 257 | measuredChildState<<MEASURED_HEIGHT_STATE_SHIFT)); |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 258 | } |
| 259 | |
| 260 | @Override |
| 261 | public void onBackStackChanged() { |
| 262 | updateCrumbs(); |
| 263 | } |
| 264 | |
Amith Yamasani | c9ecb73 | 2010-12-14 14:23:21 -0800 | [diff] [blame] | 265 | /** |
| 266 | * Returns the number of entries before the backstack, including the title of the current |
| 267 | * fragment and any custom parent title that was set. |
| 268 | */ |
| 269 | private int getPreEntryCount() { |
| 270 | return (mTopEntry != null ? 1 : 0) + (mParentEntry != null ? 1 : 0); |
| 271 | } |
| 272 | |
| 273 | /** |
| 274 | * Returns the pre-entry corresponding to the index. If there is a parent and a top entry |
| 275 | * set, parent has an index of zero and top entry has an index of 1. Returns null if the |
| 276 | * specified index doesn't exist or is null. |
| 277 | * @param index should not be more than {@link #getPreEntryCount()} - 1 |
| 278 | */ |
| 279 | private BackStackEntry getPreEntry(int index) { |
| 280 | // If there's a parent entry, then return that for zero'th item, else top entry. |
| 281 | if (mParentEntry != null) { |
| 282 | return index == 0 ? mParentEntry : mTopEntry; |
| 283 | } else { |
| 284 | return mTopEntry; |
| 285 | } |
| 286 | } |
| 287 | |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 288 | void updateCrumbs() { |
| 289 | FragmentManager fm = mActivity.getFragmentManager(); |
Dianne Hackborn | 327fbd2 | 2011-01-17 14:38:50 -0800 | [diff] [blame] | 290 | int numEntries = fm.getBackStackEntryCount(); |
Amith Yamasani | c9ecb73 | 2010-12-14 14:23:21 -0800 | [diff] [blame] | 291 | int numPreEntries = getPreEntryCount(); |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 292 | int numViews = mContainer.getChildCount(); |
Amith Yamasani | c9ecb73 | 2010-12-14 14:23:21 -0800 | [diff] [blame] | 293 | for (int i = 0; i < numEntries + numPreEntries; i++) { |
| 294 | BackStackEntry bse = i < numPreEntries |
| 295 | ? getPreEntry(i) |
Dianne Hackborn | 327fbd2 | 2011-01-17 14:38:50 -0800 | [diff] [blame] | 296 | : fm.getBackStackEntryAt(i - numPreEntries); |
Amith Yamasani | c9ecb73 | 2010-12-14 14:23:21 -0800 | [diff] [blame] | 297 | if (i < numViews) { |
| 298 | View v = mContainer.getChildAt(i); |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 299 | Object tag = v.getTag(); |
| 300 | if (tag != bse) { |
Amith Yamasani | c9ecb73 | 2010-12-14 14:23:21 -0800 | [diff] [blame] | 301 | for (int j = i; j < numViews; j++) { |
| 302 | mContainer.removeViewAt(i); |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 303 | } |
Amith Yamasani | c9ecb73 | 2010-12-14 14:23:21 -0800 | [diff] [blame] | 304 | numViews = i; |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 305 | } |
| 306 | } |
Amith Yamasani | c9ecb73 | 2010-12-14 14:23:21 -0800 | [diff] [blame] | 307 | if (i >= numViews) { |
Amith Yamasani | 3c9f519 | 2010-12-08 16:48:31 -0800 | [diff] [blame] | 308 | final View item = mInflater.inflate( |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 309 | com.android.internal.R.layout.fragment_bread_crumb_item, |
| 310 | this, false); |
Amith Yamasani | 3c9f519 | 2010-12-08 16:48:31 -0800 | [diff] [blame] | 311 | final TextView text = (TextView) item.findViewById(com.android.internal.R.id.title); |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 312 | text.setText(bse.getBreadCrumbTitle()); |
Amith Yamasani | 3c9f519 | 2010-12-08 16:48:31 -0800 | [diff] [blame] | 313 | text.setTag(bse); |
Amith Yamasani | c9ecb73 | 2010-12-14 14:23:21 -0800 | [diff] [blame] | 314 | if (i == 0) { |
Amith Yamasani | 3c9f519 | 2010-12-08 16:48:31 -0800 | [diff] [blame] | 315 | item.findViewById(com.android.internal.R.id.left_icon).setVisibility(View.GONE); |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 316 | } |
| 317 | mContainer.addView(item); |
Amith Yamasani | 3c9f519 | 2010-12-08 16:48:31 -0800 | [diff] [blame] | 318 | text.setOnClickListener(mOnClickListener); |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 319 | } |
| 320 | } |
Amith Yamasani | c9ecb73 | 2010-12-14 14:23:21 -0800 | [diff] [blame] | 321 | int viewI = numEntries + numPreEntries; |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 322 | numViews = mContainer.getChildCount(); |
| 323 | while (numViews > viewI) { |
Amith Yamasani | c9ecb73 | 2010-12-14 14:23:21 -0800 | [diff] [blame] | 324 | mContainer.removeViewAt(numViews - 1); |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 325 | numViews--; |
| 326 | } |
Amith Yamasani | 3c9f519 | 2010-12-08 16:48:31 -0800 | [diff] [blame] | 327 | // Adjust the visibility and availability of the bread crumbs and divider |
| 328 | for (int i = 0; i < numViews; i++) { |
| 329 | final View child = mContainer.getChildAt(i); |
| 330 | // Disable the last one |
| 331 | child.findViewById(com.android.internal.R.id.title).setEnabled(i < numViews - 1); |
| 332 | if (mMaxVisible > 0) { |
| 333 | // Make only the last mMaxVisible crumbs visible |
| 334 | child.setVisibility(i < numViews - mMaxVisible ? View.GONE : View.VISIBLE); |
| 335 | final View leftIcon = child.findViewById(com.android.internal.R.id.left_icon); |
| 336 | // Remove the divider for all but the last mMaxVisible - 1 |
| 337 | leftIcon.setVisibility(i > numViews - mMaxVisible && i != 0 ? View.VISIBLE |
| 338 | : View.GONE); |
| 339 | } |
| 340 | } |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 341 | } |
Amith Yamasani | dcfb9f7 | 2010-09-21 14:22:09 -0700 | [diff] [blame] | 342 | |
| 343 | private OnClickListener mOnClickListener = new OnClickListener() { |
| 344 | public void onClick(View v) { |
| 345 | if (v.getTag() instanceof BackStackEntry) { |
| 346 | BackStackEntry bse = (BackStackEntry) v.getTag(); |
Amith Yamasani | c9ecb73 | 2010-12-14 14:23:21 -0800 | [diff] [blame] | 347 | if (bse == mParentEntry) { |
| 348 | if (mParentClickListener != null) { |
| 349 | mParentClickListener.onClick(v); |
| 350 | } |
| 351 | } else { |
Dianne Hackborn | d94df45 | 2011-02-16 18:53:31 -0800 | [diff] [blame] | 352 | if (mOnBreadCrumbClickListener != null) { |
| 353 | if (mOnBreadCrumbClickListener.onBreadCrumbClick( |
| 354 | bse == mTopEntry ? null : bse, 0)) { |
| 355 | return; |
| 356 | } |
| 357 | } |
| 358 | if (bse == mTopEntry) { |
| 359 | // Pop everything off the back stack. |
| 360 | mActivity.getFragmentManager().popBackStack(); |
| 361 | } else { |
| 362 | mActivity.getFragmentManager().popBackStack(bse.getId(), 0); |
| 363 | } |
Amith Yamasani | c9ecb73 | 2010-12-14 14:23:21 -0800 | [diff] [blame] | 364 | } |
Amith Yamasani | dcfb9f7 | 2010-09-21 14:22:09 -0700 | [diff] [blame] | 365 | } |
| 366 | } |
| 367 | }; |
Dianne Hackborn | c6669ca | 2010-09-16 01:33:24 -0700 | [diff] [blame] | 368 | } |