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