diff --git a/packages/DocumentsUI/res/animator/dir_enter.xml b/packages/DocumentsUI/res/animator/dir_enter.xml index 7daf1c04bce8d..43c50bd6d4d9c 100644 --- a/packages/DocumentsUI/res/animator/dir_enter.xml +++ b/packages/DocumentsUI/res/animator/dir_enter.xml @@ -24,6 +24,7 @@ android:duration="@android:integer/config_mediumAnimTime" android:interpolator="@android:interpolator/decelerate_quad" /> + + - - + diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java index c9d18b3791e68..1a8ce18ce03d1 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java @@ -18,10 +18,6 @@ package com.android.documentsui; import static com.android.documentsui.Shared.DEBUG; import static com.android.documentsui.State.MODE_GRID; -import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_ENTER; -import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_LEAVE; -import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_NONE; -import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_SIDE; import android.app.Activity; import android.app.Fragment; @@ -48,6 +44,7 @@ import android.widget.Spinner; import com.android.documentsui.SearchViewManager.SearchManagerListener; import com.android.documentsui.State.ViewMode; +import com.android.documentsui.dirlist.AnimationView; import com.android.documentsui.dirlist.DirectoryFragment; import com.android.documentsui.dirlist.Model; import com.android.documentsui.model.DocumentInfo; @@ -225,7 +222,7 @@ public abstract class BaseActivity extends Activity // Otherwise we delegate loading data from disk to a task // to ensure a responsive ui. if (mRoots.isRecentsRoot(root)) { - refreshCurrentRootAndDirectory(ANIM_NONE); + refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE); } else { new PickRootTask(this, root).executeOnExecutor(getExecutorForCurrentDirectory()); } @@ -327,7 +324,7 @@ public abstract class BaseActivity extends Activity // previous directory. Especially after opening a root document, pressing // back, wouldn't go to the previous root, but close the activity. final int anim = (mState.hasLocationChanged() && mState.stack.size() > 1) - ? ANIM_ENTER : ANIM_NONE; + ? AnimationView.ANIM_ENTER : AnimationView.ANIM_NONE; refreshCurrentRootAndDirectory(anim); } @@ -543,7 +540,7 @@ public abstract class BaseActivity extends Activity // Update the restored stack to ensure we have freshest data stack.updateDocuments(getContentResolver()); mState.setStack(stack); - refreshCurrentRootAndDirectory(ANIM_SIDE); + refreshCurrentRootAndDirectory(AnimationView.ANIM_SIDE); } catch (FileNotFoundException e) { Log.w(mTag, "Failed to restore stack: " + e); @@ -644,7 +641,7 @@ public abstract class BaseActivity extends Activity private boolean popDir() { if (mState.stack.size() > 1) { mState.stack.pop(); - refreshCurrentRootAndDirectory(ANIM_LEAVE); + refreshCurrentRootAndDirectory(AnimationView.ANIM_LEAVE); return true; } return false; diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryView.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryView.java deleted file mode 100644 index a26fb478b64e8..0000000000000 --- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryView.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2013 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 com.android.documentsui; - -import android.content.Context; -import android.util.AttributeSet; -import android.widget.LinearLayout; - -public class DirectoryView extends LinearLayout { - private float mPosition = 0f; - - private int mWidth; - - public DirectoryView(Context context) { - super(context); - } - - public DirectoryView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - mWidth = w; - setPosition(mPosition); - } - - public float getPosition() { - return mPosition; - } - - public void setPosition(float position) { - mPosition = position; - setY((mWidth > 0) ? (mPosition * mWidth) : 0); - - if (mPosition != 0) { - setTranslationZ(getResources().getDimensionPixelSize(R.dimen.dir_elevation)); - } else { - setTranslationZ(0); - } - } -} diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java index f8b32a035539b..ba593dc370bc4 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java @@ -22,7 +22,6 @@ import static com.android.documentsui.State.ACTION_GET_CONTENT; import static com.android.documentsui.State.ACTION_OPEN; import static com.android.documentsui.State.ACTION_OPEN_TREE; import static com.android.documentsui.State.ACTION_PICK_COPY_DESTINATION; -import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_NONE; import android.app.Activity; import android.app.Fragment; @@ -46,6 +45,7 @@ import android.view.MenuItem; import com.android.documentsui.RecentsProvider.RecentColumns; import com.android.documentsui.RecentsProvider.ResumeColumns; +import com.android.documentsui.dirlist.AnimationView; import com.android.documentsui.dirlist.DirectoryFragment; import com.android.documentsui.dirlist.Model; import com.android.documentsui.model.DocumentInfo; @@ -492,7 +492,7 @@ public class DocumentsActivity extends BaseActivity { protected void finish(Void result) { mState.restored = true; mState.external = mExternal; - mOwner.refreshCurrentRootAndDirectory(ANIM_NONE); + mOwner.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE); } } diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java index 573e4f3f5e742..0af8aa26bb530 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java @@ -18,7 +18,6 @@ package com.android.documentsui; import static com.android.documentsui.OperationDialogFragment.DIALOG_TYPE_UNKNOWN; import static com.android.documentsui.Shared.DEBUG; -import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_NONE; import android.app.Activity; import android.app.FragmentManager; @@ -39,6 +38,7 @@ import android.view.MenuItem; import com.android.documentsui.OperationDialogFragment.DialogType; import com.android.documentsui.RecentsProvider.ResumeColumns; +import com.android.documentsui.dirlist.AnimationView; import com.android.documentsui.dirlist.DirectoryFragment; import com.android.documentsui.dirlist.Model; import com.android.documentsui.model.DocumentInfo; @@ -97,7 +97,7 @@ public class FilesActivity extends BaseActivity { if (DEBUG) Log.d(TAG, "Launching with non-empty stack."); assert(uri == null || uri.getAuthority() == null || LauncherActivity.isLaunchUri(uri)); - refreshCurrentRootAndDirectory(ANIM_NONE); + refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE); } else if (intent.getAction() == Intent.ACTION_VIEW) { assert(uri != null); new OpenUriForViewTask(this).executeOnExecutor( @@ -470,7 +470,7 @@ public class FilesActivity extends BaseActivity { @Override protected void finish(Void result) { - mOwner.refreshCurrentRootAndDirectory(ANIM_NONE); + mOwner.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE); } } } diff --git a/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java b/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java index c5202042de69b..30c1020d0dbd5 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java +++ b/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java @@ -19,7 +19,6 @@ package com.android.documentsui; import static android.view.View.GONE; import static android.view.View.VISIBLE; import static com.android.documentsui.Shared.DEBUG; -import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_LEAVE; import android.annotation.Nullable; import android.graphics.drawable.Drawable; @@ -30,10 +29,10 @@ import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.BaseAdapter; -import android.widget.ImageView; import android.widget.Spinner; import android.widget.TextView; +import com.android.documentsui.dirlist.AnimationView; import com.android.documentsui.model.DocumentInfo; import com.android.documentsui.model.RootInfo; @@ -105,7 +104,7 @@ class NavigationView { while (mState.stack.size() > position + 1) { mState.popDocument(); } - mEnv.refreshCurrentRootAndDirectory(ANIM_LEAVE); + mEnv.refreshCurrentRootAndDirectory(AnimationView.ANIM_LEAVE); } void update() { diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/AnimationView.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/AnimationView.java new file mode 100644 index 0000000000000..4f076f1d9f858 --- /dev/null +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/AnimationView.java @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2013 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 com.android.documentsui.dirlist; + +import android.annotation.IntDef; +import android.app.FragmentTransaction; +import android.content.Context; +import android.os.Bundle; +import android.util.AttributeSet; +import android.widget.LinearLayout; + +import com.android.documentsui.R; +import com.android.documentsui.Shared; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * This class exists solely to support animated transition of our directory fragment. + * The structure of this class is tightly coupled with the static animations defined in + * res/animator, specifically the "position" property referenced by + * res/animator/dir_{enter,leave}.xml. + */ +public class AnimationView extends LinearLayout { + + @IntDef(flag = true, value = { + ANIM_NONE, + ANIM_SIDE, + ANIM_LEAVE, + ANIM_ENTER + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AnimationType {} + public static final int ANIM_NONE = 1; + public static final int ANIM_SIDE = 2; + public static final int ANIM_LEAVE = 3; + public static final int ANIM_ENTER = 4; + + private float mPosition = 0f; + + // The distance the animation will cover...currently matches the height of the + // content area. + private int mSpan; + + public AnimationView(Context context) { + super(context); + } + + public AnimationView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + mSpan = h; + setPosition(mPosition); + } + + public float getPosition() { + return mPosition; + } + + public void setPosition(float position) { + mPosition = position; + setY((mSpan > 0) ? (mPosition * mSpan) : 0); + + if (mPosition != 0) { + setTranslationZ(getResources().getDimensionPixelSize(R.dimen.dir_elevation)); + } else { + setTranslationZ(0); + } + } + + /** + * Configures custom animations on the transaction according to the specified + * @AnimationType. + */ + static void setupAnimations( + FragmentTransaction ft, @AnimationType int anim, Bundle args) { + switch (anim) { + case AnimationView.ANIM_SIDE: + args.putBoolean(Shared.EXTRA_IGNORE_STATE, true); + break; + case AnimationView.ANIM_ENTER: + // TODO: Document which behavior is being tailored + // by passing this bit. Remove if possible. + args.putBoolean(Shared.EXTRA_IGNORE_STATE, true); + ft.setCustomAnimations(R.animator.dir_enter, R.animator.fade_out); + break; + case AnimationView.ANIM_LEAVE: + ft.setCustomAnimations(R.animator.fade_in, R.animator.dir_leave); + break; + } + } +} diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java index 95aa067b806bd..bfc8d71c3fdf3 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java @@ -84,7 +84,6 @@ import com.android.documentsui.Events; import com.android.documentsui.Events.MotionInputEvent; import com.android.documentsui.Menus; import com.android.documentsui.MessageBar; -import com.android.documentsui.MimePredicate; import com.android.documentsui.R; import com.android.documentsui.RecentsLoader; import com.android.documentsui.RootsCache; @@ -124,19 +123,6 @@ public class DirectoryFragment extends Fragment public static final int TYPE_NORMAL = 1; public static final int TYPE_RECENT_OPEN = 2; - @IntDef(flag = true, value = { - ANIM_NONE, - ANIM_SIDE, - ANIM_LEAVE, - ANIM_ENTER - }) - @Retention(RetentionPolicy.SOURCE) - public @interface AnimationType {} - public static final int ANIM_NONE = 1; - public static final int ANIM_SIDE = 2; - public static final int ANIM_LEAVE = 3; - public static final int ANIM_ENTER = 4; - @IntDef(flag = true, value = { REQUEST_COPY_DESTINATION }) @@ -1485,18 +1471,7 @@ public class DirectoryFragment extends Fragment args.putParcelable(Shared.EXTRA_SELECTION, new Selection()); final FragmentTransaction ft = fm.beginTransaction(); - switch (anim) { - case ANIM_SIDE: - args.putBoolean(Shared.EXTRA_IGNORE_STATE, true); - break; - case ANIM_ENTER: - args.putBoolean(Shared.EXTRA_IGNORE_STATE, true); - ft.setCustomAnimations(R.animator.dir_enter, R.animator.fade_out); - break; - case ANIM_LEAVE: - ft.setCustomAnimations(R.animator.fade_in, R.animator.dir_leave); - break; - } + AnimationView.setupAnimations(ft, anim, args); final DirectoryFragment fragment = new DirectoryFragment(); fragment.setArguments(args);