Home | History | Annotate | Download | only in launcher3
      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 
     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      */
     49     void setContentTypeImmediate(AppsCustomizePagedView.ContentType type) {
     50         mPagedView.setContentType(type);
     51     }
     52 
     53     public void setCurrentTabFromContent(AppsCustomizePagedView.ContentType type) {
     54         setContentTypeImmediate(type);
     55     }
     56 
     57     @Override
     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
     72     protected void onFinishInflate() {
     73         mPagedView = (AppsCustomizePagedView) findViewById(R.id.apps_customize_pane_content);
     74         mContent = findViewById(R.id.content);
     75     }
     76 
     77     public String getContentTag() {
     78         return getTabTagForContentType(mPagedView.getContentType());
     79     }
     80 
     81     /**
     82      * Returns the content type for the specified tab tag.
     83      */
     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      */
     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
    109     public int getDescendantFocusability() {
    110         if (getVisibility() != View.VISIBLE) {
    111             return ViewGroup.FOCUS_BLOCK_DESCENDANTS;
    112         }
    113         return super.getDescendantFocusability();
    114     }
    115 
    116     void reset() {
    117         // Reset immediately
    118         mPagedView.reset();
    119     }
    120 
    121     void trimMemory() {
    122         mPagedView.trimMemory();
    123     }
    124 
    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
    135     public ViewGroup getContent() {
    136         return mPagedView;
    137     }
    138 
    139     public boolean isInTransition() {
    140         return mInTransition;
    141     }
    142 
    143     /* LauncherTransitionable overrides */
    144     @Override
    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
    164     public void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace) {
    165         mPagedView.onLauncherTransitionStart(l, animated, toWorkspace);
    166     }
    167 
    168     @Override
    169     public void onLauncherTransitionStep(Launcher l, float t) {
    170         mPagedView.onLauncherTransitionStep(l, t);
    171     }
    172 
    173     @Override
    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 
    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