예제 #1
0
  /**
   * Shows the migration cling.
   *
   * <p>This flow is mutually exclusive with showFirstRunCling, and only runs if this Launcher
   * package was not preinstalled and there exists a db to migrate from.
   */
  public void showMigrationCling() {
    mLauncher.hideWorkspaceSearchAndHotseat();

    ViewGroup root = (ViewGroup) mLauncher.findViewById(R.id.launcher);
    View inflated = mInflater.inflate(R.layout.migration_cling, root);
    inflated.findViewById(R.id.cling_dismiss_migration_copy_apps).setOnClickListener(this);
    inflated.findViewById(R.id.cling_dismiss_migration_use_default).setOnClickListener(this);
  }
예제 #2
0
  /** 以图标为中心,中心对齐,比如缩放时要以中心对齐 */
  private void centerAboutIcon() {
    DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();

    int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth();
    int height =
        getPaddingTop() + getPaddingBottom() + mContent.getDesiredHeight() + mFolderNameHeight;
    DragLayer parent = (DragLayer) mLauncher.findViewById(R.id.drag_layer);

    float scale = parent.getDescendantRectRelativeToSelf(mFolderIcon, mTempRect);

    int centerX = (int) (mTempRect.left + mTempRect.width() * scale / 2);
    int centerY = (int) (mTempRect.top + mTempRect.height() * scale / 2);
    int centeredLeft = centerX - width / 2;
    int centeredTop = centerY - height / 2;

    int currentPage = mLauncher.getWorkspace().getCurrentPage();
    // In case the workspace is scrolling, we need to use the final scroll
    // to compute
    // the folders bounds.
    // 如果workspace正在滚动,就强制滚动到最后以计算最终的位置
    mLauncher.getWorkspace().setFinalScrollForPageChange(currentPage);
    // We first fetch the currently visible CellLayoutChildren
    // 首先获取可见CellLayoutChildren
    CellLayout currentLayout = (CellLayout) mLauncher.getWorkspace().getChildAt(currentPage);
    ShortcutAndWidgetContainer boundingLayout = currentLayout.getShortcutsAndWidgets();
    Rect bounds = new Rect();
    parent.getDescendantRectRelativeToSelf(boundingLayout, bounds);
    // We reset the workspaces scroll
    // 强制重置workspace的滚动状态
    mLauncher.getWorkspace().resetFinalScrollForPageChange(currentPage);

    // 重新调整folder的边界,如果有需要的话,比如实际内容比folder要更大或者更小
    int left = Math.min(Math.max(bounds.left, centeredLeft), bounds.left + bounds.width() - width);
    int top = Math.min(Math.max(bounds.top, centeredTop), bounds.top + bounds.height() - height);
    // 如果实际内容比folder要更大或者更小,那么调整为实际大小
    if (width >= bounds.width()) {
      left = bounds.left + (bounds.width() - width) / 2;
    }
    if (height >= bounds.height()) {
      top = bounds.top + (bounds.height() - height) / 2;
    }

    int folderPivotX = width / 2 + (centeredLeft - left);
    int folderPivotY = height / 2 + (centeredTop - top);
    // 设置Folder的锚点
    setPivotX(folderPivotX);
    setPivotY(folderPivotY);
    mFolderIconPivotX = (int) (mFolderIcon.getMeasuredWidth() * (1.0f * folderPivotX / width));
    mFolderIconPivotY = (int) (mFolderIcon.getMeasuredHeight() * (1.0f * folderPivotY / height));

    lp.width = width;
    lp.height = height;
    lp.x = left;
    lp.y = top;
  }
  private void centerAboutIcon() {
    DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();

    DragLayer parent = (DragLayer) mLauncher.findViewById(R.id.drag_layer);
    int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth();
    int height = getFolderHeight();

    float scale = parent.getDescendantRectRelativeToSelf(mFolderIcon, mTempRect);

    LauncherAppState app = LauncherAppState.getInstance();
    DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();

    int centerX = (int) (mTempRect.left + mTempRect.width() * scale / 2);
    int centerY = (int) (mTempRect.top + mTempRect.height() * scale / 2);
    int centeredLeft = centerX - width / 2;
    int centeredTop = centerY - height / 2;
    int currentPage = mLauncher.getWorkspace().getNextPage();
    // In case the workspace is scrolling, we need to use the final scroll to compute
    // the folders bounds.
    mLauncher.getWorkspace().setFinalScrollForPageChange(currentPage);
    // We first fetch the currently visible CellLayoutChildren
    CellLayout currentLayout = (CellLayout) mLauncher.getWorkspace().getChildAt(currentPage);
    ShortcutAndWidgetContainer boundingLayout = currentLayout.getShortcutsAndWidgets();
    Rect bounds = new Rect();
    parent.getDescendantRectRelativeToSelf(boundingLayout, bounds);
    // We reset the workspaces scroll
    mLauncher.getWorkspace().resetFinalScrollForPageChange(currentPage);

    // We need to bound the folder to the currently visible CellLayoutChildren
    int left = Math.min(Math.max(bounds.left, centeredLeft), bounds.left + bounds.width() - width);
    int top = Math.min(Math.max(bounds.top, centeredTop), bounds.top + bounds.height() - height);
    if (grid.isPhone() && (grid.availableWidthPx - width) < grid.iconSizePx) {
      // Center the folder if it is full (on phones only)
      left = (grid.availableWidthPx - width) / 2;
    } else if (width >= bounds.width()) {
      // If the folder doesn't fit within the bounds, center it about the desired bounds
      left = bounds.left + (bounds.width() - width) / 2;
    }
    if (height >= bounds.height()) {
      top = bounds.top + (bounds.height() - height) / 2;
    }

    int folderPivotX = width / 2 + (centeredLeft - left);
    int folderPivotY = height / 2 + (centeredTop - top);
    setPivotX(folderPivotX);
    setPivotY(folderPivotY);
    mFolderIconPivotX = (int) (mFolderIcon.getMeasuredWidth() * (1.0f * folderPivotX / width));
    mFolderIconPivotY = (int) (mFolderIcon.getMeasuredHeight() * (1.0f * folderPivotY / height));

    lp.width = width;
    lp.height = height;
    lp.x = left;
    lp.y = top;
  }
예제 #4
0
  private void centerAboutIcon() {
    DragLayer.LayoutParams lp = (DragLayer.LayoutParams) getLayoutParams();

    int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth();
    int height =
        getPaddingTop() + getPaddingBottom() + mContent.getDesiredHeight() + mFolderNameHeight;
    DragLayer parent = (DragLayer) mLauncher.findViewById(R.id.drag_layer);

    parent.getDescendantRectRelativeToSelf(mFolderIcon, mTempRect);

    int centerX = mTempRect.centerX();
    int centerY = mTempRect.centerY();
    int centeredLeft = centerX - width / 2;
    int centeredTop = centerY - height / 2;

    // We first fetch the currently visible CellLayoutChildren
    CellLayout currentPage = mLauncher.getWorkspace().getCurrentDropLayout();
    CellLayoutChildren boundingLayout = currentPage.getChildrenLayout();
    Rect bounds = new Rect();
    parent.getDescendantRectRelativeToSelf(boundingLayout, bounds);

    // We need to bound the folder to the currently visible CellLayoutChildren
    int left = Math.min(Math.max(bounds.left, centeredLeft), bounds.left + bounds.width() - width);
    int top = Math.min(Math.max(bounds.top, centeredTop), bounds.top + bounds.height() - height);
    // If the folder doesn't fit within the bounds, center it about the desired bounds
    if (width >= bounds.width()) {
      left = bounds.left + (bounds.width() - width) / 2;
    }
    if (height >= bounds.height()) {
      top = bounds.top + (bounds.height() - height) / 2;
    }

    int folderPivotX = width / 2 + (centeredLeft - left);
    int folderPivotY = height / 2 + (centeredTop - top);
    setPivotX(folderPivotX);
    setPivotY(folderPivotY);
    int folderIconPivotX = (int) (mFolderIcon.getMeasuredWidth() * (1.0f * folderPivotX / width));
    int folderIconPivotY = (int) (mFolderIcon.getMeasuredHeight() * (1.0f * folderPivotY / height));
    mFolderIcon.setPivotX(folderIconPivotX);
    mFolderIcon.setPivotY(folderIconPivotY);

    if (mMode == PARTIAL_GROW) {
      lp.width = width;
      lp.height = height;
      lp.x = left;
      lp.y = top;
    } else {
      mNewSize.set(left, top, left + width, top + height);
    }
  }
예제 #5
0
  public void showLongPressCling(boolean showWelcome) {
    ViewGroup root = (ViewGroup) mLauncher.findViewById(R.id.launcher);
    View cling = mInflater.inflate(R.layout.longpress_cling, root, false);

    cling.setOnLongClickListener(
        new OnLongClickListener() {

          @Override
          public boolean onLongClick(View v) {
            mLauncher.getWorkspace().enterOverviewMode();
            dismissLongPressCling();
            return true;
          }
        });

    final ViewGroup content = (ViewGroup) cling.findViewById(R.id.cling_content);
    mInflater.inflate(
        showWelcome ? R.layout.longpress_cling_welcome_content : R.layout.longpress_cling_content,
        content);
    content.findViewById(R.id.cling_dismiss_longpress_info).setOnClickListener(this);

    if (TAG_CROP_TOP_AND_SIDES.equals(content.getTag())) {
      Drawable bg =
          new BorderCropDrawable(
              mLauncher.getResources().getDrawable(R.drawable.cling_bg), true, true, true, false);
      content.setBackground(bg);
    }

    root.addView(cling);

    if (showWelcome) {
      // This is the first cling being shown. No need to animate.
      return;
    }

    // Animate
    content
        .getViewTreeObserver()
        .addOnGlobalLayoutListener(
            new OnGlobalLayoutListener() {

              @Override
              public void onGlobalLayout() {
                content.getViewTreeObserver().removeOnGlobalLayoutListener(this);

                ObjectAnimator anim;
                if (TAG_CROP_TOP_AND_SIDES.equals(content.getTag())) {
                  content.setTranslationY(-content.getMeasuredHeight());
                  anim = LauncherAnimUtils.ofFloat(content, "translationY", 0);
                } else {
                  content.setScaleX(0);
                  content.setScaleY(0);
                  PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1);
                  PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1);
                  anim = LauncherAnimUtils.ofPropertyValuesHolder(content, scaleX, scaleY);
                }

                anim.setDuration(SHOW_CLING_DURATION);
                anim.setInterpolator(new LogDecelerateInterpolator(100, 0));
                anim.start();
              }
            });
  }
예제 #6
0
  public void layout(Launcher launcher) {
    FrameLayout.LayoutParams lp;
    Resources res = launcher.getResources();
    boolean hasVerticalBarLayout = isVerticalBarLayout();

    // Layout the search bar space
    View searchBar = launcher.getSearchBar();
    lp = (FrameLayout.LayoutParams) searchBar.getLayoutParams();
    if (hasVerticalBarLayout) {
      // Vertical search bar space
      lp.gravity = Gravity.TOP | Gravity.LEFT;
      lp.width = searchBarSpaceHeightPx;
      lp.height = LayoutParams.WRAP_CONTENT;

      LinearLayout targets = (LinearLayout) searchBar.findViewById(R.id.drag_target_bar);
      targets.setOrientation(LinearLayout.VERTICAL);
    } else {
      // Horizontal search bar space
      lp.gravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL;
      lp.width = searchBarSpaceWidthPx;
      lp.height = searchBarSpaceHeightPx;
    }
    searchBar.setLayoutParams(lp);

    // Layout the workspace
    PagedView workspace = (PagedView) launcher.findViewById(R.id.workspace);
    lp = (FrameLayout.LayoutParams) workspace.getLayoutParams();
    lp.gravity = Gravity.CENTER;
    int orientation = isLandscape ? CellLayout.LANDSCAPE : CellLayout.PORTRAIT;
    Rect padding = getWorkspacePadding(orientation);
    workspace.setLayoutParams(lp);
    workspace.setPadding(padding.left, padding.top, padding.right, padding.bottom);
    workspace.setPageSpacing(getWorkspacePageSpacing(orientation));

    // Layout the hotseat
    View hotseat = launcher.findViewById(R.id.hotseat);
    lp = (FrameLayout.LayoutParams) hotseat.getLayoutParams();
    if (hasVerticalBarLayout) {
      // Vertical hotseat
      lp.gravity = Gravity.END;
      lp.width = hotseatBarHeightPx;
      lp.height = LayoutParams.MATCH_PARENT;
      hotseat.findViewById(R.id.layout).setPadding(0, 2 * edgeMarginPx, 0, 2 * edgeMarginPx);
    } else if (isTablet()) {
      // Pad the hotseat with the workspace padding calculated above
      lp.gravity = Gravity.BOTTOM;
      lp.width = LayoutParams.MATCH_PARENT;
      lp.height = hotseatBarHeightPx;
      hotseat.setPadding(
          edgeMarginPx + padding.left, 0, edgeMarginPx + padding.right, 2 * edgeMarginPx);
    } else {
      // For phones, layout the hotseat without any bottom margin
      // to ensure that we have space for the folders
      lp.gravity = Gravity.BOTTOM;
      lp.width = LayoutParams.MATCH_PARENT;
      lp.height = hotseatBarHeightPx;
      hotseat.findViewById(R.id.layout).setPadding(2 * edgeMarginPx, 0, 2 * edgeMarginPx, 0);
    }
    hotseat.setLayoutParams(lp);

    // Layout the page indicators
    View pageIndicator = launcher.findViewById(R.id.page_indicator);
    if (pageIndicator != null) {
      if (hasVerticalBarLayout) {
        // Hide the page indicators when we have vertical search/hotseat
        pageIndicator.setVisibility(View.GONE);
      } else {
        // Put the page indicators above the hotseat
        lp = (FrameLayout.LayoutParams) pageIndicator.getLayoutParams();
        lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
        lp.width = LayoutParams.WRAP_CONTENT;
        lp.height = LayoutParams.WRAP_CONTENT;
        lp.bottomMargin = hotseatBarHeightPx;
        pageIndicator.setLayoutParams(lp);
      }
    }

    // Layout AllApps
    AppsCustomizeTabHost host =
        (AppsCustomizeTabHost) launcher.findViewById(R.id.apps_customize_pane);
    if (host != null) {
      // Center the all apps page indicator
      int pageIndicatorHeight =
          (int)
              (pageIndicatorHeightPx
                  * Math.min(1f, (allAppsIconSizePx / DynamicGrid.DEFAULT_ICON_SIZE_PX)));
      pageIndicator = host.findViewById(R.id.apps_customize_page_indicator);
      if (pageIndicator != null) {
        LinearLayout.LayoutParams lllp =
            (LinearLayout.LayoutParams) pageIndicator.getLayoutParams();
        lllp.width = LayoutParams.WRAP_CONTENT;
        lllp.height = pageIndicatorHeight;
        pageIndicator.setLayoutParams(lllp);
      }

      AppsCustomizePagedView pagedView =
          (AppsCustomizePagedView) host.findViewById(R.id.apps_customize_pane_content);

      FrameLayout fakePageContainer = (FrameLayout) host.findViewById(R.id.fake_page_container);
      FrameLayout fakePage = (FrameLayout) host.findViewById(R.id.fake_page);

      padding = new Rect();
      if (pagedView != null) {
        // Constrain the dimensions of all apps so that it does not span the full width
        int paddingLR =
            (availableWidthPx - (allAppsCellWidthPx * allAppsNumCols)) / (2 * (allAppsNumCols + 1));
        int paddingTB =
            (availableHeightPx - (allAppsCellHeightPx * allAppsNumRows))
                / (2 * (allAppsNumRows + 1));
        paddingLR = Math.min(paddingLR, (int) ((paddingLR + paddingTB) * 0.75f));
        paddingTB = Math.min(paddingTB, (int) ((paddingLR + paddingTB) * 0.75f));
        int maxAllAppsWidth = (allAppsNumCols * (allAppsCellWidthPx + 2 * paddingLR));
        int gridPaddingLR = (availableWidthPx - maxAllAppsWidth) / 2;
        // Only adjust the side paddings on landscape phones, or tablets
        if ((isTablet() || isLandscape) && gridPaddingLR > (allAppsCellWidthPx / 4)) {
          padding.left = padding.right = gridPaddingLR;
        }

        // The icons are centered, so we can't just offset by the page indicator height
        // because the empty space will actually be pageIndicatorHeight + paddingTB
        padding.bottom = Math.max(0, pageIndicatorHeight - paddingTB);

        pagedView.setWidgetsPageIndicatorPadding(pageIndicatorHeight);
        fakePage.setBackground(res.getDrawable(R.drawable.quantum_panel));

        // Horizontal padding for the whole paged view
        int pagedFixedViewPadding =
            res.getDimensionPixelSize(R.dimen.apps_customize_horizontal_padding);

        padding.left += pagedFixedViewPadding;
        padding.right += pagedFixedViewPadding;

        pagedView.setPadding(padding.left, padding.top, padding.right, padding.bottom);
        fakePageContainer.setPadding(padding.left, padding.top, padding.right, padding.bottom);
      }
    }

    // Layout the Overview Mode
    ViewGroup overviewMode = launcher.getOverviewPanel();
    if (overviewMode != null) {
      Rect r = getOverviewModeButtonBarRect();
      lp = (FrameLayout.LayoutParams) overviewMode.getLayoutParams();
      lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;

      int visibleChildCount = getVisibleChildCount(overviewMode);
      int totalItemWidth = visibleChildCount * overviewModeBarItemWidthPx;
      int maxWidth = totalItemWidth + (visibleChildCount - 1) * overviewModeBarSpacerWidthPx;

      lp.width = Math.min(availableWidthPx, maxWidth);
      lp.height = r.height();
      overviewMode.setLayoutParams(lp);

      if (lp.width > totalItemWidth && visibleChildCount > 1) {
        // We have enough space. Lets add some margin too.
        int margin = (lp.width - totalItemWidth) / (visibleChildCount - 1);
        View lastChild = null;

        // Set margin of all visible children except the last visible child
        for (int i = 0; i < visibleChildCount; i++) {
          if (lastChild != null) {
            MarginLayoutParams clp = (MarginLayoutParams) lastChild.getLayoutParams();
            if (isLayoutRtl) {
              clp.leftMargin = margin;
            } else {
              clp.rightMargin = margin;
            }
            lastChild.setLayoutParams(clp);
            lastChild = null;
          }
          View thisChild = overviewMode.getChildAt(i);
          if (thisChild.getVisibility() != View.GONE) {
            lastChild = thisChild;
          }
        }
      }
    }
  }