ListRowPresenter.java revision cb04695965b44b6ff633a773426df286d3bfaad9
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except 5 * in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the License 10 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express 11 * or implied. See the License for the specific language governing permissions and limitations under 12 * the License. 13 */ 14package android.support.v17.leanback.widget; 15 16import android.content.Context; 17import android.content.res.TypedArray; 18import android.support.v17.leanback.R; 19import android.support.v17.leanback.graphics.ColorOverlayDimmer; 20import android.util.Log; 21import android.view.View; 22import android.view.ViewGroup; 23import android.view.ViewGroup.LayoutParams; 24 25import java.util.HashMap; 26 27/** 28 * ListRowPresenter renders {@link ListRow} using a 29 * {@link HorizontalGridView} hosted in a {@link ListRowView}. 30 * 31 * <h3>Hover card</h3> 32 * Optionally, {@link #setHoverCardPresenterSelector(PresenterSelector)} can be used to 33 * display a view for the currently focused list item below the rendered 34 * list. This view is known as a hover card. 35 * 36 * <h3>Selection animation</h3> 37 * ListRowPresenter disables {@link RowPresenter}'s default dimming effect and draw 38 * a dim overlay on top of each individual child items. Subclass may override and disable 39 * {@link #isUsingDefaultListSelectEffect()} and write its own dim effect in 40 * {@link #onSelectLevelChanged(RowPresenter.ViewHolder)}. 41 * 42 * <h3>Shadow</h3> 43 * ListRowPresenter applies a default shadow to child of each view. Call 44 * {@link #setShadowEnabled(boolean)} to disable shadow. Subclass may override and return 45 * false in {@link #isUsingDefaultShadow()} and replace with its own shadow implementation. 46 */ 47public class ListRowPresenter extends RowPresenter { 48 49 private static final String TAG = "ListRowPresenter"; 50 private static final boolean DEBUG = false; 51 52 private static final int DEFAULT_RECYCLED_POOL_SIZE = 24; 53 54 public static class ViewHolder extends RowPresenter.ViewHolder { 55 final ListRowPresenter mListRowPresenter; 56 final HorizontalGridView mGridView; 57 ItemBridgeAdapter mItemBridgeAdapter; 58 final HorizontalHoverCardSwitcher mHoverCardViewSwitcher = new HorizontalHoverCardSwitcher(); 59 final int mPaddingTop; 60 final int mPaddingBottom; 61 final int mPaddingLeft; 62 final int mPaddingRight; 63 64 public ViewHolder(View rootView, HorizontalGridView gridView, ListRowPresenter p) { 65 super(rootView); 66 mGridView = gridView; 67 mListRowPresenter = p; 68 mPaddingTop = mGridView.getPaddingTop(); 69 mPaddingBottom = mGridView.getPaddingBottom(); 70 mPaddingLeft = mGridView.getPaddingLeft(); 71 mPaddingRight = mGridView.getPaddingRight(); 72 } 73 74 public final ListRowPresenter getListRowPresenter() { 75 return mListRowPresenter; 76 } 77 78 public final HorizontalGridView getGridView() { 79 return mGridView; 80 } 81 82 public final ItemBridgeAdapter getBridgeAdapter() { 83 return mItemBridgeAdapter; 84 } 85 } 86 87 class ListRowPresenterItemBridgeAdapter extends ItemBridgeAdapter { 88 ListRowPresenter.ViewHolder mRowViewHolder; 89 90 ListRowPresenterItemBridgeAdapter(ListRowPresenter.ViewHolder rowViewHolder) { 91 mRowViewHolder = rowViewHolder; 92 } 93 94 @Override 95 public void onBind(final ItemBridgeAdapter.ViewHolder viewHolder) { 96 // Only when having an OnItemClickListner, we will attach the OnClickListener. 97 if (getOnItemClickedListener() != null || getOnItemViewClickedListener() != null) { 98 viewHolder.mHolder.view.setOnClickListener(new View.OnClickListener() { 99 @Override 100 public void onClick(View v) { 101 ItemBridgeAdapter.ViewHolder ibh = (ItemBridgeAdapter.ViewHolder) 102 mRowViewHolder.mGridView.getChildViewHolder(viewHolder.itemView); 103 if (getOnItemClickedListener() != null) { 104 getOnItemClickedListener().onItemClicked(ibh.mItem, 105 (ListRow) mRowViewHolder.mRow); 106 } 107 if (getOnItemViewClickedListener() != null) { 108 getOnItemViewClickedListener().onItemClicked(viewHolder.mHolder, 109 ibh.mItem, mRowViewHolder, (ListRow) mRowViewHolder.mRow); 110 } 111 } 112 }); 113 } 114 } 115 116 @Override 117 public void onUnbind(ItemBridgeAdapter.ViewHolder viewHolder) { 118 if (getOnItemClickedListener() != null || getOnItemViewClickedListener() != null) { 119 viewHolder.mHolder.view.setOnClickListener(null); 120 } 121 } 122 123 @Override 124 public void onAttachedToWindow(ItemBridgeAdapter.ViewHolder viewHolder) { 125 if (viewHolder.itemView instanceof ShadowOverlayContainer) { 126 int dimmedColor = mRowViewHolder.mColorDimmer.getPaint().getColor(); 127 ((ShadowOverlayContainer) viewHolder.itemView).setOverlayColor(dimmedColor); 128 } 129 mRowViewHolder.syncActivatedStatus(viewHolder.itemView); 130 } 131 132 @Override 133 public void onAddPresenter(Presenter presenter, int type) { 134 mRowViewHolder.getGridView().getRecycledViewPool().setMaxRecycledViews( 135 type, getRecycledPoolSize(presenter)); 136 } 137 } 138 139 private int mRowHeight; 140 private int mExpandedRowHeight; 141 private PresenterSelector mHoverCardPresenterSelector; 142 private int mZoomFactor; 143 private boolean mShadowEnabled = true; 144 private int mBrowseRowsFadingEdgeLength = -1; 145 private boolean mRoundedCornersEnabled = true; 146 private HashMap<Presenter, Integer> mRecycledPoolSize = new HashMap<Presenter, Integer>(); 147 148 private static int sSelectedRowTopPadding; 149 private static int sExpandedSelectedRowTopPadding; 150 private static int sExpandedRowNoHovercardBottomPadding; 151 152 /** 153 * Constructs a ListRowPresenter with defaults. 154 * Uses {@link FocusHighlight#ZOOM_FACTOR_MEDIUM} for focus zooming. 155 */ 156 public ListRowPresenter() { 157 this(FocusHighlight.ZOOM_FACTOR_MEDIUM); 158 } 159 160 /** 161 * Constructs a ListRowPresenter with the given parameters. 162 * 163 * @param zoomFactor Controls the zoom factor used when an item view is focused. One of 164 * {@link FocusHighlight#ZOOM_FACTOR_NONE}, 165 * {@link FocusHighlight#ZOOM_FACTOR_SMALL}, 166 * {@link FocusHighlight#ZOOM_FACTOR_XSMALL}, 167 * {@link FocusHighlight#ZOOM_FACTOR_MEDIUM}, 168 * {@link FocusHighlight#ZOOM_FACTOR_LARGE} 169 */ 170 public ListRowPresenter(int zoomFactor) { 171 if (!FocusHighlightHelper.isValidZoomIndex(zoomFactor)) { 172 throw new IllegalArgumentException("Unhandled zoom factor"); 173 } 174 mZoomFactor = zoomFactor; 175 } 176 177 /** 178 * Sets the row height for rows created by this Presenter. Rows 179 * created before calling this method will not be updated. 180 * 181 * @param rowHeight Row height in pixels, or WRAP_CONTENT, or 0 182 * to use the default height. 183 */ 184 public void setRowHeight(int rowHeight) { 185 mRowHeight = rowHeight; 186 } 187 188 /** 189 * Returns the row height for list rows created by this Presenter. 190 */ 191 public int getRowHeight() { 192 return mRowHeight; 193 } 194 195 /** 196 * Sets the expanded row height for rows created by this Presenter. 197 * If not set, expanded rows have the same height as unexpanded 198 * rows. 199 * 200 * @param rowHeight The row height in to use when the row is expanded, 201 * in pixels, or WRAP_CONTENT, or 0 to use the default. 202 */ 203 public void setExpandedRowHeight(int rowHeight) { 204 mExpandedRowHeight = rowHeight; 205 } 206 207 /** 208 * Returns the expanded row height for rows created by this Presenter. 209 */ 210 public int getExpandedRowHeight() { 211 return mExpandedRowHeight != 0 ? mExpandedRowHeight : mRowHeight; 212 } 213 214 /** 215 * Returns the zoom factor used for focus highlighting. 216 */ 217 public final int getZoomFactor() { 218 return mZoomFactor; 219 } 220 221 private ItemBridgeAdapter.Wrapper mCardWrapper = new ItemBridgeAdapter.Wrapper() { 222 @Override 223 public View createWrapper(View root) { 224 ShadowOverlayContainer wrapper = new ShadowOverlayContainer(root.getContext()); 225 wrapper.setLayoutParams( 226 new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); 227 wrapper.initialize(needsDefaultShadow(), 228 needsDefaultListSelectEffect(), 229 areChildRoundedCornersEnabled()); 230 return wrapper; 231 } 232 @Override 233 public void wrap(View wrapper, View wrapped) { 234 ((ShadowOverlayContainer) wrapper).wrap(wrapped); 235 } 236 }; 237 238 @Override 239 protected void initializeRowViewHolder(RowPresenter.ViewHolder holder) { 240 super.initializeRowViewHolder(holder); 241 final ViewHolder rowViewHolder = (ViewHolder) holder; 242 rowViewHolder.mItemBridgeAdapter = new ListRowPresenterItemBridgeAdapter(rowViewHolder); 243 if (needsDefaultListSelectEffect() || needsDefaultShadow() 244 || areChildRoundedCornersEnabled()) { 245 rowViewHolder.mItemBridgeAdapter.setWrapper(mCardWrapper); 246 } 247 if (needsDefaultListSelectEffect()) { 248 ShadowOverlayContainer.prepareParentForShadow(rowViewHolder.mGridView); 249 } 250 FocusHighlightHelper.setupBrowseItemFocusHighlight(rowViewHolder.mItemBridgeAdapter, 251 mZoomFactor, false); 252 rowViewHolder.mGridView.setFocusDrawingOrderEnabled(!isUsingZOrder()); 253 rowViewHolder.mGridView.setOnChildSelectedListener( 254 new OnChildSelectedListener() { 255 @Override 256 public void onChildSelected(ViewGroup parent, View view, int position, long id) { 257 selectChildView(rowViewHolder, view); 258 } 259 }); 260 } 261 262 final boolean needsDefaultListSelectEffect() { 263 return isUsingDefaultListSelectEffect() && getSelectEffectEnabled(); 264 } 265 266 /** 267 * Sets the recycled pool size for the given presenter. 268 */ 269 public void setRecycledPoolSize(Presenter presenter, int size) { 270 mRecycledPoolSize.put(presenter, size); 271 } 272 273 /** 274 * Returns the recycled pool size for the given presenter. 275 */ 276 public int getRecycledPoolSize(Presenter presenter) { 277 return mRecycledPoolSize.containsKey(presenter) ? mRecycledPoolSize.get(presenter) : 278 DEFAULT_RECYCLED_POOL_SIZE; 279 } 280 281 /** 282 * Set {@link PresenterSelector} used for showing a select object in a hover card. 283 */ 284 public final void setHoverCardPresenterSelector(PresenterSelector selector) { 285 mHoverCardPresenterSelector = selector; 286 } 287 288 /** 289 * Get {@link PresenterSelector} used for showing a select object in a hover card. 290 */ 291 public final PresenterSelector getHoverCardPresenterSelector() { 292 return mHoverCardPresenterSelector; 293 } 294 295 /* 296 * Perform operations when a child of horizontal grid view is selected. 297 */ 298 private void selectChildView(ViewHolder rowViewHolder, View view) { 299 if (view != null) { 300 if (rowViewHolder.mExpanded && rowViewHolder.mSelected) { 301 ItemBridgeAdapter.ViewHolder ibh = (ItemBridgeAdapter.ViewHolder) 302 rowViewHolder.mGridView.getChildViewHolder(view); 303 304 if (mHoverCardPresenterSelector != null) { 305 rowViewHolder.mHoverCardViewSwitcher.select(rowViewHolder.mGridView, view, 306 ibh.mItem); 307 } 308 if (getOnItemViewSelectedListener() != null) { 309 getOnItemViewSelectedListener().onItemSelected(ibh.mHolder, ibh.mItem, 310 rowViewHolder, rowViewHolder.mRow); 311 } 312 if (getOnItemSelectedListener() != null) { 313 getOnItemSelectedListener().onItemSelected(ibh.mItem, rowViewHolder.mRow); 314 } 315 } 316 } else { 317 if (mHoverCardPresenterSelector != null) { 318 rowViewHolder.mHoverCardViewSwitcher.unselect(); 319 } 320 if (getOnItemViewSelectedListener() != null) { 321 getOnItemViewSelectedListener().onItemSelected(null, null, 322 rowViewHolder, rowViewHolder.mRow); 323 } 324 if (getOnItemSelectedListener() != null) { 325 getOnItemSelectedListener().onItemSelected(null, rowViewHolder.mRow); 326 } 327 } 328 } 329 330 private static void initStatics(Context context) { 331 if (sSelectedRowTopPadding == 0) { 332 sSelectedRowTopPadding = context.getResources().getDimensionPixelSize( 333 R.dimen.lb_browse_selected_row_top_padding); 334 sExpandedSelectedRowTopPadding = context.getResources().getDimensionPixelSize( 335 R.dimen.lb_browse_expanded_selected_row_top_padding); 336 sExpandedRowNoHovercardBottomPadding = context.getResources().getDimensionPixelSize( 337 R.dimen.lb_browse_expanded_row_no_hovercard_bottom_padding); 338 } 339 } 340 341 private int getSpaceUnderBaseline(ListRowPresenter.ViewHolder vh) { 342 RowHeaderPresenter.ViewHolder headerViewHolder = vh.getHeaderViewHolder(); 343 if (headerViewHolder != null) { 344 if (getHeaderPresenter() != null) { 345 return getHeaderPresenter().getSpaceUnderBaseline(headerViewHolder); 346 } 347 return headerViewHolder.view.getPaddingBottom(); 348 } 349 return 0; 350 } 351 352 private void setVerticalPadding(ListRowPresenter.ViewHolder vh) { 353 int paddingTop, paddingBottom; 354 // Note: sufficient bottom padding needed for card shadows. 355 if (vh.isExpanded()) { 356 int headerSpaceUnderBaseline = getSpaceUnderBaseline(vh); 357 if (DEBUG) Log.v(TAG, "headerSpaceUnderBaseline " + headerSpaceUnderBaseline); 358 paddingTop = (vh.isSelected() ? sExpandedSelectedRowTopPadding : vh.mPaddingTop) - 359 headerSpaceUnderBaseline; 360 paddingBottom = mHoverCardPresenterSelector == null ? 361 sExpandedRowNoHovercardBottomPadding : vh.mPaddingBottom; 362 } else if (vh.isSelected()) { 363 paddingTop = sSelectedRowTopPadding - vh.mPaddingBottom; 364 paddingBottom = sSelectedRowTopPadding; 365 } else { 366 paddingTop = 0; 367 paddingBottom = vh.mPaddingBottom; 368 } 369 vh.getGridView().setPadding(vh.mPaddingLeft, paddingTop, vh.mPaddingRight, 370 paddingBottom); 371 } 372 373 @Override 374 protected RowPresenter.ViewHolder createRowViewHolder(ViewGroup parent) { 375 initStatics(parent.getContext()); 376 ListRowView rowView = new ListRowView(parent.getContext()); 377 setupFadingEffect(rowView); 378 if (mRowHeight != 0) { 379 rowView.getGridView().setRowHeight(mRowHeight); 380 } 381 return new ViewHolder(rowView, rowView.getGridView(), this); 382 } 383 384 /** 385 * Dispatch item selected event using current selected item in the {@link HorizontalGridView}. 386 * The method should only be called from onRowViewSelected(). 387 */ 388 @Override 389 protected void dispatchItemSelectedListener(RowPresenter.ViewHolder holder, boolean selected) { 390 ViewHolder vh = (ViewHolder)holder; 391 ItemBridgeAdapter.ViewHolder itemViewHolder = (ItemBridgeAdapter.ViewHolder) 392 vh.mGridView.findViewHolderForPosition(vh.mGridView.getSelectedPosition()); 393 if (itemViewHolder == null) { 394 super.dispatchItemSelectedListener(holder, selected); 395 return; 396 } 397 398 if (selected) { 399 if (getOnItemViewSelectedListener() != null) { 400 getOnItemViewSelectedListener().onItemSelected( 401 itemViewHolder.getViewHolder(), itemViewHolder.mItem, vh, vh.getRow()); 402 } 403 if (getOnItemSelectedListener() != null) { 404 getOnItemSelectedListener().onItemSelected(itemViewHolder.mItem, vh.getRow()); 405 } 406 } 407 } 408 409 @Override 410 protected void onRowViewSelected(RowPresenter.ViewHolder holder, boolean selected) { 411 super.onRowViewSelected(holder, selected); 412 ViewHolder vh = (ViewHolder) holder; 413 setVerticalPadding(vh); 414 updateFooterViewSwitcher(vh); 415 } 416 417 /* 418 * Show or hide hover card when row selection or expanded state is changed. 419 */ 420 private void updateFooterViewSwitcher(ViewHolder vh) { 421 if (vh.mExpanded && vh.mSelected) { 422 if (mHoverCardPresenterSelector != null) { 423 vh.mHoverCardViewSwitcher.init((ViewGroup) vh.view, 424 mHoverCardPresenterSelector); 425 } 426 ItemBridgeAdapter.ViewHolder ibh = (ItemBridgeAdapter.ViewHolder) 427 vh.mGridView.findViewHolderForPosition( 428 vh.mGridView.getSelectedPosition()); 429 selectChildView(vh, ibh == null ? null : ibh.itemView); 430 } else { 431 if (mHoverCardPresenterSelector != null) { 432 vh.mHoverCardViewSwitcher.unselect(); 433 } 434 } 435 } 436 437 private void setupFadingEffect(ListRowView rowView) { 438 // content is completely faded at 1/2 padding of left, fading length is 1/2 of padding. 439 HorizontalGridView gridView = rowView.getGridView(); 440 if (mBrowseRowsFadingEdgeLength < 0) { 441 TypedArray ta = gridView.getContext() 442 .obtainStyledAttributes(R.styleable.LeanbackTheme); 443 mBrowseRowsFadingEdgeLength = (int) ta.getDimension( 444 R.styleable.LeanbackTheme_browseRowsFadingEdgeLength, 0); 445 ta.recycle(); 446 } 447 gridView.setFadingLeftEdgeLength(mBrowseRowsFadingEdgeLength); 448 } 449 450 @Override 451 protected void onRowViewExpanded(RowPresenter.ViewHolder holder, boolean expanded) { 452 super.onRowViewExpanded(holder, expanded); 453 ViewHolder vh = (ViewHolder) holder; 454 if (getRowHeight() != getExpandedRowHeight()) { 455 int newHeight = expanded ? getExpandedRowHeight() : getRowHeight(); 456 vh.getGridView().setRowHeight(newHeight); 457 } 458 setVerticalPadding(vh); 459 updateFooterViewSwitcher(vh); 460 } 461 462 @Override 463 protected void onBindRowViewHolder(RowPresenter.ViewHolder holder, Object item) { 464 super.onBindRowViewHolder(holder, item); 465 ViewHolder vh = (ViewHolder) holder; 466 ListRow rowItem = (ListRow) item; 467 vh.mItemBridgeAdapter.setAdapter(rowItem.getAdapter()); 468 vh.mGridView.setAdapter(vh.mItemBridgeAdapter); 469 } 470 471 @Override 472 protected void onUnbindRowViewHolder(RowPresenter.ViewHolder holder) { 473 ViewHolder vh = (ViewHolder) holder; 474 vh.mGridView.setAdapter(null); 475 vh.mItemBridgeAdapter.clear(); 476 super.onUnbindRowViewHolder(holder); 477 } 478 479 /** 480 * ListRowPresenter overrides the default select effect of {@link RowPresenter} 481 * and return false. 482 */ 483 @Override 484 public final boolean isUsingDefaultSelectEffect() { 485 return false; 486 } 487 488 /** 489 * Returns true so that default select effect is applied to each individual 490 * child of {@link HorizontalGridView}. Subclass may return false to disable 491 * the default implementation. 492 * @see #onSelectLevelChanged(RowPresenter.ViewHolder) 493 */ 494 public boolean isUsingDefaultListSelectEffect() { 495 return true; 496 } 497 498 /** 499 * Returns true if SDK >= 18, where default shadow 500 * is applied to each individual child of {@link HorizontalGridView}. 501 * Subclass may return false to disable. 502 */ 503 public boolean isUsingDefaultShadow() { 504 return ShadowOverlayContainer.supportsShadow(); 505 } 506 507 /** 508 * Returns true if SDK >= L, where Z shadow is enabled so that Z order is enabled 509 * on each child of horizontal list. If subclass returns false in isUsingDefaultShadow() 510 * and does not use Z-shadow on SDK >= L, it should override isUsingZOrder() return false. 511 */ 512 public boolean isUsingZOrder() { 513 return ShadowHelper.getInstance().usesZShadow(); 514 } 515 516 /** 517 * Enable or disable child shadow. 518 * This is not only for enable/disable default shadow implementation but also subclass must 519 * respect this flag. 520 */ 521 public final void setShadowEnabled(boolean enabled) { 522 mShadowEnabled = enabled; 523 } 524 525 /** 526 * Returns true if child shadow is enabled. 527 * This is not only for enable/disable default shadow implementation but also subclass must 528 * respect this flag. 529 */ 530 public final boolean getShadowEnabled() { 531 return mShadowEnabled; 532 } 533 534 /** 535 * Enables or disabled rounded corners on children of this row. 536 * Supported on Android SDK >= L. 537 */ 538 public final void enableChildRoundedCorners(boolean enable) { 539 mRoundedCornersEnabled = enable; 540 } 541 542 /** 543 * Returns true if rounded corners are enabled for children of this row. 544 */ 545 public final boolean areChildRoundedCornersEnabled() { 546 return mRoundedCornersEnabled; 547 } 548 549 final boolean needsDefaultShadow() { 550 return isUsingDefaultShadow() && getShadowEnabled(); 551 } 552 553 @Override 554 public boolean canDrawOutOfBounds() { 555 return needsDefaultShadow(); 556 } 557 558 /** 559 * Applies select level to header and draw a default color dim over each child 560 * of {@link HorizontalGridView}. 561 * <p> 562 * Subclass may override this method. A subclass 563 * needs to call super.onSelectLevelChanged() for applying header select level 564 * and optionally applying a default select level to each child view of 565 * {@link HorizontalGridView} if {@link #isUsingDefaultListSelectEffect()} 566 * is true. Subclass may override {@link #isUsingDefaultListSelectEffect()} to return 567 * false and deal with the individual item select level by itself. 568 * </p> 569 */ 570 @Override 571 protected void onSelectLevelChanged(RowPresenter.ViewHolder holder) { 572 super.onSelectLevelChanged(holder); 573 if (needsDefaultListSelectEffect()) { 574 ViewHolder vh = (ViewHolder) holder; 575 int dimmedColor = vh.mColorDimmer.getPaint().getColor(); 576 for (int i = 0, count = vh.mGridView.getChildCount(); i < count; i++) { 577 ShadowOverlayContainer wrapper = (ShadowOverlayContainer) vh.mGridView.getChildAt(i); 578 wrapper.setOverlayColor(dimmedColor); 579 } 580 if (vh.mGridView.getFadingLeftEdge()) { 581 vh.mGridView.invalidate(); 582 } 583 } 584 } 585 586 @Override 587 public void freeze(RowPresenter.ViewHolder holder, boolean freeze) { 588 ViewHolder vh = (ViewHolder) holder; 589 vh.mGridView.setScrollEnabled(!freeze); 590 } 591 592 @Override 593 public void setEntranceTransitionState(RowPresenter.ViewHolder holder, 594 boolean afterEntrance) { 595 super.setEntranceTransitionState(holder, afterEntrance); 596 ((ViewHolder) holder).mGridView.setChildrenVisibility( 597 afterEntrance? View.VISIBLE : View.INVISIBLE); 598 } 599} 600