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.view.View;
17import android.view.ViewGroup;
18
19/**
20 * An abstract helper class that switches a view in its parent view using a
21 * {@link PresenterSelector}.  A subclass should implement {@link #insertView(View)} to define
22 * how to add the view in parent, and may optionally override {@link #onViewSelected(View)}.
23 */
24public abstract class PresenterSwitcher {
25
26    private ViewGroup mParent;
27    private PresenterSelector mPresenterSelector;
28    private Presenter mCurrentPresenter;
29    private Presenter.ViewHolder mCurrentViewHolder;
30
31    /**
32     * Initializes the switcher with a parent view to insert view into and a
33     * {@link PresenterSelector} for choosing a {@link Presenter} for a given object.
34     * This will destroy any existing views.
35     */
36    public void init(ViewGroup parent, PresenterSelector presenterSelector) {
37        clear();
38        mParent = parent;
39        mPresenterSelector = presenterSelector;
40    }
41
42    /**
43     * Selects a view based on the given object and shows that view.
44     */
45    public void select(Object object) {
46        switchView(object);
47        showView(true);
48    }
49
50    /**
51     * Hides the view.
52     */
53    public void unselect() {
54        showView(false);
55    }
56
57    /**
58     * Returns the parent.
59     */
60    public final ViewGroup getParentViewGroup() {
61        return mParent;
62    }
63
64    private void showView(boolean show) {
65        if (mCurrentViewHolder != null) {
66            showView(mCurrentViewHolder.view, show);
67        }
68    }
69
70    private void switchView(Object object) {
71        Presenter presenter = mPresenterSelector.getPresenter(object);
72        if (presenter != mCurrentPresenter) {
73            showView(false);
74            clear();
75            mCurrentPresenter = presenter;
76            if (mCurrentPresenter == null) {
77                return;
78            }
79            mCurrentViewHolder = mCurrentPresenter.onCreateViewHolder(mParent);
80            insertView(mCurrentViewHolder.view);
81        } else {
82            if (mCurrentPresenter == null) {
83                return;
84            }
85            mCurrentPresenter.onUnbindViewHolder(mCurrentViewHolder);
86        }
87        mCurrentPresenter.onBindViewHolder(mCurrentViewHolder, object);
88        onViewSelected(mCurrentViewHolder.view);
89    }
90
91    protected abstract void insertView(View view);
92
93    /**
94     * Called when a view is bound to the object of {@link #select(Object)}.
95     */
96    protected void onViewSelected(View view) {
97    }
98
99    protected void showView(View view, boolean visible) {
100        view.setVisibility(visible ? View.VISIBLE : View.GONE);
101    }
102
103    /**
104     * Destroys created views.
105     */
106    public void clear() {
107        if (mCurrentPresenter != null) {
108            mCurrentPresenter.onUnbindViewHolder(mCurrentViewHolder);
109            mParent.removeView(mCurrentViewHolder.view);
110            mCurrentViewHolder = null;
111            mCurrentPresenter = null;
112        }
113    }
114
115}
116