• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.launcher3;
18 
19 import android.content.Context;
20 import android.graphics.Rect;
21 import android.util.AttributeSet;
22 import android.view.View;
23 import android.view.ViewGroup;
24 import android.view.accessibility.AccessibilityManager;
25 import android.widget.FrameLayout;
26 
27 public class AppsCustomizeTabHost extends FrameLayout implements LauncherTransitionable, Insettable  {
28     static final String LOG_TAG = "AppsCustomizeTabHost";
29 
30     private static final String APPS_TAB_TAG = "APPS";
31     private static final String WIDGETS_TAB_TAG = "WIDGETS";
32 
33     private AppsCustomizePagedView mPagedView;
34     private View mContent;
35     private boolean mInTransition = false;
36 
37     private final Rect mInsets = new Rect();
38 
AppsCustomizeTabHost(Context context, AttributeSet attrs)39     public AppsCustomizeTabHost(Context context, AttributeSet attrs) {
40         super(context, attrs);
41     }
42 
43     /**
44      * Convenience methods to select specific tabs.  We want to set the content type immediately
45      * in these cases, but we note that we still call setCurrentTabByTag() so that the tab view
46      * reflects the new content (but doesn't do the animation and logic associated with changing
47      * tabs manually).
48      */
setContentTypeImmediate(AppsCustomizePagedView.ContentType type)49     void setContentTypeImmediate(AppsCustomizePagedView.ContentType type) {
50         mPagedView.setContentType(type);
51     }
52 
setCurrentTabFromContent(AppsCustomizePagedView.ContentType type)53     public void setCurrentTabFromContent(AppsCustomizePagedView.ContentType type) {
54         setContentTypeImmediate(type);
55     }
56 
57     @Override
setInsets(Rect insets)58     public void setInsets(Rect insets) {
59         mInsets.set(insets);
60         LayoutParams flp = (LayoutParams) mContent.getLayoutParams();
61         flp.topMargin = insets.top;
62         flp.bottomMargin = insets.bottom;
63         flp.leftMargin = insets.left;
64         flp.rightMargin = insets.right;
65         mContent.setLayoutParams(flp);
66     }
67 
68     /**
69      * Setup the tab host and create all necessary tabs.
70      */
71     @Override
onFinishInflate()72     protected void onFinishInflate() {
73         mPagedView = (AppsCustomizePagedView) findViewById(R.id.apps_customize_pane_content);
74         mContent = findViewById(R.id.content);
75     }
76 
getContentTag()77     public String getContentTag() {
78         return getTabTagForContentType(mPagedView.getContentType());
79     }
80 
81     /**
82      * Returns the content type for the specified tab tag.
83      */
getContentTypeForTabTag(String tag)84     public AppsCustomizePagedView.ContentType getContentTypeForTabTag(String tag) {
85         if (tag.equals(APPS_TAB_TAG)) {
86             return AppsCustomizePagedView.ContentType.Applications;
87         } else if (tag.equals(WIDGETS_TAB_TAG)) {
88             return AppsCustomizePagedView.ContentType.Widgets;
89         }
90         return AppsCustomizePagedView.ContentType.Applications;
91     }
92 
93     /**
94      * Returns the tab tag for a given content type.
95      */
getTabTagForContentType(AppsCustomizePagedView.ContentType type)96     public String getTabTagForContentType(AppsCustomizePagedView.ContentType type) {
97         if (type == AppsCustomizePagedView.ContentType.Applications) {
98             return APPS_TAB_TAG;
99         } else if (type == AppsCustomizePagedView.ContentType.Widgets) {
100             return WIDGETS_TAB_TAG;
101         }
102         return APPS_TAB_TAG;
103     }
104 
105     /**
106      * Disable focus on anything under this view in the hierarchy if we are not visible.
107      */
108     @Override
getDescendantFocusability()109     public int getDescendantFocusability() {
110         if (getVisibility() != View.VISIBLE) {
111             return ViewGroup.FOCUS_BLOCK_DESCENDANTS;
112         }
113         return super.getDescendantFocusability();
114     }
115 
reset()116     void reset() {
117         // Reset immediately
118         mPagedView.reset();
119     }
120 
trimMemory()121     void trimMemory() {
122         mPagedView.trimMemory();
123     }
124 
onWindowVisible()125     public void onWindowVisible() {
126         if (getVisibility() == VISIBLE) {
127             mContent.setVisibility(VISIBLE);
128             // We unload the widget previews when the UI is hidden, so need to reload pages
129             // Load the current page synchronously, and the neighboring pages asynchronously
130             mPagedView.loadAssociatedPages(mPagedView.getCurrentPage(), true);
131             mPagedView.loadAssociatedPages(mPagedView.getCurrentPage());
132         }
133     }
134     @Override
getContent()135     public ViewGroup getContent() {
136         return mPagedView;
137     }
138 
isInTransition()139     public boolean isInTransition() {
140         return mInTransition;
141     }
142 
143     /* LauncherTransitionable overrides */
144     @Override
onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace)145     public void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace) {
146         mPagedView.onLauncherTransitionPrepare(l, animated, toWorkspace);
147         mInTransition = true;
148 
149         if (toWorkspace) {
150             // Going from All Apps -> Workspace
151             setVisibilityOfSiblingsWithLowerZOrder(VISIBLE);
152         } else {
153             // Going from Workspace -> All Apps
154             mContent.setVisibility(VISIBLE);
155 
156             // Make sure the current page is loaded (we start loading the side pages after the
157             // transition to prevent slowing down the animation)
158             // TODO: revisit this
159             mPagedView.loadAssociatedPages(mPagedView.getCurrentPage());
160         }
161     }
162 
163     @Override
onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace)164     public void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace) {
165         mPagedView.onLauncherTransitionStart(l, animated, toWorkspace);
166     }
167 
168     @Override
onLauncherTransitionStep(Launcher l, float t)169     public void onLauncherTransitionStep(Launcher l, float t) {
170         mPagedView.onLauncherTransitionStep(l, t);
171     }
172 
173     @Override
onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace)174     public void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace) {
175         mPagedView.onLauncherTransitionEnd(l, animated, toWorkspace);
176         mInTransition = false;
177 
178         if (!toWorkspace) {
179             // Make sure adjacent pages are loaded (we wait until after the transition to
180             // prevent slowing down the animation)
181             mPagedView.loadAssociatedPages(mPagedView.getCurrentPage());
182 
183             // Opening apps, need to announce what page we are on.
184             AccessibilityManager am = (AccessibilityManager)
185                     getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
186             if (am.isEnabled()) {
187                 // Notify the user when the page changes
188                 announceForAccessibility(mPagedView.getCurrentPageDescription());
189             }
190 
191             // Going from Workspace -> All Apps
192             // NOTE: We should do this at the end since we check visibility state in some of the
193             // cling initialization/dismiss code above.
194             setVisibilityOfSiblingsWithLowerZOrder(INVISIBLE);
195         }
196     }
197 
setVisibilityOfSiblingsWithLowerZOrder(int visibility)198     private void setVisibilityOfSiblingsWithLowerZOrder(int visibility) {
199         ViewGroup parent = (ViewGroup) getParent();
200         if (parent == null) return;
201 
202         View overviewPanel = ((Launcher) getContext()).getOverviewPanel();
203         final int count = parent.getChildCount();
204         if (!isChildrenDrawingOrderEnabled()) {
205             for (int i = 0; i < count; i++) {
206                 final View child = parent.getChildAt(i);
207                 if (child == this) {
208                     break;
209                 } else {
210                     if (child.getVisibility() == GONE || child == overviewPanel) {
211                         continue;
212                     }
213                     child.setVisibility(visibility);
214                 }
215             }
216         } else {
217             throw new RuntimeException("Failed; can't get z-order of views");
218         }
219     }
220 }
221