FragmentManager.java revision b4bc78b16a05554c57508b488e21dd8eca4e13e6
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 17package android.app; 18 19import android.content.res.TypedArray; 20import android.os.Bundle; 21import android.os.Handler; 22import android.os.Parcel; 23import android.os.Parcelable; 24import android.util.SparseArray; 25import android.view.ViewGroup; 26import android.view.animation.Animation; 27import android.view.animation.AnimationUtils; 28 29import java.util.ArrayList; 30import java.util.HashMap; 31 32final class BackStackEntry implements FragmentTransaction, Runnable { 33 final FragmentManager mManager; 34 35 ArrayList<Fragment> mAdded; 36 ArrayList<Fragment> mRemoved; 37 int mTransition; 38 int mTransitionStyle; 39 boolean mAddToBackStack; 40 String mName; 41 boolean mCommitted; 42 43 public BackStackEntry(FragmentManager manager) { 44 mManager = manager; 45 } 46 47 public FragmentTransaction add(Fragment fragment, String tag) { 48 fragment.mTag = tag; 49 return add(fragment, 0); 50 } 51 52 public FragmentTransaction add(Fragment fragment, int containerViewId) { 53 if (fragment.mActivity != null) { 54 throw new IllegalStateException("Fragment already added: " + fragment); 55 } 56 if (mRemoved != null) { 57 mRemoved.remove(fragment); 58 } 59 if (mAdded == null) { 60 mAdded = new ArrayList<Fragment>(); 61 } 62 fragment.mContainerId = fragment.mFragmentId = containerViewId; 63 mAdded.add(fragment); 64 return this; 65 } 66 67 public FragmentTransaction replace(Fragment fragment, int containerViewId) { 68 if (containerViewId == 0) { 69 throw new IllegalArgumentException("Must use non-zero containerViewId"); 70 } 71 if (mManager.mFragments != null) { 72 for (int i=0; i<mManager.mFragments.size(); i++) { 73 Fragment old = mManager.mFragments.get(i); 74 if (old.mContainerId == containerViewId) { 75 remove(old); 76 } 77 } 78 } 79 return add(fragment, containerViewId); 80 } 81 82 public FragmentTransaction remove(Fragment fragment) { 83 if (fragment.mActivity == null) { 84 throw new IllegalStateException("Fragment not added: " + fragment); 85 } 86 if (mAdded != null) { 87 mAdded.remove(fragment); 88 } 89 if (mRemoved == null) { 90 mRemoved = new ArrayList<Fragment>(); 91 } 92 mRemoved.add(fragment); 93 return this; 94 } 95 96 public FragmentTransaction setTransition(int transition) { 97 mTransition = transition; 98 return this; 99 } 100 101 public FragmentTransaction setTransitionStyle(int styleRes) { 102 mTransitionStyle = styleRes; 103 return this; 104 } 105 106 public FragmentTransaction addToBackStack(String name) { 107 mAddToBackStack = true; 108 mName = name; 109 return this; 110 } 111 112 public void commit() { 113 if (mCommitted) throw new IllegalStateException("commit already called"); 114 mCommitted = true; 115 mManager.mActivity.mHandler.post(this); 116 } 117 118 public void run() { 119 if (mRemoved != null) { 120 for (int i=mRemoved.size()-1; i>=0; i--) { 121 mManager.removeFragment(mRemoved.get(i), mTransition, 122 mTransitionStyle); 123 } 124 } 125 if (mAdded != null) { 126 for (int i=mAdded.size()-1; i>=0; i--) { 127 Fragment f = mAdded.get(i); 128 mManager.addFragment(f, false); 129 if (mAddToBackStack) { 130 f.mBackStackNesting++; 131 } 132 } 133 } 134 mManager.moveToState(mManager.mCurState, mTransition, 135 mTransitionStyle, true); 136 if (mAddToBackStack) { 137 mManager.addBackStackState(this); 138 } 139 } 140 141 public void popFromBackStack() { 142 if (mAdded != null) { 143 for (int i=mAdded.size()-1; i>=0; i--) { 144 Fragment f = mAdded.get(i); 145 if (mAddToBackStack) { 146 f.mBackStackNesting--; 147 } 148 mManager.removeFragment(f, 149 FragmentManager.reverseTransit(mTransition), 150 mTransitionStyle); 151 } 152 } 153 if (mRemoved != null) { 154 for (int i=mRemoved.size()-1; i>=0; i--) { 155 mManager.addFragment(mRemoved.get(i), false); 156 } 157 } 158 } 159 160 public String getName() { 161 return mName; 162 } 163 164 public int getTransition() { 165 return mTransition; 166 } 167 168 public int getTransitionStyle() { 169 return mTransitionStyle; 170 } 171} 172 173final class BackStackState implements Parcelable { 174 final int[] mAdded; 175 final int[] mRemoved; 176 final int mTransition; 177 final int mTransitionStyle; 178 final String mName; 179 180 public BackStackState(FragmentManager fm, BackStackEntry bse) { 181 mAdded = buildFragmentStateList(fm, bse.mAdded); 182 mRemoved = buildFragmentStateList(fm, bse.mRemoved); 183 mTransition = bse.mTransition; 184 mTransitionStyle = bse.mTransitionStyle; 185 mName = bse.mName; 186 } 187 188 public BackStackState(Parcel in) { 189 mAdded = in.createIntArray(); 190 mRemoved = in.createIntArray(); 191 mTransition = in.readInt(); 192 mTransitionStyle = in.readInt(); 193 mName = in.readString(); 194 } 195 196 public BackStackEntry instantiate(FragmentManager fm) { 197 BackStackEntry bse = new BackStackEntry(fm); 198 bse.mAdded = buildFragmentList(fm, mAdded); 199 bse.mRemoved = buildFragmentList(fm, mRemoved); 200 bse.mTransition = mTransition; 201 bse.mTransitionStyle = mTransitionStyle; 202 bse.mName = mName; 203 return bse; 204 } 205 206 static int[] buildFragmentStateList(FragmentManager fm, ArrayList<Fragment> frags) { 207 if (frags == null) return null; 208 final int N = frags.size(); 209 int[] ids = new int[N]; 210 for (int i=0; i<N; i++) { 211 FragmentState fs = fm.saveFragment(frags.get(i)); 212 ids[i] = fs.mSavedStateId; 213 } 214 return ids; 215 } 216 217 static ArrayList<Fragment> buildFragmentList(FragmentManager fm, int[] states) { 218 if (states == null) return null; 219 final int N = states.length; 220 ArrayList<Fragment> frags = new ArrayList<Fragment>(N); 221 for (int i=0; i<N; i++) { 222 frags.add(fm.mRestoredFragments.get(states[i]).instantiate(fm.mActivity)); 223 } 224 return frags; 225 } 226 227 public int describeContents() { 228 return 0; 229 } 230 231 public void writeToParcel(Parcel dest, int flags) { 232 dest.writeIntArray(mAdded); 233 dest.writeIntArray(mRemoved); 234 dest.writeInt(mTransition); 235 dest.writeInt(mTransitionStyle); 236 dest.writeString(mName); 237 } 238 239 public static final Parcelable.Creator<BackStackState> CREATOR 240 = new Parcelable.Creator<BackStackState>() { 241 public BackStackState createFromParcel(Parcel in) { 242 return new BackStackState(in); 243 } 244 245 public BackStackState[] newArray(int size) { 246 return new BackStackState[size]; 247 } 248 }; 249} 250 251final class FragmentManagerState implements Parcelable { 252 FragmentState[] mFragments; 253 int[] mAdded; 254 BackStackState[] mBackStack; 255 256 public FragmentManagerState() { 257 } 258 259 public FragmentManagerState(Parcel in) { 260 mFragments = in.createTypedArray(FragmentState.CREATOR); 261 mAdded = in.createIntArray(); 262 mBackStack = in.createTypedArray(BackStackState.CREATOR); 263 } 264 265 public int describeContents() { 266 return 0; 267 } 268 269 public void writeToParcel(Parcel dest, int flags) { 270 dest.writeTypedArray(mFragments, flags); 271 dest.writeIntArray(mAdded); 272 dest.writeTypedArray(mBackStack, flags); 273 } 274 275 public static final Parcelable.Creator<FragmentManagerState> CREATOR 276 = new Parcelable.Creator<FragmentManagerState>() { 277 public FragmentManagerState createFromParcel(Parcel in) { 278 return new FragmentManagerState(in); 279 } 280 281 public FragmentManagerState[] newArray(int size) { 282 return new FragmentManagerState[size]; 283 } 284 }; 285} 286 287/** 288 * @hide 289 * Container for fragments associated with an activity. 290 */ 291public class FragmentManager { 292 ArrayList<Fragment> mFragments; 293 ArrayList<BackStackEntry> mBackStack; 294 295 int mCurState = Fragment.INITIALIZING; 296 Activity mActivity; 297 298 int mSaveStateSeq = 0; 299 300 // Temporary vars for state save and restore. 301 int mCurSaveId = 0; 302 HashMap<Fragment, FragmentState> mSavedFragments; 303 SparseArray<FragmentState> mRestoredFragments; 304 Bundle mStateBundle = null; 305 SparseArray<Parcelable> mStateArray = null; 306 307 Animation loadAnimation(Fragment fragment, int transit, boolean enter, 308 int transitionStyle) { 309 Animation animObj = fragment.onCreateAnimation(transitionStyle, enter); 310 if (animObj != null) { 311 return animObj; 312 } 313 314 if (transit == 0) { 315 return null; 316 } 317 318 int styleIndex = transitToStyleIndex(transit, enter); 319 if (styleIndex < 0) { 320 return null; 321 } 322 323 if (transitionStyle == 0 && mActivity.getWindow() != null) { 324 transitionStyle = mActivity.getWindow().getAttributes().windowAnimations; 325 } 326 if (transitionStyle == 0) { 327 return null; 328 } 329 330 TypedArray attrs = mActivity.obtainStyledAttributes(transitionStyle, 331 com.android.internal.R.styleable.WindowAnimation); 332 int anim = attrs.getResourceId(styleIndex, 0); 333 attrs.recycle(); 334 335 if (anim == 0) { 336 return null; 337 } 338 339 return AnimationUtils.loadAnimation(mActivity, anim); 340 } 341 342 void moveToState(Fragment f, int newState, int transit, int transitionStyle) { 343 if (f.mState < newState) { 344 switch (f.mState) { 345 case Fragment.INITIALIZING: 346 f.mActivity = mActivity; 347 f.mCalled = false; 348 f.onAttach(mActivity); 349 if (!f.mCalled) { 350 throw new SuperNotCalledException("Fragment " + f 351 + " did not call through to super.onAttach()"); 352 } 353 354 if (!f.mRetaining) { 355 f.mCalled = false; 356 f.onCreate(f.mSavedFragmentState); 357 if (!f.mCalled) { 358 throw new SuperNotCalledException("Fragment " + f 359 + " did not call through to super.onCreate()"); 360 } 361 } 362 f.mRetaining = false; 363 if (f.mFromLayout) { 364 // For fragments that are part of the content view 365 // layout, we need to instantiate the view immediately 366 // and the inflater will take care of adding it. 367 f.mView = f.onCreateView(mActivity.getLayoutInflater(), 368 null, f.mSavedFragmentState); 369 } 370 case Fragment.CONTENT: 371 if (newState > Fragment.CONTENT) { 372 if (!f.mFromLayout) { 373 ViewGroup container = null; 374 if (f.mContainerId != 0) { 375 container = (ViewGroup)mActivity.findViewById(f.mContainerId); 376 if (container == null) { 377 throw new IllegalArgumentException("New view found for id 0x" 378 + Integer.toHexString(f.mContainerId) 379 + " for fragment " + f); 380 } 381 } 382 f.mContainer = container; 383 f.mView = f.onCreateView(mActivity.getLayoutInflater(), 384 container, f.mSavedFragmentState); 385 if (f.mView != null) { 386 f.mView.setSaveFromParentEnabled(false); 387 if (container != null) { 388 Animation anim = loadAnimation(f, transit, true, 389 transitionStyle); 390 if (anim != null) { 391 f.mView.setAnimation(anim); 392 } 393 container.addView(f.mView); 394 f.restoreViewState(); 395 } 396 } 397 } 398 399 f.mCalled = false; 400 f.onReady(f.mSavedFragmentState); 401 if (!f.mCalled) { 402 throw new SuperNotCalledException("Fragment " + f 403 + " did not call through to super.onReady()"); 404 } 405 f.mSavedFragmentState = null; 406 } 407 case Fragment.CREATED: 408 if (newState > Fragment.CREATED) { 409 f.mCalled = false; 410 f.onStart(); 411 if (!f.mCalled) { 412 throw new SuperNotCalledException("Fragment " + f 413 + " did not call through to super.onStart()"); 414 } 415 } 416 case Fragment.STARTED: 417 if (newState > Fragment.STARTED) { 418 f.mCalled = false; 419 f.onResume(); 420 if (!f.mCalled) { 421 throw new SuperNotCalledException("Fragment " + f 422 + " did not call through to super.onResume()"); 423 } 424 } 425 } 426 } else if (f.mState > newState) { 427 switch (f.mState) { 428 case Fragment.RESUMED: 429 if (newState < Fragment.RESUMED) { 430 f.mCalled = false; 431 f.onPause(); 432 if (!f.mCalled) { 433 throw new SuperNotCalledException("Fragment " + f 434 + " did not call through to super.onPause()"); 435 } 436 } 437 case Fragment.STARTED: 438 if (newState < Fragment.STARTED) { 439 f.mCalled = false; 440 f.onStop(); 441 if (!f.mCalled) { 442 throw new SuperNotCalledException("Fragment " + f 443 + " did not call through to super.onStop()"); 444 } 445 } 446 case Fragment.CONTENT: 447 if (newState < Fragment.CONTENT) { 448 if (f.mView != null) { 449 // Need to save the current view state if not 450 // done already. 451 if (!mActivity.isFinishing()) { 452 saveFragmentViewState(f); 453 } 454 if (f.mContainer != null) { 455 if (mCurState > Fragment.INITIALIZING) { 456 Animation anim = loadAnimation(f, transit, false, 457 transitionStyle); 458 if (anim != null) { 459 f.mView.setAnimation(anim); 460 } 461 } 462 f.mContainer.removeView(f.mView); 463 } 464 } 465 f.mContainer = null; 466 f.mView = null; 467 } 468 case Fragment.CREATED: 469 if (newState < Fragment.CREATED) { 470 if (!f.mRetaining) { 471 f.mCalled = false; 472 f.onDestroy(); 473 if (!f.mCalled) { 474 throw new SuperNotCalledException("Fragment " + f 475 + " did not call through to super.onDestroy()"); 476 } 477 } 478 479 f.mCalled = false; 480 f.onDetach(); 481 if (!f.mCalled) { 482 throw new SuperNotCalledException("Fragment " + f 483 + " did not call through to super.onDetach()"); 484 } 485 f.mActivity = null; 486 } 487 } 488 } 489 490 f.mState = newState; 491 } 492 493 void moveToState(int newState, boolean always) { 494 moveToState(newState, 0, 0, always); 495 } 496 497 void moveToState(int newState, int transit, int transitStyle, boolean always) { 498 if (mActivity == null && newState != Fragment.INITIALIZING) { 499 throw new IllegalStateException("No activity"); 500 } 501 502 if (!always && mCurState == newState) { 503 return; 504 } 505 506 mCurState = newState; 507 if (mFragments != null) { 508 for (int i=0; i<mFragments.size(); i++) { 509 Fragment f = mFragments.get(i); 510 moveToState(f, newState, transit, transitStyle); 511 } 512 } 513 } 514 515 public void addFragment(Fragment fragment, boolean moveToStateNow) { 516 if (mFragments == null) { 517 mFragments = new ArrayList<Fragment>(); 518 } 519 mFragments.add(fragment); 520 if (moveToStateNow) { 521 moveToState(fragment, mCurState, 0, 0); 522 } 523 } 524 525 public void removeFragment(Fragment fragment, int transition, int transitionStyle) { 526 mFragments.remove(fragment); 527 moveToState(fragment, Fragment.INITIALIZING, transition, transitionStyle); 528 } 529 530 public Fragment findFragmentById(int id) { 531 if (mFragments != null) { 532 for (int i=mFragments.size()-1; i>=0; i--) { 533 Fragment f = mFragments.get(i); 534 if (f.mFragmentId == id) { 535 return f; 536 } 537 } 538 } 539 return null; 540 } 541 542 public Fragment findFragmentByTag(String tag) { 543 if (mFragments != null && tag != null) { 544 for (int i=mFragments.size()-1; i>=0; i--) { 545 Fragment f = mFragments.get(i); 546 if (tag.equals(f.mTag)) { 547 return f; 548 } 549 } 550 } 551 return null; 552 } 553 554 public void addBackStackState(BackStackEntry state) { 555 if (mBackStack == null) { 556 mBackStack = new ArrayList<BackStackEntry>(); 557 } 558 mBackStack.add(state); 559 } 560 561 public boolean popBackStackState(Handler handler, String name) { 562 if (mBackStack == null) { 563 return false; 564 } 565 if (name == null) { 566 int last = mBackStack.size()-1; 567 if (last < 0) { 568 return false; 569 } 570 final BackStackEntry bss = mBackStack.remove(last); 571 handler.post(new Runnable() { 572 public void run() { 573 bss.popFromBackStack(); 574 moveToState(mCurState, reverseTransit(bss.getTransition()), 575 bss.getTransitionStyle(), true); 576 } 577 }); 578 } else { 579 int index = mBackStack.size()-1; 580 while (index >= 0) { 581 BackStackEntry bss = mBackStack.get(index); 582 if (name.equals(bss.getName())) { 583 break; 584 } 585 } 586 if (index < 0 || index == mBackStack.size()-1) { 587 return false; 588 } 589 final ArrayList<BackStackEntry> states 590 = new ArrayList<BackStackEntry>(); 591 for (int i=mBackStack.size()-1; i>index; i--) { 592 states.add(mBackStack.remove(i)); 593 } 594 handler.post(new Runnable() { 595 public void run() { 596 for (int i=0; i<states.size(); i++) { 597 states.get(i).popFromBackStack(); 598 } 599 moveToState(mCurState, true); 600 } 601 }); 602 } 603 return true; 604 } 605 606 ArrayList<Fragment> retainNonConfig() { 607 ArrayList<Fragment> fragments = null; 608 if (mFragments != null) { 609 for (int i=0; i<mFragments.size(); i++) { 610 Fragment f = mFragments.get(i); 611 if (f.mBackStackNesting <= 0 && f.mRetainInstance && f.mTag != null) { 612 if (fragments == null) { 613 fragments = new ArrayList<Fragment>(); 614 } 615 fragments.add(f); 616 f.mRetaining = true; 617 } 618 } 619 } 620 return fragments; 621 } 622 623 void saveFragmentViewState(Fragment f) { 624 if (f.mSavedViewState != null) { 625 return; 626 } 627 if (mStateArray == null) { 628 mStateArray = new SparseArray<Parcelable>(); 629 } 630 f.mView.saveHierarchyState(mStateArray); 631 if (mStateArray.size() > 0) { 632 f.mSavedViewState = mStateArray; 633 mStateArray = null; 634 } 635 } 636 637 FragmentState saveFragment(Fragment f) { 638 if (mSavedFragments != null) { 639 FragmentState fs = mSavedFragments.get(f); 640 if (fs != null) { 641 return fs; 642 } 643 } else { 644 mSavedFragments = new HashMap<Fragment, FragmentState>(); 645 } 646 647 f.mSavedStateSeq = mSaveStateSeq; 648 f.mSavedStateId = ++mCurSaveId; 649 650 FragmentState fs = new FragmentState(f); 651 mSavedFragments.put(f, fs); 652 653 if (mStateBundle == null) { 654 mStateBundle = new Bundle(); 655 } 656 f.onSaveInstanceState(mStateBundle); 657 if (!mStateBundle.isEmpty()) { 658 fs.mSavedFragmentState = mStateBundle; 659 mStateBundle = null; 660 } 661 662 if (f.mView != null) { 663 saveFragmentViewState(f); 664 if (f.mSavedViewState != null) { 665 if (fs.mSavedFragmentState == null) { 666 fs.mSavedFragmentState = new Bundle(); 667 } 668 fs.mSavedFragmentState.putSparseParcelableArray( 669 FragmentState.VIEW_STATE_TAG, f.mSavedViewState); 670 } 671 } 672 673 return fs; 674 } 675 676 Parcelable saveAllState() { 677 mSavedFragments = null; 678 mSaveStateSeq++; 679 680 if (mFragments == null) { 681 return null; 682 } 683 684 int[] added = null; 685 BackStackState[] backStack = null; 686 687 // First collect all active fragments. 688 int N = mFragments.size(); 689 if (N > 0) { 690 added = new int[N]; 691 for (int i=0; i<N; i++) { 692 added[i] = saveFragment(mFragments.get(i)).mSavedStateId; 693 } 694 } 695 696 // Now save back stack. 697 if (mBackStack != null) { 698 N = mBackStack.size(); 699 if (N > 0) { 700 backStack = new BackStackState[N]; 701 for (int i=0; i<N; i++) { 702 backStack[i] = new BackStackState(this, mBackStack.get(i)); 703 } 704 } 705 } 706 707 if (mSavedFragments == null) { 708 return null; 709 } 710 N = mSavedFragments.size(); 711 if (N <= 0) { 712 return null; 713 } 714 715 FragmentManagerState fms = new FragmentManagerState(); 716 fms.mFragments = new FragmentState[N]; 717 int i = 0; 718 for (FragmentState fs : mSavedFragments.values()) { 719 fms.mFragments[i] = fs; 720 i++; 721 } 722 fms.mAdded = added; 723 fms.mBackStack = backStack; 724 return fms; 725 } 726 727 void restoreAllState(Parcelable state, ArrayList<Fragment> nonConfig) { 728 // If there is no saved state at all, then there can not be 729 // any nonConfig fragments either, so that is that. 730 if (state == null) return; 731 FragmentManagerState fms = (FragmentManagerState)state; 732 if (fms.mFragments == null) return; 733 734 // First build our lookup table of all known Fragment objects. 735 mRestoredFragments = new SparseArray<FragmentState>(); 736 for (int i=0; i<fms.mFragments.length; i++) { 737 FragmentState fs = fms.mFragments[i]; 738 mRestoredFragments.put(fs.mSavedStateId, fs); 739 } 740 741 // Stick any non-config instances we are retaining directly 742 // into the lookup table, so we don't try to instantiate them again. 743 if (nonConfig != null) { 744 for (int i=0; i<nonConfig.size(); i++) { 745 Fragment f = nonConfig.get(i); 746 FragmentState fs = mRestoredFragments.get(f.mSavedStateId); 747 fs.mInstance = f; 748 f.mSavedViewState = null; 749 if (fs.mSavedFragmentState != null) { 750 f.mSavedViewState = fs.mSavedFragmentState.getSparseParcelableArray( 751 FragmentState.VIEW_STATE_TAG); 752 } 753 addFragment(f, false); 754 } 755 } 756 757 // Now build our data structures from the saved state, instantiating 758 // the fragment objects as needed. 759 if (fms.mAdded != null) { 760 if (mFragments == null) { 761 mFragments = new ArrayList<Fragment>(fms.mAdded.length); 762 } 763 for (int i=0; i<fms.mAdded.length; i++) { 764 FragmentState fs = mRestoredFragments.get(fms.mAdded[i]); 765 Fragment f = fs.instantiate(mActivity); 766 // This will return null if this is a layout fragment, 767 // since the instance for such a fragment will be created 768 // later during layout inflation. 769 if (f != null) { 770 mFragments.add(f); 771 } 772 } 773 } 774 if (fms.mBackStack != null) { 775 mBackStack = new ArrayList<BackStackEntry>(fms.mBackStack.length); 776 for (int i=0; i<fms.mBackStack.length; i++) { 777 BackStackEntry bse = fms.mBackStack[i].instantiate(this); 778 mBackStack.add(bse); 779 } 780 } 781 } 782 783 public void attachActivity(Activity activity) { 784 if (mActivity != null) throw new IllegalStateException(); 785 mActivity = activity; 786 } 787 788 public void dispatchCreate() { 789 moveToState(Fragment.CREATED, false); 790 } 791 792 public void dispatchStart() { 793 moveToState(Fragment.STARTED, false); 794 } 795 796 public void dispatchResume() { 797 moveToState(Fragment.RESUMED, false); 798 } 799 800 public void dispatchPause() { 801 moveToState(Fragment.STARTED, false); 802 } 803 804 public void dispatchStop() { 805 moveToState(Fragment.CREATED, false); 806 } 807 808 public void dispatchDestroy() { 809 moveToState(Fragment.INITIALIZING, false); 810 mActivity = null; 811 } 812 813 public static int reverseTransit(int transit) { 814 int rev = 0; 815 switch (transit) { 816 case FragmentTransaction.TRANSIT_ENTER: 817 rev = FragmentTransaction.TRANSIT_EXIT; 818 break; 819 case FragmentTransaction.TRANSIT_EXIT: 820 rev = FragmentTransaction.TRANSIT_ENTER; 821 break; 822 case FragmentTransaction.TRANSIT_SHOW: 823 rev = FragmentTransaction.TRANSIT_HIDE; 824 break; 825 case FragmentTransaction.TRANSIT_HIDE: 826 rev = FragmentTransaction.TRANSIT_SHOW; 827 break; 828 case FragmentTransaction.TRANSIT_ACTIVITY_OPEN: 829 rev = FragmentTransaction.TRANSIT_ACTIVITY_CLOSE; 830 break; 831 case FragmentTransaction.TRANSIT_ACTIVITY_CLOSE: 832 rev = FragmentTransaction.TRANSIT_ACTIVITY_OPEN; 833 break; 834 case FragmentTransaction.TRANSIT_TASK_OPEN: 835 rev = FragmentTransaction.TRANSIT_TASK_CLOSE; 836 break; 837 case FragmentTransaction.TRANSIT_TASK_CLOSE: 838 rev = FragmentTransaction.TRANSIT_TASK_OPEN; 839 break; 840 case FragmentTransaction.TRANSIT_TASK_TO_FRONT: 841 rev = FragmentTransaction.TRANSIT_TASK_TO_BACK; 842 break; 843 case FragmentTransaction.TRANSIT_TASK_TO_BACK: 844 rev = FragmentTransaction.TRANSIT_TASK_TO_FRONT; 845 break; 846 case FragmentTransaction.TRANSIT_WALLPAPER_OPEN: 847 rev = FragmentTransaction.TRANSIT_WALLPAPER_CLOSE; 848 break; 849 case FragmentTransaction.TRANSIT_WALLPAPER_CLOSE: 850 rev = FragmentTransaction.TRANSIT_WALLPAPER_OPEN; 851 break; 852 case FragmentTransaction.TRANSIT_WALLPAPER_INTRA_OPEN: 853 rev = FragmentTransaction.TRANSIT_WALLPAPER_INTRA_CLOSE; 854 break; 855 case FragmentTransaction.TRANSIT_WALLPAPER_INTRA_CLOSE: 856 rev = FragmentTransaction.TRANSIT_WALLPAPER_INTRA_OPEN; 857 break; 858 } 859 return rev; 860 861 } 862 863 public static int transitToStyleIndex(int transit, boolean enter) { 864 int animAttr = -1; 865 switch (transit) { 866 case FragmentTransaction.TRANSIT_ENTER: 867 animAttr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation; 868 break; 869 case FragmentTransaction.TRANSIT_EXIT: 870 animAttr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation; 871 break; 872 case FragmentTransaction.TRANSIT_SHOW: 873 animAttr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation; 874 break; 875 case FragmentTransaction.TRANSIT_HIDE: 876 animAttr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation; 877 break; 878 case FragmentTransaction.TRANSIT_ACTIVITY_OPEN: 879 animAttr = enter 880 ? com.android.internal.R.styleable.WindowAnimation_activityOpenEnterAnimation 881 : com.android.internal.R.styleable.WindowAnimation_activityOpenExitAnimation; 882 break; 883 case FragmentTransaction.TRANSIT_ACTIVITY_CLOSE: 884 animAttr = enter 885 ? com.android.internal.R.styleable.WindowAnimation_activityCloseEnterAnimation 886 : com.android.internal.R.styleable.WindowAnimation_activityCloseExitAnimation; 887 break; 888 case FragmentTransaction.TRANSIT_TASK_OPEN: 889 animAttr = enter 890 ? com.android.internal.R.styleable.WindowAnimation_taskOpenEnterAnimation 891 : com.android.internal.R.styleable.WindowAnimation_taskOpenExitAnimation; 892 break; 893 case FragmentTransaction.TRANSIT_TASK_CLOSE: 894 animAttr = enter 895 ? com.android.internal.R.styleable.WindowAnimation_taskCloseEnterAnimation 896 : com.android.internal.R.styleable.WindowAnimation_taskCloseExitAnimation; 897 break; 898 case FragmentTransaction.TRANSIT_TASK_TO_FRONT: 899 animAttr = enter 900 ? com.android.internal.R.styleable.WindowAnimation_taskToFrontEnterAnimation 901 : com.android.internal.R.styleable.WindowAnimation_taskToFrontExitAnimation; 902 break; 903 case FragmentTransaction.TRANSIT_TASK_TO_BACK: 904 animAttr = enter 905 ? com.android.internal.R.styleable.WindowAnimation_taskToBackEnterAnimation 906 : com.android.internal.R.styleable.WindowAnimation_taskToBackExitAnimation; 907 break; 908 case FragmentTransaction.TRANSIT_WALLPAPER_OPEN: 909 animAttr = enter 910 ? com.android.internal.R.styleable.WindowAnimation_wallpaperOpenEnterAnimation 911 : com.android.internal.R.styleable.WindowAnimation_wallpaperOpenExitAnimation; 912 break; 913 case FragmentTransaction.TRANSIT_WALLPAPER_CLOSE: 914 animAttr = enter 915 ? com.android.internal.R.styleable.WindowAnimation_wallpaperCloseEnterAnimation 916 : com.android.internal.R.styleable.WindowAnimation_wallpaperCloseExitAnimation; 917 break; 918 case FragmentTransaction.TRANSIT_WALLPAPER_INTRA_OPEN: 919 animAttr = enter 920 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenEnterAnimation 921 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraOpenExitAnimation; 922 break; 923 case FragmentTransaction.TRANSIT_WALLPAPER_INTRA_CLOSE: 924 animAttr = enter 925 ? com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseEnterAnimation 926 : com.android.internal.R.styleable.WindowAnimation_wallpaperIntraCloseExitAnimation; 927 break; 928 } 929 return animAttr; 930 } 931} 932