AppsCustomizeTabHost.java revision 39e5d176e6e375e7ae46d42ed14412d54cb223c9
1785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung/*
2785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * Copyright (C) 2011 The Android Open Source Project
3785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung *
4785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * Licensed under the Apache License, Version 2.0 (the "License");
5785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * you may not use this file except in compliance with the License.
6785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * You may obtain a copy of the License at
7785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung *
8785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung *      http://www.apache.org/licenses/LICENSE-2.0
9785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung *
10785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * Unless required by applicable law or agreed to in writing, software
11785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * distributed under the License is distributed on an "AS IS" BASIS,
12785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * See the License for the specific language governing permissions and
14785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung * limitations under the License.
15785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung */
16785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
17785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungpackage com.android.launcher2;
18785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
19f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chungimport android.animation.Animator;
20b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chungimport android.animation.AnimatorListenerAdapter;
21f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chungimport android.animation.AnimatorSet;
22b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chungimport android.animation.ObjectAnimator;
23785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.content.Context;
24785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.content.res.Resources;
25785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.util.AttributeSet;
26785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.view.LayoutInflater;
274179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chungimport android.view.MotionEvent;
28785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.view.View;
29785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.view.ViewGroup;
30141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurkaimport android.widget.FrameLayout;
311899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurkaimport android.widget.LinearLayout;
32785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.widget.TabHost;
33faa13255de0fb1d581ec7a583ed6ef0b661dbea0Winson Chungimport android.widget.TabWidget;
34785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport android.widget.TextView;
35785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
36785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungimport com.android.launcher.R;
37785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
38141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurkaimport java.util.ArrayList;
39141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka
40785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chungpublic class AppsCustomizeTabHost extends TabHost implements LauncherTransitionable,
41785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        TabHost.OnTabChangeListener  {
42785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    static final String LOG_TAG = "AppsCustomizeTabHost";
43785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
44785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    private static final String APPS_TAB_TAG = "APPS";
45785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    private static final String WIDGETS_TAB_TAG = "WIDGETS";
46785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
47785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    private final LayoutInflater mLayoutInflater;
48f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung    private ViewGroup mTabs;
49fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung    private ViewGroup mTabsContainer;
504179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung    private AppsCustomizePagedView mAppsCustomizePane;
510cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen    private boolean mSuppressContentCallback = false;
52141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka    private FrameLayout mAnimationBuffer;
531899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka    private LinearLayout mContent;
54785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
55c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung    private boolean mInTransition;
567044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung    private boolean mTransitioningToWorkspace;
57c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung    private boolean mResetAfterTransition;
586cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka    private Runnable mRelayoutAndMakeVisible;
59c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung
60785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    public AppsCustomizeTabHost(Context context, AttributeSet attrs) {
61785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        super(context, attrs);
62785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        mLayoutInflater = LayoutInflater.from(context);
636cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka        mRelayoutAndMakeVisible = new Runnable() {
646cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka                public void run() {
656cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka                    mTabs.requestLayout();
666cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka                    mTabsContainer.setAlpha(1f);
676cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka                }
686cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka            };
69785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    }
70785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
71f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung    /**
725a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung     * Convenience methods to select specific tabs.  We want to set the content type immediately
735a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung     * in these cases, but we note that we still call setCurrentTabByTag() so that the tab view
745a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung     * reflects the new content (but doesn't do the animation and logic associated with changing
755a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung     * tabs manually).
76f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung     */
775a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung    private void setContentTypeImmediate(AppsCustomizePagedView.ContentType type) {
785a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung        onTabChangedStart();
795a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung        onTabChangedEnd(type);
805a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung    }
8155b6550e37da5df2fda44fc712bc082731f2d8e7Winson Chung    void selectAppsTab() {
825a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung        setContentTypeImmediate(AppsCustomizePagedView.ContentType.Applications);
8355b6550e37da5df2fda44fc712bc082731f2d8e7Winson Chung        setCurrentTabByTag(APPS_TAB_TAG);
8455b6550e37da5df2fda44fc712bc082731f2d8e7Winson Chung    }
8555b6550e37da5df2fda44fc712bc082731f2d8e7Winson Chung    void selectWidgetsTab() {
865a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung        setContentTypeImmediate(AppsCustomizePagedView.ContentType.Widgets);
875a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung        setCurrentTabByTag(WIDGETS_TAB_TAG);
885a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung    }
8955b6550e37da5df2fda44fc712bc082731f2d8e7Winson Chung
90785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    /**
91785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung     * Setup the tab host and create all necessary tabs.
92785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung     */
93785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    @Override
94785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    protected void onFinishInflate() {
95785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        // Setup the tab host
96785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        setup();
97785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
98fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung        final ViewGroup tabsContainer = (ViewGroup) findViewById(R.id.tabs_container);
99faa13255de0fb1d581ec7a583ed6ef0b661dbea0Winson Chung        final TabWidget tabs = (TabWidget) findViewById(com.android.internal.R.id.tabs);
1004179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung        final AppsCustomizePagedView appsCustomizePane = (AppsCustomizePagedView)
101785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung                findViewById(R.id.apps_customize_pane_content);
102f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        mTabs = tabs;
103fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung        mTabsContainer = tabsContainer;
1044179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung        mAppsCustomizePane = appsCustomizePane;
105141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka        mAnimationBuffer = (FrameLayout) findViewById(R.id.animation_buffer);
1061899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka        mContent = (LinearLayout) findViewById(R.id.apps_customize_content);
1074179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung        if (tabs == null || mAppsCustomizePane == null) throw new Resources.NotFoundException();
108785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
109785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        // Configure the tabs content factory to return the same paged view (that we change the
110785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        // content filter on)
111785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        TabContentFactory contentFactory = new TabContentFactory() {
112785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung            public View createTabContent(String tag) {
1134179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung                return appsCustomizePane;
114785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung            }
115785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        };
116785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
117785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        // Create the tabs
118785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        TextView tabView;
119d2c1f80aa73bef9d7fb5991ec29ea7a7b2e38f90Winson Chung        String label;
120d2c1f80aa73bef9d7fb5991ec29ea7a7b2e38f90Winson Chung        label = mContext.getString(R.string.all_apps_button_label);
121785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        tabView = (TextView) mLayoutInflater.inflate(R.layout.tab_widget_indicator, tabs, false);
122d2c1f80aa73bef9d7fb5991ec29ea7a7b2e38f90Winson Chung        tabView.setText(label);
123d2c1f80aa73bef9d7fb5991ec29ea7a7b2e38f90Winson Chung        tabView.setContentDescription(label);
124785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        addTab(newTabSpec(APPS_TAB_TAG).setIndicator(tabView).setContent(contentFactory));
125d2c1f80aa73bef9d7fb5991ec29ea7a7b2e38f90Winson Chung        label = mContext.getString(R.string.widgets_tab_label);
126785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        tabView = (TextView) mLayoutInflater.inflate(R.layout.tab_widget_indicator, tabs, false);
127d2c1f80aa73bef9d7fb5991ec29ea7a7b2e38f90Winson Chung        tabView.setText(label);
128d2c1f80aa73bef9d7fb5991ec29ea7a7b2e38f90Winson Chung        tabView.setContentDescription(label);
129785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        addTab(newTabSpec(WIDGETS_TAB_TAG).setIndicator(tabView).setContent(contentFactory));
130785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        setOnTabChangedListener(this);
131faa13255de0fb1d581ec7a583ed6ef0b661dbea0Winson Chung
132faa13255de0fb1d581ec7a583ed6ef0b661dbea0Winson Chung        // Setup the key listener to jump between the last tab view and the market icon
133faa13255de0fb1d581ec7a583ed6ef0b661dbea0Winson Chung        AppsCustomizeTabKeyEventListener keyListener = new AppsCustomizeTabKeyEventListener();
134faa13255de0fb1d581ec7a583ed6ef0b661dbea0Winson Chung        View lastTab = tabs.getChildTabViewAt(tabs.getTabCount() - 1);
135faa13255de0fb1d581ec7a583ed6ef0b661dbea0Winson Chung        lastTab.setOnKeyListener(keyListener);
136faa13255de0fb1d581ec7a583ed6ef0b661dbea0Winson Chung        View shopButton = findViewById(R.id.market_button);
137faa13255de0fb1d581ec7a583ed6ef0b661dbea0Winson Chung        shopButton.setOnKeyListener(keyListener);
138fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung
139fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung        // Hide the tab bar until we measure
140fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung        mTabsContainer.setAlpha(0f);
141f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung    }
142785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
143f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung    @Override
144f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
145f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        boolean remeasureTabWidth = (mTabs.getLayoutParams().width <= 0);
146f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
147f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung
148f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        // Set the width of the tab list to the content width
149f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        if (remeasureTabWidth) {
150fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung            int contentWidth = mAppsCustomizePane.getPageContentWidth();
151141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka            if (contentWidth > 0 && mTabs.getLayoutParams().width != contentWidth) {
152141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                // Set the width and show the tab bar
153fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung                mTabs.getLayoutParams().width = contentWidth;
1546cfafb96c3b108fec90897c1a251229be9861ddbMichael Jurka                post(mRelayoutAndMakeVisible);
155fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung            }
156f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        }
157fd3385fe9e0f034b04f99d5d59a58d74fe040da4Winson Chung        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
1584179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung    }
1594179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung
1607044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung     public boolean onInterceptTouchEvent(MotionEvent ev) {
1617044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung         // If we are mid transition then intercept touch events here so we can ignore them
1627044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung         if (mInTransition) {
1637044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung             return true;
1647044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung         }
1657044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung         return super.onInterceptTouchEvent(ev);
1667044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung     };
1677044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung
1684179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung    @Override
1694179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung    public boolean onTouchEvent(MotionEvent event) {
1707044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung        // Allow touch events to fall through if we are transitioning to the workspace
1717044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung        if (mInTransition) {
1727044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung            if (mTransitioningToWorkspace) {
1737044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung                return super.onTouchEvent(event);
1747044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung            }
1757044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung        }
1767044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung
1774179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung        // Intercept all touch events up to the bottom of the AppsCustomizePane so they do not fall
1784179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung        // through to the workspace and trigger showWorkspace()
1794179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung        if (event.getY() < mAppsCustomizePane.getBottom()) {
1804179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung            return true;
1814179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung        }
1824179b4e048dd019daca053dc3a7eddf6c464b08bWinson Chung        return super.onTouchEvent(event);
183785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    }
184785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
1855a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung    private void onTabChangedStart() {
1865a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung        mAppsCustomizePane.hideScrollingIndicator(false);
1875a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung    }
1880cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen
189097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung    private void reloadCurrentPage() {
190097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung        if (!LauncherApplication.isScreenLarge()) {
191b737ee6ab2dc4938a1b2a574c336af0eab826712Michael Jurka            mAppsCustomizePane.flashScrollingIndicator(true);
192097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung        }
193097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung        mAppsCustomizePane.loadAssociatedPages(mAppsCustomizePane.getCurrentPage());
194097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung        mAppsCustomizePane.requestFocus();
195097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung    }
196097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung
1975a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung    private void onTabChangedEnd(AppsCustomizePagedView.ContentType type) {
1985a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung        mAppsCustomizePane.setContentType(type);
1995a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung    }
2005a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung
201785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    @Override
202785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    public void onTabChanged(String tabId) {
203b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung        final AppsCustomizePagedView.ContentType type = getContentTypeForTabTag(tabId);
2040cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen        if (mSuppressContentCallback) {
2050cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen            mSuppressContentCallback = false;
2060cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen            return;
207b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung        }
208b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung
2090cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen        // Animate the changing of the tab content by fading pages in and out
2100cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen        final Resources res = getResources();
2110cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen        final int duration = res.getInteger(R.integer.config_tabTransitionDuration);
212f314b0eab03bb354c14b6c89f694a6685bd246d9Winson Chung
2130cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen        // We post a runnable here because there is a delay while the first page is loading and
2140cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen        // the feedback from having changed the tab almost feels better than having it stick
2150cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen        post(new Runnable() {
2160cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen            @Override
2170cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen            public void run() {
218097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung                if (mAppsCustomizePane.getMeasuredWidth() <= 0 ||
219097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung                        mAppsCustomizePane.getMeasuredHeight() <= 0) {
220097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung                    reloadCurrentPage();
221097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung                    return;
222097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung                }
223097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung
224141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                // Take the visible pages and re-parent them temporarily to mAnimatorBuffer
225141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                // and then cross fade to the new pages
226c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                int[] visiblePageRange = new int[2];
227c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                mAppsCustomizePane.getVisiblePages(visiblePageRange);
228c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                if (visiblePageRange[0] == -1 && visiblePageRange[1] == -1) {
229c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                    // If we can't get the visible page ranges, then just skip the animation
230c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                    reloadCurrentPage();
231c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                    return;
232c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                }
233c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                ArrayList<View> visiblePages = new ArrayList<View>();
234c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                for (int i = visiblePageRange[0]; i <= visiblePageRange[1]; i++) {
235c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                    visiblePages.add(mAppsCustomizePane.getPageAt(i));
236c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                }
237141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka
238141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                // We want the pages to be rendered in exactly the same way as they were when
239141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                // their parent was mAppsCustomizePane -- so set the scroll on mAnimationBuffer
240141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                // to be exactly the same as mAppsCustomizePane, and below, set the left/top
241141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                // parameters to be correct for each of the pages
242141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                mAnimationBuffer.scrollTo(mAppsCustomizePane.getScrollX(), 0);
243141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka
244141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                // mAppsCustomizePane renders its children in reverse order, so
245141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                // add the pages to mAnimationBuffer in reverse order to match that behavior
246141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                for (int i = visiblePages.size() - 1; i >= 0; i--) {
247141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    View child = visiblePages.get(i);
248c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                    if (child instanceof PagedViewCellLayout) {
249c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                        ((PagedViewCellLayout) child).resetChildrenOnKeyListeners();
250c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                    } else if (child instanceof PagedViewGridLayout) {
251c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                        ((PagedViewGridLayout) child).resetChildrenOnKeyListeners();
252c6f10b906fc9c120cafc81046a42b2434ff635a9Winson Chung                    }
253141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    PagedViewWidget.setDeletePreviewsWhenDetachedFromWindow(false);
254141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    mAppsCustomizePane.removeView(child);
255141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    PagedViewWidget.setDeletePreviewsWhenDetachedFromWindow(true);
256141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    mAnimationBuffer.setAlpha(1f);
257141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    mAnimationBuffer.setVisibility(View.VISIBLE);
258141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    LayoutParams p = new FrameLayout.LayoutParams(child.getWidth(),
259141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                            child.getHeight());
260141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    p.setMargins((int) child.getLeft(), (int) child.getTop(), 0, 0);
261141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    mAnimationBuffer.addView(child, p);
262141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                }
263b44b52439d155f570db7d6d0b80fdd3350e35685Winson Chung
2640cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                // Toggle the new content
2650cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                onTabChangedStart();
2660cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                onTabChangedEnd(type);
2670cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen
2680cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                // Animate the transition
2690cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                ObjectAnimator outAnim = ObjectAnimator.ofFloat(mAnimationBuffer, "alpha", 0f);
2700cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                outAnim.addListener(new AnimatorListenerAdapter() {
2710cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                    @Override
2720cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                    public void onAnimationEnd(Animator animation) {
2730cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                        mAnimationBuffer.setVisibility(View.GONE);
274141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                        mAnimationBuffer.removeAllViews();
275141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    }
276141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    @Override
277141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                    public void onAnimationCancel(Animator animation) {
278141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                        mAnimationBuffer.setVisibility(View.GONE);
279141dbd0e02f9fd9f3a096722d8d812990b5931e1Michael Jurka                        mAnimationBuffer.removeAllViews();
2800cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                    }
2810cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                });
2820cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                ObjectAnimator inAnim = ObjectAnimator.ofFloat(mAppsCustomizePane, "alpha", 1f);
2830cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                inAnim.addListener(new AnimatorListenerAdapter() {
2840cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                    @Override
2850cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                    public void onAnimationEnd(Animator animation) {
286097e6c71b12ad1fdc9beba5f74c466521508df9dWinson Chung                        reloadCurrentPage();
2870cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                    }
2880cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                });
2890cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                AnimatorSet animSet = new AnimatorSet();
2900cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                animSet.playTogether(outAnim, inAnim);
2910cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                animSet.setDuration(duration);
2920cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen                animSet.start();
2930cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen            }
2940cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen        });
2950cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen    }
2960cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen
2970cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen    public void setCurrentTabFromContent(AppsCustomizePagedView.ContentType type) {
2980cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen        mSuppressContentCallback = true;
2990cd3b64e607cc1f81ed49b00ef7398c2a2b7a48dAdam Cohen        setCurrentTabByTag(getTabTagForContentType(type));
300785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    }
301785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
302785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    /**
303785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung     * Returns the content type for the specified tab tag.
304785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung     */
305785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    public AppsCustomizePagedView.ContentType getContentTypeForTabTag(String tag) {
306785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        if (tag.equals(APPS_TAB_TAG)) {
307785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung            return AppsCustomizePagedView.ContentType.Applications;
308785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        } else if (tag.equals(WIDGETS_TAB_TAG)) {
309785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung            return AppsCustomizePagedView.ContentType.Widgets;
310785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        }
311785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        return AppsCustomizePagedView.ContentType.Applications;
312785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    }
313785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
314785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    /**
315fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung     * Returns the tab tag for a given content type.
316fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung     */
317fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung    public String getTabTagForContentType(AppsCustomizePagedView.ContentType type) {
318fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung        if (type == AppsCustomizePagedView.ContentType.Applications) {
319fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung            return APPS_TAB_TAG;
320fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung        } else if (type == AppsCustomizePagedView.ContentType.Widgets) {
321fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung            return WIDGETS_TAB_TAG;
322fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung        }
323fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung        return APPS_TAB_TAG;
324fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung    }
325fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung
326fc79c8067e21e55fce3802a63e15ee4c6f11d595Winson Chung    /**
327785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung     * Disable focus on anything under this view in the hierarchy if we are not visible.
328785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung     */
329785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    @Override
330785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    public int getDescendantFocusability() {
331785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        if (getVisibility() != View.VISIBLE) {
332785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung            return ViewGroup.FOCUS_BLOCK_DESCENDANTS;
333785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        }
334785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung        return super.getDescendantFocusability();
335785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    }
336785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung
337c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung    void reset() {
338c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung        if (mInTransition) {
339c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung            // Defer to after the transition to reset
340c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung            mResetAfterTransition = true;
341c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung        } else {
342c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung            // Reset immediately
343c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung            mAppsCustomizePane.reset();
344c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung        }
345c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung    }
346c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung
3471899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka    private void enableAndBuildHardwareLayer() {
34819e0fc53c43a7746d7ae3d7c6027166bded33f0fMichael Jurka        // isHardwareAccelerated() checks if we're attached to a window and if that
34919e0fc53c43a7746d7ae3d7c6027166bded33f0fMichael Jurka        // window is HW accelerated-- we were sometimes not attached to a window
35019e0fc53c43a7746d7ae3d7c6027166bded33f0fMichael Jurka        // and buildLayer was throwing an IllegalStateException
3511899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka        if (isHardwareAccelerated()) {
352f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung            // Turn on hardware layers for performance
353f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung            setLayerType(LAYER_TYPE_HARDWARE, null);
354f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung
3551899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka            // force building the layer, so you don't get a blip early in an animation
3561899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka            // when the layer is created layer
357f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung            buildLayer();
35839e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka
35939e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka            // Let the GC system know that now is a good time to do any garbage
36039e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka            // collection; makes it less likely we'll get a GC during the all apps
36139e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka            // to workspace animation
36239e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka            System.gc();
363f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        }
3641899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka    }
3651899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka
3662a4b1a809c6bc0af9ae3ad974fe50e2a91569543Michael Jurka    @Override
3672a4b1a809c6bc0af9ae3ad974fe50e2a91569543Michael Jurka    public View getContent() {
3682a4b1a809c6bc0af9ae3ad974fe50e2a91569543Michael Jurka        return mContent;
3691899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka    }
3701899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka
3711899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka    /* LauncherTransitionable overrides */
3721899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka    @Override
373bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka    public void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace) {
37439e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka        mAppsCustomizePane.onLauncherTransitionStart(l, animated, toWorkspace);
3751899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka        mInTransition = true;
3767044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung        mTransitioningToWorkspace = toWorkspace;
3771899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka
378bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        if (toWorkspace) {
379bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            // Going from All Apps -> Workspace
380bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            setVisibilityOfSiblingsWithLowerZOrder(VISIBLE);
381a8352d22afd3b78ab01ded90ad1674599100fda5Michael Jurka            // Stop the scrolling indicator - we don't want All Apps to be invalidating itself
382a8352d22afd3b78ab01ded90ad1674599100fda5Michael Jurka            // during the transition, especially since it has a hardware layer set on it
383a8352d22afd3b78ab01ded90ad1674599100fda5Michael Jurka            mAppsCustomizePane.cancelScrollingIndicatorAnimations();
384bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        } else {
385bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            // Going from Workspace -> All Apps
386bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            mContent.setVisibility(VISIBLE);
3873d845e8d8921eebe0b072b7856b660b4350921e1Michael Jurka
388e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            // Make sure the current page is loaded (we start loading the side pages after the
389e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            // transition to prevent slowing down the animation)
390e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            mAppsCustomizePane.loadAssociatedPages(mAppsCustomizePane.getCurrentPage(), true);
3911899a36ab3aab7671420511f47eb8b273b9b1078Michael Jurka
392bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            if (!LauncherApplication.isScreenLarge()) {
393bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka                mAppsCustomizePane.showScrollingIndicator(true);
394bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            }
395430e8a5f5b06181addfd37223518fc21c5c41b69Michael Jurka        }
396bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka
397c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung        if (mResetAfterTransition) {
398c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung            mAppsCustomizePane.reset();
399c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung            mResetAfterTransition = false;
400c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung        }
401bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka
402bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        if (animated) {
403bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            enableAndBuildHardwareLayer();
404bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        }
405785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    }
406f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung
407785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    @Override
4087044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung    public void onLauncherTransitionStep(Launcher l, float t) {
4097044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung        // Do nothing
4107044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung    }
4117044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung
4127044272f180d34ab29866f6c59ee75376e8a1df5Winson Chung    @Override
413bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka    public void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace) {
41439e5d176e6e375e7ae46d42ed14412d54cb223c9Michael Jurka        mAppsCustomizePane.onLauncherTransitionEnd(l, animated, toWorkspace);
415c100e8eae7d67ad5bd78767494b62b8fae5d1779Winson Chung        mInTransition = false;
416bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        if (animated) {
417f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung            setLayerType(LAYER_TYPE_NONE, null);
418f0ea4d3378be7b962c8e0bce2392df5e82491fb8Winson Chung        }
4193ac74c55cf8baef29db80e8c67ab4ab033b04417Winson Chung
4207d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung        if (!toWorkspace) {
421bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            // Going from Workspace -> All Apps
422bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            setVisibilityOfSiblingsWithLowerZOrder(INVISIBLE);
423bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka
4243f4e1423804d64a38cb69e4511d7b80783564827Winson Chung            // Dismiss the workspace cling and show the all apps cling (if not already shown)
4257d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung            l.dismissWorkspaceCling(null);
4263f4e1423804d64a38cb69e4511d7b80783564827Winson Chung            mAppsCustomizePane.showAllAppsCling();
427e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            // Make sure adjacent pages are loaded (we wait until after the transition to
428e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            // prevent slowing down the animation)
429e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            mAppsCustomizePane.loadAssociatedPages(mAppsCustomizePane.getCurrentPage());
4307d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung
4317d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung            if (!LauncherApplication.isScreenLarge()) {
4327d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung                mAppsCustomizePane.hideScrollingIndicator(false);
4337d7541e7b48fdc114c24b3b0aa75e70d7228041eWinson Chung            }
4345a808358f1a773dab8babae44899ffd4ed1810c1Winson Chung        }
435785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung    }
43670d721061536e0634f6cfa8cd219759a83befceeWinson Chung
437bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka    private void setVisibilityOfSiblingsWithLowerZOrder(int visibility) {
438bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        ViewGroup parent = (ViewGroup) getParent();
439bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        final int count = parent.getChildCount();
440bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        if (!isChildrenDrawingOrderEnabled()) {
441bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            for (int i = 0; i < count; i++) {
442bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka                final View child = parent.getChildAt(i);
443bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka                if (child == this) {
444bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka                    break;
445bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka                } else {
446bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka                    if (child.getVisibility() == GONE) {
447bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka                        continue;
448bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka                    }
449bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka                    child.setVisibility(visibility);
450bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka                }
451bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            }
452bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        } else {
453bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka            throw new RuntimeException("Failed; can't get z-order of views");
454bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka        }
455bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka    }
456bed61d22bdbfcdbe04f92675c7751b83c7a8947cMichael Jurka
4572a4b1a809c6bc0af9ae3ad974fe50e2a91569543Michael Jurka    public void onWindowVisible() {
458e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka        if (getVisibility() == VISIBLE) {
459e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            mContent.setVisibility(VISIBLE);
460e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            // We unload the widget previews when the UI is hidden, so need to reload pages
461e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            // Load the current page synchronously, and the neighboring pages asynchronously
462e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            mAppsCustomizePane.loadAssociatedPages(mAppsCustomizePane.getCurrentPage(), true);
463e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka            mAppsCustomizePane.loadAssociatedPages(mAppsCustomizePane.getCurrentPage());
464e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka        }
465e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka    }
466e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka
467e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka    public void onTrimMemory() {
468e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka        mContent.setVisibility(GONE);
469e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka        // Clear the widget pages of all their subviews - this will trigger the widget previews
470e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka        // to delete their bitmaps
471e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka        mAppsCustomizePane.clearAllWidgetPages();
472e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka    }
473e326f186af6b00e4ea32849f1527254c669d0600Michael Jurka
47470d721061536e0634f6cfa8cd219759a83befceeWinson Chung    boolean isTransitioning() {
47570d721061536e0634f6cfa8cd219759a83befceeWinson Chung        return mInTransition;
47670d721061536e0634f6cfa8cd219759a83befceeWinson Chung    }
477785d2eb2b8d7072c8124300dd9168ff51a91cf38Winson Chung}
478