GuidedStepFragment: fix initial selector view size flicking
In layout pass, onLayout of VerticalGridView triggers a focus change event
where we change LayoutParams of the selectorView, but because parent RelativeLayout
does not re-measure the selectorView in RelativeLayout.onLayout, parent RelativeLayout
calls selectorView.layout() with the obsolete values and leave the view size
inconsistent with LayoutParams.
Our current workaround "post a Runnable" causes one frame flicking when fragment
is initially loaded.
One non-trivial fix is to override RelativeLayout and re-measure the selectorView
between VerticalGridView.onLayout() and selectorView.onLayout().
But since we use scaleY anyway later, switching to use scaleY is much simpler.
Change-Id: I585609695048cffd23e67619320af187e37ffbb6
diff --git a/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionsStylist.java b/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionsStylist.java
index 74dc1b6..ab50399 100644
--- a/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionsStylist.java
+++ b/v17/leanback/src/android/support/v17/leanback/widget/GuidedActionsStylist.java
@@ -273,6 +273,18 @@
public View onCreateView(LayoutInflater inflater, ViewGroup container) {
mMainView = inflater.inflate(onProvideLayoutId(), container, false);
mSelectorView = mMainView.findViewById(R.id.guidedactions_selector);
+ mSelectorView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
+ @Override
+ public void onLayoutChange(View v, int left, int top, int right, int bottom,
+ int oldLeft, int oldTop, int oldRight, int oldBottom) {
+ final View focusedChild = mActionsGridView.getFocusedChild();
+ if (focusedChild != null && mSelectorView.getVisibility() == View.VISIBLE &&
+ mSelectorView.getHeight() > 0) {
+ mSelectorView.setScaleY((float) focusedChild.getHeight()
+ / mSelectorView.getHeight());
+ }
+ }
+ });
mBgView = mMainView.findViewById(R.id.guided_button_actions_background);
if (mMainView instanceof VerticalGridView) {
mActionsGridView = (VerticalGridView) mMainView;
@@ -358,16 +370,10 @@
} else if (!mChildFocused) {
mChildFocused = true;
mSelectorView.setVisibility(View.VISIBLE);
- // Change Selector size in a post Runnable, doing it directly in
- // GlobalFocusChangeListener does not trigger the layout pass.
- mSelectorView.post(new Runnable() {
- public void run() {
- int height = focusedChild.getHeight();
- LayoutParams lp = mSelectorView.getLayoutParams();
- lp.height = height;
- mSelectorView.setLayoutParams(lp);
- }
- });
+ if (mSelectorView.getHeight() > 0) {
+ mSelectorView.setScaleY((float) focusedChild.getHeight()
+ / mSelectorView.getHeight());
+ }
}
}
};