content: package com.mothership.tvhome.widget;
  
  /*
   * Copyright (C) 2014 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.
   */
  
  
  import android.support.v17.leanback.app.HeadersFragment;
  import android.support.v17.leanback.graphics.ColorOverlayDimmer;
  import android.support.v17.leanback.widget.Presenter;
  import android.support.v17.leanback.widget.Row;
  import android.support.v17.leanback.widget.RowHeaderPresenter;
  import android.text.TextUtils;
  import android.util.Log;
  import android.view.View;
  import android.view.ViewGroup;
  
  /**
   * An abstract {@link Presenter} that renders a {@link Row}.
   *
   * <h3>Customize UI widgets</h3>
   * When a subclass of RowPresenter adds UI widgets, it should subclass
   * {@link RowPresenter.ViewHolder} and override {@link #createRowViewHolder(ViewGroup)}
   * and {@link #initializeRowViewHolder(ViewHolder)}. The subclass must use layout id
   * "row_content" for the widget that will be aligned to the title of any {@link HeadersFragment}
   * that may exist in the parent fragment. RowPresenter contains an optional and
   * replaceable {@link RowHeaderPresenter} that renders the header. You can disable
   * the default rendering or replace the Presenter with a new header presenter
   * by calling {@link #setHeaderPresenter(RowHeaderPresenter)}.
   *
   * <h3>UI events from fragments</h3>
   * RowPresenter receives calls from its parent (typically a Fragment) when:
   * <ul>
   * <li>
   * A row is selected via {@link #setRowViewSelected(Presenter.ViewHolder, boolean)}.  The event
   * is triggered immediately when there is a row selection change before the selection
   * animation is started.  Selected status may control activated status of the row (see
   * "Activated status" below).
   * Subclasses of RowPresenter may override {@link #onRowViewSelected(ViewHolder, boolean)}.
   * </li>
   * <li>
   * A row is expanded to full height via {@link #setRowViewExpanded(Presenter.ViewHolder, boolean)}
   * when BrowseFragment hides fast lane on the left.
   * The event is triggered immediately before the expand animation is started.
   * Row title is shown when row is expanded.  Expanded status may control activated status
   * of the row (see "Activated status" below).
   * Subclasses of RowPresenter may override {@link #onRowViewExpanded(ViewHolder, boolean)}.
   * </li>
   * </ul>
   *
   * <h3>Activated status</h3>
   * The activated status of a row is applied to the row view and it's children via
   * {@link View#setActivated(boolean)}.
   * The activated status is typically used to control {@link BaseCardView} info region visibility.
   * The row's activated status can be controlled by selected status and/or expanded status.
   * Call {@link #setSyncActivatePolicy(int)} and choose one of the four policies:
   * <ul>
   * <li>{@link #SYNC_ACTIVATED_TO_EXPANDED} Activated status is synced with row expanded status</li>
   * <li>{@link #SYNC_ACTIVATED_TO_SELECTED} Activated status is synced with row selected status</li>
   * <li>{@link #SYNC_ACTIVATED_TO_EXPANDED_AND_SELECTED} Activated status is set to true
   *     when both expanded and selected status are true</li>
   * <li>{@link #SYNC_ACTIVATED_CUSTOM} Activated status is not controlled by selected status
   *     or expanded status, application can control activated status by its own.
   *     Application should call {@link RowPresenter.ViewHolder#setActivated(boolean)} to change
   *     activated status of row view.
   * </li>
   * </ul>
   *
   * <h3>User events</h3>
   * RowPresenter provides {@link OnItemViewSelectedListener} and {@link OnItemViewClickedListener}.
   * If a subclass wants to add its own {@link View.OnFocusChangeListener} or
   * {@link View.OnClickListener}, it must do that in {@link #createRowViewHolder(ViewGroup)}
   * to be properly chained by the library.  Adding View listeners after
   * {@link #createRowViewHolder(ViewGroup)} is undefined and may result in
   * incorrect behavior by the library's listeners.
   *
   * <h3>Selection animation</h3>
   * <p>
   * When a user scrolls through rows, a fragment will initiate animation and call
   * {@link #setSelectLevel(Presenter.ViewHolder, float)} with float value between
   * 0 and 1.  By default, the RowPresenter draws a dim overlay on top of the row
   * view for views that are not selected. Subclasses may override this default effect
   * by having {@link #isUsingDefaultSelectEffect()} return false and overriding
   * {@link #onSelectLevelChanged(ViewHolder)} to apply a different selection effect.
   * </p>
   * <p>
   * Call {@link #setSelectEffectEnabled(boolean)} to enable/disable the select effect,
   * This will not only enable/disable the default dim effect but also subclasses must
   * respect this flag as well.
   * </p>
   */
  public abstract class RowPresenter extends Presenter {
  
      /**
       * Don't synchronize row view activated status with selected status or expanded status,
       * application will do its own through {@link RowPresenter.ViewHolder#setActivated(boolean)}.
       */
      public static final int SYNC_ACTIVATED_CUSTOM = 0;
  
      /**
       * Synchronizes row view's activated status to expand status of the row view holder.
       */
      public static final int SYNC_ACTIVATED_TO_EXPANDED = 1;
  
      /**
       * Synchronizes row view's activated status to selected status of the row view holder.
       */
      public static final int SYNC_ACTIVATED_TO_SELECTED = 2;
  
      /**
       * Sets the row view's activated status to true when both expand and selected are true.
       */
      public static final int SYNC_ACTIVATED_TO_EXPANDED_AND_SELECTED = 3;
  
      static class ContainerViewHolder extends Presenter.ViewHolder {
          /**
           * wrapped row view holder
           */
          final ViewHolder mRowViewHolder;
  
          public ContainerViewHolder(RowContainerView containerView, ViewHolder rowViewHolder) {
              super(containerView);
              containerView.addRowView(rowViewHolder.view);
              if (rowViewHolder.mHeaderViewHolder != null) {
                  containerView.addHeaderView(rowViewHolder.mHeaderViewHolder.view);
              }
              mRowViewHolder = rowViewHolder;
              mRowViewHolder.mContainerViewHolder = this;
          }
      }
  
      public interface OnItemViewSelectedListener {
          public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item,
                                     ViewHolder rowViewHolder, Row row);
      }
      public interface OnItemViewClickedListener {
  
          public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item,
                                    RowPresenter.ViewHolder rowViewHolder, Row row);
      }
  
      /**
       * A ViewHolder for a {@link Row}.
       */
      public static class ViewHolder extends Presenter.ViewHolder {
          private static final int ACTIVATED_NOT_ASSIGNED = 0;
          private static final int ACTIVATED = 1;
          private static final int NOT_ACTIVATED = 2;
  
          public ContainerViewHolder mContainerViewHolder;
          RowHeaderPresenter.ViewHolder mHeaderViewHolder;
          Row mRow;
          int mActivated = ACTIVATED_NOT_ASSIGNED;
          boolean mSelected;
          boolean mExpanded;
          boolean mInitialzed;
          float mSelectLevel = 0f; // initially unselected
          protected final ColorOverlayDimmer mColorDimmer;
          private View.OnKeyListener mOnKeyListener;
          private OnItemViewSelectedListener mOnItemViewSelectedListener;
          private OnItemViewClickedListener mOnItemViewClickedListener;
  
          /**
           * Constructor for ViewHolder.
           *
           * @param view The View bound to the Row.
           */
          public ViewHolder(View view) {
              super(view);
              mColorDimmer = ColorOverlayDimmer.createDefault(view.getContext());
          }
  
          /**
           * Returns the Row bound to the View in this ViewHolder.
           */
          public final Row getRow() {
              return mRow;
          }
  
          /**
           * Returns whether the Row is in its expanded state.
           *
           * @return true if the Row is expanded, false otherwise.
           */
          public final boolean isExpanded() {
              return mExpanded;
          }
  
          /**
           * Returns whether the Row is selected.
           *
           * @return true if the Row is selected, false otherwise.
           */
          public final boolean isSelected() {
              return mSelected;
          }
  
          /**
           * Returns the current selection level of the Row.
           */
          public final float getSelectLevel() {
              return mSelectLevel;
          }
  
          /**
           * Returns the view holder for the Row header for this Row.
           */
          public final RowHeaderPresenter.ViewHolder getHeaderViewHolder() {
              return mHeaderViewHolder;
          }
  
          /**
           * Sets the row view's activated status.  The status will be applied to children through
           * {@link #syncActivatedStatus(View)}.  Application should only call this function
           * when {@link RowPresenter#getSyncActivatePolicy()} is
           * {@link RowPresenter#SYNC_ACTIVATED_CUSTOM}; otherwise the value will
           * be overwritten when expanded or selected status changes.
           */
          public final void setActivated(boolean activated) {
              mActivated = activated ? ACTIVATED : NOT_ACTIVATED;
          }
  
          /**
           * Synchronizes the activated status of view to the last value passed through
           * {@link RowPresenter.ViewHolder#setActivated(boolean)}. No operation if
           * {@link RowPresenter.ViewHolder#setActivated(boolean)} is never called.  Normally
           * application does not need to call this method,  {@link android.support.v17.leanback.widget.ListRowPresenter} automatically
           * calls this method when a child is attached to list row.   However if
           * application writes its own custom RowPresenter, it should call this method
           * when attaches a child to the row view.
           */
          public final void syncActivatedStatus(View view) {
              if (mActivated == ACTIVATED) {
                  view.setActivated(true);
              } else if (mActivated == NOT_ACTIVATED) {
                  view.setActivated(false);
              }
          }
  
          /**
           * Sets a key listener.
           */
          public void setOnKeyListener(View.OnKeyListener keyListener) {
              mOnKeyListener = keyListener;
          }
  
          /**
           * Returns the key listener.
           */
          public View.OnKeyListener getOnKeyListener() {
              return mOnKeyListener;
          }
  
          /**
           * Sets the listener for item or row selection.  RowPresenter fires row selection
           * event with null item.  A subclass of RowPresenter e.g. {@link android.support.v17.leanback.widget.ListRowPresenter} may
           * fire a selection event with selected item.
           */
          public final void setOnItemViewSelectedListener(OnItemViewSelectedListener listener) {
              mOnItemViewSelectedListener = listener;
          }
  
          /**
           * Returns the listener for item or row selection.
           */
          public final OnItemViewSelectedListener getOnItemViewSelectedListener() {
              return mOnItemViewSelectedListener;
          }
  
          /**
           * Sets the listener for item click event.  RowPresenter does nothing but subclass of
           * RowPresenter may fire item click event if it has the concept of item.
           * OnItemViewClickedListener will override {@link View.OnClickListener} that
           * item presenter sets during {@link Presenter#onCreateViewHolder(ViewGroup)}.
           */
          public final void setOnItemViewClickedListener(OnItemViewClickedListener listener) {
              mOnItemViewClickedListener = listener;
          }
  
          /**
           * Returns the listener for item click event.
           */
          public final OnItemViewClickedListener getOnItemViewClickedListener() {
              return mOnItemViewClickedListener;
          }
  
  
      }
  
      private RowHeaderPresenter mHeaderPresenter = new RowHeaderPresenter();
  
      boolean mSelectEffectEnabled = false;
      int mSyncActivatePolicy = SYNC_ACTIVATED_TO_EXPANDED;
      private static FocusHelper.FocusHighlightHandler mFocusHighlight;
  
      /**
       * Constructs a RowPresenter.
       */
      public RowPresenter() {
          mHeaderPresenter.setNullItemVisibilityGone(true);
      }
  
      @Override
      public final Presenter.ViewHolder onCreateViewHolder(ViewGroup parent) {
          ViewHolder vh = createRowViewHolder(parent);
          vh.mInitialzed = false;
          Presenter.ViewHolder result;
          if (needsRowContainerView()) {
              RowContainerView containerView = new RowContainerView(parent.getContext());
              if (mHeaderPresenter != null) {
                  vh.mHeaderViewHolder = (RowHeaderPresenter.ViewHolder)
                          mHeaderPresenter.onCreateViewHolder((ViewGroup) vh.view);
              }
              result = new ContainerViewHolder(containerView, vh);
          } else {
              result = vh;
          }
          initializeRowViewHolder(vh);
          if (!vh.mInitialzed) {
              throw new RuntimeException("super.initializeRowViewHolder() must be called");
          }
          return result;
      }
  
      /**
       * Called to create a ViewHolder object for a Row. Subclasses will override
       * this method to return a different concrete ViewHolder object.
       *
       * @param parent The parent View for the Row's view holder.
       * @return A ViewHolder for the Row's View.
       */
      protected abstract ViewHolder createRowViewHolder(ViewGroup parent);
  
      /**
       * Returns true if the Row view should clip it's children.  The clipChildren
       * flag is set on view in {@link #initializeRowViewHolder(ViewHolder)}.  Note that
       * Slide transition or explode transition need turn off clipChildren.
       * Default value is false.
       */
      protected boolean isClippingChildren() {
          return false;
      }
  
      /**
       * Called after a {@link RowPresenter.ViewHolder} is created for a Row.
       * Subclasses may override this method and start by calling
       * super.initializeRowViewHolder(ViewHolder).
       *
       * @param vh The ViewHolder to initialize for the Row.
       */
      protected void initializeRowViewHolder(ViewHolder vh) {
          vh.mInitialzed = true;
          if (!isClippingChildren()) {
              // set clip children to false for slide transition
              if (vh.view instanceof ViewGroup) {
                  ((ViewGroup) vh.view).setClipChildren(false);
              }
              if (vh.mContainerViewHolder != null) {
                  ((ViewGroup) vh.mContainerViewHolder.view).setClipChildren(false);
              }
          }
      }
  
      /**
       * Sets the Presenter used for rendering the header. Can be null to disable
       * header rendering. The method must be called before creating any Row Views.
       */
      public final void setHeaderPresenter(RowHeaderPresenter headerPresenter) {
          mHeaderPresenter = headerPresenter;
      }
  
      /**
       * Returns the Presenter used for rendering the header, or null if none has been
       * set.
       */
      public final RowHeaderPresenter getHeaderPresenter() {
          return mHeaderPresenter;
      }
  
      /**
       * Returns the {@link RowPresenter.ViewHolder} from the given RowPresenter
       * ViewHolder.
       */
      public final ViewHolder getRowViewHolder(Presenter.ViewHolder holder) {
          if (holder instanceof ContainerViewHolder) {
              return ((ContainerViewHolder) holder).mRowViewHolder;
          } else {
              return (ViewHolder) holder;
          }
      }
  
      /**
       * Sets the expanded state of a Row view.
       *
       * @param holder The Row ViewHolder to set expanded state on.
       * @param expanded True if the Row is expanded, false otherwise.
       */
      public final void setRowViewExpanded(Presenter.ViewHolder holder, boolean expanded) {
          ViewHolder rowViewHolder = getRowViewHolder(holder);
          rowViewHolder.mExpanded = expanded;
          onRowViewExpanded(rowViewHolder, expanded);
      }
  
      /**
       * Sets the selected state of a Row view.
       *
       * @param holder The Row ViewHolder to set expanded state on.
       * @param selected True if the Row is expanded, false otherwise.
       */
      public final void setRowViewSelected(Presenter.ViewHolder holder, boolean selected) {
          ViewHolder rowViewHolder = getRowViewHolder(holder);
          rowViewHolder.mSelected = selected;
          onRowViewSelected(rowViewHolder, selected);
      }
  
      /**
       * Called when the row view's expanded state changes.  A subclass may override this method to
       * respond to expanded state changes of a Row.
       * The default implementation will hide/show the header view. Subclasses may
       * make visual changes to the Row View but must not create animation on the
       * Row view.
       */
      protected void onRowViewExpanded(ViewHolder vh, boolean expanded) {
          updateHeaderViewVisibility(vh);
          updateActivateStatus(vh, vh.view);
      }
  
      /**
       * Updates the view's activate status according to {@link #getSyncActivatePolicy()} and the
       * selected status and expanded status of the RowPresenter ViewHolder.
       */
      private void updateActivateStatus(ViewHolder vh, View view) {
          switch (mSyncActivatePolicy) {
              case SYNC_ACTIVATED_TO_EXPANDED:
                  vh.setActivated(vh.isExpanded());
                  break;
              case SYNC_ACTIVATED_TO_SELECTED:
                  vh.setActivated(vh.isSelected());
                  break;
              case SYNC_ACTIVATED_TO_EXPANDED_AND_SELECTED:
                  vh.setActivated(vh.isExpanded() && vh.isSelected());
                  break;
          }
          vh.syncActivatedStatus(view);
      }
  
      /**
       * Sets the policy of updating row view activated status.  Can be one of:
       * <li> Default value {@link #SYNC_ACTIVATED_TO_EXPANDED}
       * <li> {@link #SYNC_ACTIVATED_TO_SELECTED}
       * <li> {@link #SYNC_ACTIVATED_TO_EXPANDED_AND_SELECTED}
       * <li> {@link #SYNC_ACTIVATED_CUSTOM}
       */
      public final void setSyncActivatePolicy(int syncActivatePolicy) {
          mSyncActivatePolicy = syncActivatePolicy;
      }
  
      /**
       * Returns the policy of updating row view activated status.  Can be one of:
       * <li> Default value {@link #SYNC_ACTIVATED_TO_EXPANDED}
       * <li> {@link #SYNC_ACTIVATED_TO_SELECTED}
       * <li> {@link #SYNC_ACTIVATED_TO_EXPANDED_AND_SELECTED}
       * <li> {@link #SYNC_ACTIVATED_CUSTOM}
       */
      public final int getSyncActivatePolicy() {
          return mSyncActivatePolicy;
      }
  
      /**
       * This method is only called from
       * {@link #onRowViewSelected(ViewHolder, boolean)} onRowViewSelected.
       * The default behavior is to signal row selected events with a null item parameter.
       * A Subclass of RowPresenter having child items should override this method and dispatch
       * events with item information.
       */
      protected void dispatchItemSelectedListener(ViewHolder vh, boolean selected) {
          if (selected) {
              if (vh.mOnItemViewSelectedListener != null) {
                  vh.mOnItemViewSelectedListener.onItemSelected(null, null, vh, vh.getRow());
              }
          }
      }
  
      /**
       * Called when the given row view changes selection state.  A subclass may override this to
       * respond to selected state changes of a Row.  A subclass may make visual changes to Row view
       * but must not create animation on the Row view.
       */
      protected void onRowViewSelected(ViewHolder vh, boolean selected) {
          dispatchItemSelectedListener(vh, selected);
          updateHeaderViewVisibility(vh);
          updateActivateStatus(vh, vh.view);
      }
  
      private void updateHeaderViewVisibility(ViewHolder vh) {
          if (mHeaderPresenter != null && vh.mHeaderViewHolder != null) {
              RowContainerView containerView = ((RowContainerView) vh.mContainerViewHolder.view);
              containerView.showHeader(vh.isExpanded());
          }
      }
  
      /**
       * Sets the current select level to a value between 0 (unselected) and 1 (selected).
       * Subclasses may override {@link #onSelectLevelChanged(ViewHolder)} to
       * respond to changes in the selected level.
       */
      public final void setSelectLevel(Presenter.ViewHolder vh, float level) {
          ViewHolder rowViewHolder = getRowViewHolder(vh);
          rowViewHolder.mSelectLevel = level;
          onSelectLevelChanged(rowViewHolder);
      }
  
      /**
       * Returns the current select level. The value will be between 0 (unselected)
       * and 1 (selected).
       */
      public final float getSelectLevel(Presenter.ViewHolder vh) {
          return getRowViewHolder(vh).mSelectLevel;
      }
  
      /**
       * Callback when the select level changes. The default implementation applies
       * the select level to {@link RowHeaderPresenter#setSelectLevel(RowHeaderPresenter.ViewHolder, float)}
       * when {@link #getSelectEffectEnabled()} is true. Subclasses may override
       * this function and implement a different select effect. In this case,
       * the method {@link #isUsingDefaultSelectEffect()} should also be overridden to disable
       * the default dimming effect.
       */
      protected void onSelectLevelChanged(ViewHolder vh) {
          if (getSelectEffectEnabled()) {
              vh.mColorDimmer.setActiveLevel(vh.mSelectLevel);
              if (vh.mHeaderViewHolder != null) {
                  mHeaderPresenter.setSelectLevel(vh.mHeaderViewHolder, vh.mSelectLevel);
              }
              if (isUsingDefaultSelectEffect()) {
                  ((RowContainerView) vh.mContainerViewHolder.view).setForegroundColor(
                          vh.mColorDimmer.getPaint().getColor());
              }
          }
      }
  
      /**
       * Enables or disables the row selection effect.
       * This will not only affect the default dim effect, but subclasses must
       * respect this flag as well.
       */
      public final void setSelectEffectEnabled(boolean applyDimOnSelect) {
          mSelectEffectEnabled = applyDimOnSelect;
      }
  
      /**
       * Returns true if the row selection effect is enabled.
       * This value not only determines whether the default dim implementation is
       * used, but subclasses must also respect this flag.
       */
      public final boolean getSelectEffectEnabled() {
          return mSelectEffectEnabled;
      }
  
      /**
       * Returns true if this RowPresenter is using the default dimming effect.
       * A subclass may (most likely) return false and
       * override {@link #onSelectLevelChanged(ViewHolder)}.
       */
      public boolean isUsingDefaultSelectEffect() {
          return true;
      }
  
      final boolean needsDefaultSelectEffect() {
          return isUsingDefaultSelectEffect() && getSelectEffectEnabled();
      }
  
      final boolean needsRowContainerView() {
          return mHeaderPresenter != null || needsDefaultSelectEffect();
      }
  
      @Override
      public final void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) {
          onBindRowViewHolder(getRowViewHolder(viewHolder), item);
      }
  
      /**
       * Binds the given row object to the given ViewHolder.
       */
      protected void onBindRowViewHolder(ViewHolder vh, Object item) {
          vh.mRow = (Row) item;
          if (vh.mHeaderViewHolder != null) {
              mHeaderPresenter.onBindViewHolder(vh.mHeaderViewHolder, item);
          }
          if(TextUtils.isEmpty(vh.mRow.getHeaderItem().getName())){
              setRowViewExpanded(vh,false);
          }else{
              setRowViewExpanded(vh, true);
          }
      }
  
      @Override
      public final void onUnbindViewHolder(Presenter.ViewHolder viewHolder) {
          onUnbindRowViewHolder(getRowViewHolder(viewHolder));
      }
  
      /**
       * Unbinds the given ViewHolder.
       */
      protected void onUnbindRowViewHolder(ViewHolder vh) {
          if (vh.mHeaderViewHolder != null) {
              mHeaderPresenter.onUnbindViewHolder(vh.mHeaderViewHolder);
          }
          vh.mRow = null;
      }
  
      @Override
      public final void onViewAttachedToWindow(Presenter.ViewHolder holder) {
          onRowViewAttachedToWindow(getRowViewHolder(holder));
      }
  
      /**
       * Invoked when the row view is attached to the window.
       */
      protected void onRowViewAttachedToWindow(ViewHolder vh) {
          if (vh.mHeaderViewHolder != null) {
              mHeaderPresenter.onViewAttachedToWindow(vh.mHeaderViewHolder);
          }
      }
  
      @Override
      public final void onViewDetachedFromWindow(Presenter.ViewHolder holder) {
          onRowViewDetachedFromWindow(getRowViewHolder(holder));
      }
  
      /**
       * Invoked when the row view is detached from the window.
       */
      protected void onRowViewDetachedFromWindow(ViewHolder vh) {
          if (vh.mHeaderViewHolder != null) {
              mHeaderPresenter.onViewDetachedFromWindow(vh.mHeaderViewHolder);
          }
          cancelAnimationsRecursive(vh.view);
      }
  
      /**
       * Freezes/unfreezes the row, typically used when a transition starts/ends.
       * This method is called by the fragment, it should not call it directly by the application.
       */
      public void freeze(ViewHolder holder, boolean freeze) {
      }
  
      /**
       * 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 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 afterEntrance) {
          if (holder.mHeaderViewHolder != null &&
                  holder.mHeaderViewHolder.view.getVisibility() != View.GONE) {
              holder.mHeaderViewHolder.view.setVisibility(afterEntrance ?
                      View.VISIBLE : View.INVISIBLE);
          }
      }
  }
  
  