Staggered transition support for VerticalGrid

Bug 23319507

Change-Id: Ib86761eccd06bdbe9e2b0712a12a4d2507c5c0db
diff --git a/v17/leanback/api/current.txt b/v17/leanback/api/current.txt
index a5403c8..76ff250 100644
--- a/v17/leanback/api/current.txt
+++ b/v17/leanback/api/current.txt
@@ -427,7 +427,7 @@
     method public abstract boolean onQueryTextSubmit(java.lang.String);
   }
 
-  public class VerticalGridFragment extends android.app.Fragment {
+  public class VerticalGridFragment extends android.support.v17.leanback.app.BrandedFragment {
     ctor public VerticalGridFragment();
     method public android.support.v17.leanback.widget.ObjectAdapter getAdapter();
     method public android.support.v17.leanback.widget.VerticalGridPresenter getGridPresenter();
@@ -439,7 +439,7 @@
     method public void setSelectedPosition(int);
   }
 
-  public class VerticalGridSupportFragment extends android.support.v4.app.Fragment {
+  public class VerticalGridSupportFragment extends android.support.v17.leanback.app.BrandedSupportFragment {
     ctor public VerticalGridSupportFragment();
     method public android.support.v17.leanback.widget.ObjectAdapter getAdapter();
     method public android.support.v17.leanback.widget.VerticalGridPresenter getGridPresenter();
@@ -1585,6 +1585,7 @@
     method public void onBindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder, java.lang.Object);
     method public final android.support.v17.leanback.widget.VerticalGridPresenter.ViewHolder onCreateViewHolder(android.view.ViewGroup);
     method public void onUnbindViewHolder(android.support.v17.leanback.widget.Presenter.ViewHolder);
+    method public void setEntranceTransitionState(android.support.v17.leanback.widget.VerticalGridPresenter.ViewHolder, boolean);
     method public void setNumberOfColumns(int);
     method public final void setOnItemViewClickedListener(android.support.v17.leanback.widget.OnItemViewClickedListener);
     method public final void setOnItemViewSelectedListener(android.support.v17.leanback.widget.OnItemViewSelectedListener);
diff --git a/v17/leanback/res/transition-v21/lb_vertical_grid_enter_transition.xml b/v17/leanback/res/transition-v21/lb_vertical_grid_enter_transition.xml
new file mode 100644
index 0000000..00466cb
--- /dev/null
+++ b/v17/leanback/res/transition-v21/lb_vertical_grid_enter_transition.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 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.
+-->
+
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android" >
+  <fade
+      android:interpolator="@android:interpolator/linear_out_slow_in"
+      android:duration="150"/>
+</transitionSet>
\ No newline at end of file
diff --git a/v17/leanback/res/transition-v21/lb_vertical_grid_entrance_transition.xml b/v17/leanback/res/transition-v21/lb_vertical_grid_entrance_transition.xml
new file mode 100644
index 0000000..ee06953
--- /dev/null
+++ b/v17/leanback/res/transition-v21/lb_vertical_grid_entrance_transition.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 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.
+-->
+
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android" >
+  <slide
+      android:duration="350"
+      android:interpolator="@android:interpolator/linear_out_slow_in"
+      android:slideEdge="bottom">
+  </slide>
+</transitionSet>
\ No newline at end of file
diff --git a/v17/leanback/res/transition-v21/lb_vertical_grid_return_transition.xml b/v17/leanback/res/transition-v21/lb_vertical_grid_return_transition.xml
new file mode 100644
index 0000000..edb3816
--- /dev/null
+++ b/v17/leanback/res/transition-v21/lb_vertical_grid_return_transition.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2015 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.
+-->
+<transitionSet xmlns:android="http://schemas.android.com/apk/res/android" >
+  <slide
+      android:interpolator="@android:interpolator/fast_out_linear_in"
+      android:duration="350"
+      android:slideEdge="bottom">
+      <targets>
+          <target android:excludeId="@+id/title_orb" />
+          <target android:excludeId="@+id/title_text" />
+          <target android:excludeId="@+id/title_badge" />
+      </targets>
+  </slide>
+  <fade
+      android:interpolator="@android:interpolator/fast_out_linear_in"
+      android:duration="350">
+  </fade>
+</transitionSet>
\ No newline at end of file
diff --git a/v17/leanback/res/values/themes.xml b/v17/leanback/res/values/themes.xml
index 0ded94e..d994b3f 100644
--- a/v17/leanback/res/values/themes.xml
+++ b/v17/leanback/res/values/themes.xml
@@ -95,6 +95,11 @@
         <item name="android:windowReturnTransition">@transition/lb_browse_return_transition</item>
     </style>
 
+    <style name="Theme.Leanback.VerticalGrid" parent="Theme.Leanback">
+        <item name="android:windowEnterTransition">@transition/lb_vertical_grid_enter_transition</item>
+        <item name="android:windowReturnTransition">@transition/lb_vertical_grid_return_transition</item>
+    </style>
+
     <style name="Theme.Leanback.Details" parent="Theme.Leanback">
         <item name="android:windowEnterTransition">@transition/lb_details_enter_transition</item>
         <item name="android:windowReturnTransition">@transition/lb_details_return_transition</item>
diff --git a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
index 6b6cc2e..c7d55b9 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridFragment.java
@@ -38,7 +38,7 @@
  * <p>Renders a vertical grid of objects given a {@link VerticalGridPresenter} and
  * an {@link ObjectAdapter}.
  */
-public class VerticalGridFragment extends BrandedFragment {
+public class VerticalGridFragment extends BaseFragment {
     private static final String TAG = "VerticalGridFragment";
     private static boolean DEBUG = false;
 
@@ -47,6 +47,7 @@
     private VerticalGridPresenter.ViewHolder mGridViewHolder;
     private OnItemViewSelectedListener mOnItemViewSelectedListener;
     private OnItemViewClickedListener mOnItemViewClickedListener;
+    private Object mSceneAfterEntranceTransition;
     private int mSelectedPosition = -1;
 
     /**
@@ -170,6 +171,13 @@
         gridDock.addView(mGridViewHolder.view);
         mGridViewHolder.getGridView().setOnChildLaidOutListener(mChildLaidOutListener);
 
+        mSceneAfterEntranceTransition = sTransitionHelper.createScene(gridDock, new Runnable() {
+            @Override
+            public void run() {
+                setEntranceTransitionState(true);
+            }
+        });
+
         updateAdapter();
     }
 
@@ -183,7 +191,9 @@
     public void onStart() {
         super.onStart();
         setupFocusSearchListener();
-        mGridViewHolder.getGridView().requestFocus();
+        if (isEntranceTransitionEnabled()) {
+            setEntranceTransitionState(false);
+        }
     }
 
     @Override
@@ -210,4 +220,20 @@
             }
         }
     }
+
+    @Override
+    protected Object createEntranceTransition() {
+        return sTransitionHelper.loadTransition(getActivity(),
+                R.transition.lb_vertical_grid_entrance_transition);
+    }
+
+    @Override
+    protected void runEntranceTransition(Object entranceTransition) {
+        sTransitionHelper.runTransition(mSceneAfterEntranceTransition,
+                entranceTransition);
+    }
+
+    void setEntranceTransitionState(boolean afterTransition) {
+        mGridPresenter.setEntranceTransitionState(mGridViewHolder, afterTransition);
+    }
 }
diff --git a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridSupportFragment.java b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridSupportFragment.java
index 0770761..33fe6fc 100644
--- a/v17/leanback/src/android/support/v17/leanback/app/VerticalGridSupportFragment.java
+++ b/v17/leanback/src/android/support/v17/leanback/app/VerticalGridSupportFragment.java
@@ -40,7 +40,7 @@
  * <p>Renders a vertical grid of objects given a {@link VerticalGridPresenter} and
  * an {@link ObjectAdapter}.
  */
-public class VerticalGridSupportFragment extends BrandedSupportFragment {
+public class VerticalGridSupportFragment extends BaseSupportFragment {
     private static final String TAG = "VerticalGridSupportFragment";
     private static boolean DEBUG = false;
 
@@ -49,6 +49,7 @@
     private VerticalGridPresenter.ViewHolder mGridViewHolder;
     private OnItemViewSelectedListener mOnItemViewSelectedListener;
     private OnItemViewClickedListener mOnItemViewClickedListener;
+    private Object mSceneAfterEntranceTransition;
     private int mSelectedPosition = -1;
 
     /**
@@ -172,6 +173,13 @@
         gridDock.addView(mGridViewHolder.view);
         mGridViewHolder.getGridView().setOnChildLaidOutListener(mChildLaidOutListener);
 
+        mSceneAfterEntranceTransition = sTransitionHelper.createScene(gridDock, new Runnable() {
+            @Override
+            public void run() {
+                setEntranceTransitionState(true);
+            }
+        });
+
         updateAdapter();
     }
 
@@ -185,7 +193,9 @@
     public void onStart() {
         super.onStart();
         setupFocusSearchListener();
-        mGridViewHolder.getGridView().requestFocus();
+        if (isEntranceTransitionEnabled()) {
+            setEntranceTransitionState(false);
+        }
     }
 
     @Override
@@ -212,4 +222,20 @@
             }
         }
     }
+
+    @Override
+    protected Object createEntranceTransition() {
+        return sTransitionHelper.loadTransition(getActivity(),
+                R.transition.lb_vertical_grid_entrance_transition);
+    }
+
+    @Override
+    protected void runEntranceTransition(Object entranceTransition) {
+        sTransitionHelper.runTransition(mSceneAfterEntranceTransition,
+                entranceTransition);
+    }
+
+    void setEntranceTransitionState(boolean afterTransition) {
+        mGridPresenter.setEntranceTransitionState(mGridViewHolder, afterTransition);
+    }
 }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/RowPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/RowPresenter.java
index 4f078f1..6ab830f 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/RowPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/RowPresenter.java
@@ -642,12 +642,16 @@
      * Changes the visibility of views.  The entrance transition will be run against the views that
      * change visibilities.  A subclass may override and begin with calling
      * super.setEntranceTransitionState().  This method is called by the fragment,
-     * it should not call it directly by the application.
+     * it should not be called directly by the application.
+     *
+     * @param holder         The ViewHolder of the row.
+     * @param afterEntrance  true if children of row participating in entrance transition
+     *                       should be set to visible, false otherwise.
      */
-    public void setEntranceTransitionState(ViewHolder holder, boolean afterTransition) {
+    public void setEntranceTransitionState(ViewHolder holder, boolean afterEntrance) {
         if (holder.mHeaderViewHolder != null &&
                 holder.mHeaderViewHolder.view.getVisibility() != View.GONE) {
-            holder.mHeaderViewHolder.view.setVisibility(afterTransition ?
+            holder.mHeaderViewHolder.view.setVisibility(afterEntrance ?
                     View.VISIBLE : View.INVISIBLE);
         }
     }
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/VerticalGridPresenter.java b/v17/leanback/src/android/support/v17/leanback/widget/VerticalGridPresenter.java
index c04fe85..8f5df72 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/VerticalGridPresenter.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/VerticalGridPresenter.java
@@ -340,4 +340,18 @@
             }
         }
     }
+
+    /**
+     * Changes the visibility of views.  The entrance transition will be run against the views that
+     * change visibilities.  This method is called by the fragment, it should not be called
+     * directly by the application.
+     *
+     * @param holder         The ViewHolder for the vertical grid.
+     * @param afterEntrance  true if children of vertical grid participating in entrance transition
+     *                       should be set to visible, false otherwise.
+     */
+    public void setEntranceTransitionState(VerticalGridPresenter.ViewHolder holder,
+            boolean afterEntrance) {
+        holder.mGridView.setChildrenVisibility(afterEntrance? View.VISIBLE : View.INVISIBLE);
+    }
 }