// This method keeps track of the last item in the folder for the purposes
 // of keyboard focus
 private void updateTextViewFocus() {
   View lastChild = getItemAt(getItemCount() - 1);
   getItemAt(getItemCount() - 1);
   if (lastChild != null) {
     mFolderName.setNextFocusDownId(lastChild.getId());
     mFolderName.setNextFocusRightId(lastChild.getId());
     mFolderName.setNextFocusLeftId(lastChild.getId());
     mFolderName.setNextFocusUpId(lastChild.getId());
   }
 }
예제 #2
0
  @Override
  protected void onFinishInflate() {
    super.onFinishInflate();
    mContent = (CellLayout) findViewById(R.id.folder_content);
    mContent.setGridSize(0, 0);
    mContent.getShortcutsAndWidgets().setMotionEventSplittingEnabled(false);
    mFolderName = (FolderEditText) findViewById(R.id.folder_name);
    mFolderName.setFolder(this);
    mFolderName.setOnFocusChangeListener(this);

    // 算出TextView最终需要多大,以便可以给它腾出适合大小的地方
    int measureSpec = MeasureSpec.UNSPECIFIED;
    mFolderName.measure(measureSpec, measureSpec);
    mFolderNameHeight = mFolderName.getMeasuredHeight();

    // We disable action mode for now since it messes up the view on phones
    // 暂时禁止action mode,因为它有可能会情致view混乱
    mFolderName.setCustomSelectionActionModeCallback(mActionModeCallback);
    mFolderName.setOnEditorActionListener(this);
    mFolderName.setSelectAllOnFocus(true);
    mFolderName.setInputType(
        mFolderName.getInputType()
            | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
            | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
  }
예제 #3
0
  @Override
  protected void onFinishInflate() {
    super.onFinishInflate();
    mContent = (CellLayout) findViewById(R.id.folder_content);
    mContent.setGridSize(0, 0);
    mContent.getChildrenLayout().setMotionEventSplittingEnabled(false);
    mFolderName = (FolderEditText) findViewById(R.id.folder_name);
    mFolderName.setFolder(this);
    mFolderName.setOnFocusChangeListener(this);

    // We find out how tall the text view wants to be (it is set to wrap_content), so that
    // we can allocate the appropriate amount of space for it.
    int measureSpec = MeasureSpec.UNSPECIFIED;
    mFolderName.measure(measureSpec, measureSpec);
    mFolderNameHeight = mFolderName.getMeasuredHeight();

    // We disable action mode for now since it messes up the view on phones
    mFolderName.setCustomSelectionActionModeCallback(mActionModeCallback);
    mFolderName.setOnEditorActionListener(this);
    mFolderName.setSelectAllOnFocus(true);
    mFolderName.setInputType(
        mFolderName.getInputType()
            | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
            | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
  }
  void bind(FolderInfo info) {
    mInfo = info;
    ArrayList<ShortcutInfo> children = info.contents;
    ArrayList<ShortcutInfo> overflow = new ArrayList<ShortcutInfo>();
    setupContentForNumItems(children.size());
    placeInReadingOrder(children);
    int count = 0;
    for (int i = 0; i < children.size(); i++) {
      ShortcutInfo child = (ShortcutInfo) children.get(i);
      if (createAndAddShortcut(child) == null) {
        overflow.add(child);
      } else {
        count++;
      }
    }

    // We rearrange the items in case there are any empty gaps
    setupContentForNumItems(count);

    // If our folder has too many items we prune them from the list. This is an issue
    // when upgrading from the old Folders implementation which could contain an unlimited
    // number of items.
    for (ShortcutInfo item : overflow) {
      mInfo.remove(item);
      LauncherModel.deleteItemFromDatabase(mLauncher, item);
    }

    mItemsInvalidated = true;
    updateTextViewFocus();
    mInfo.addListener(this);

    if (!sDefaultFolderName.contentEquals(mInfo.title)) {
      mFolderName.setText(mInfo.title);
    } else {
      mFolderName.setText("");
    }
    updateItemLocationsInDatabase();

    // In case any children didn't come across during loading, clean up the folder accordingly
    mFolderIcon.post(
        new Runnable() {
          public void run() {
            if (getItemCount() <= 1) {
              replaceFolderWithFinalItem();
            }
          }
        });
  }
예제 #5
0
  void bind(FolderInfo info) {
    mInfo = info;
    ArrayList<ShortcutInfo> children = info.contents;
    ArrayList<ShortcutInfo> overflow = new ArrayList<ShortcutInfo>(); // 超出数量的item
    setupContentForNumItems(children.size());
    placeInReadingOrder(children);
    int count = 0;
    for (int i = 0; i < children.size(); i++) {
      ShortcutInfo child = (ShortcutInfo) children.get(i);
      if (!createAndAddShortcut(child)) {
        overflow.add(child);
      } else {
        count++;
      }
    }

    // 重新排序以防止有空的间隔。应该是防止万一数据有不对。
    setupContentForNumItems(count);

    // If our folder has too many items we prune them from the list. This is
    // an issue
    // when upgrading from the old Folders implementation which could
    // contain an unlimited
    // number of items.
    // 如果文件夹里面有太多项目的话,我们把他们从list里面删掉。
    // 因为从以前版本的数据库升级的时候有可能会出现许许多多的item(以前没有限制?)
    for (ShortcutInfo item : overflow) {
      mInfo.remove(item);
      LauncherModel.deleteItemFromDatabase(mLauncher, item);
    }

    mItemsInvalidated = true;
    updateTextViewFocus();
    mInfo.addListener(this);

    if (!sDefaultFolderName.contentEquals(mInfo.title)) {
      mFolderName.setText(mInfo.title);
    } else {
      mFolderName.setText("");
    }
    updateItemLocationsInDatabase(); // 更新数据库里面的位置,万一以前里面的有错误(也太小心了……)
  }
  public void doneEditingFolderName(boolean commit) {
    mFolderName.setHint(sHintText);
    // Convert to a string here to ensure that no other state associated with the text field
    // gets saved.
    String newTitle = mFolderName.getText().toString();
    mInfo.setTitle(newTitle);
    LauncherModel.updateItemInDatabase(mLauncher, mInfo);

    if (commit) {
      sendCustomAccessibilityEvent(
          AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
          String.format(getContext().getString(R.string.folder_renamed), newTitle));
    }
    // In order to clear the focus from the text field, we set the focus on ourself. This
    // ensures that every time the field is clicked, focus is gained, giving reliable behavior.
    requestFocus();

    Selection.setSelection((Spannable) mFolderName.getText(), 0, 0);
    mIsEditingName = false;
  }
예제 #7
0
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth();
    int height =
        getPaddingTop() + getPaddingBottom() + mContent.getDesiredHeight() + mFolderNameHeight;

    int contentWidthSpec =
        MeasureSpec.makeMeasureSpec(mContent.getDesiredWidth(), MeasureSpec.EXACTLY);
    int contentHeightSpec =
        MeasureSpec.makeMeasureSpec(mContent.getDesiredHeight(), MeasureSpec.EXACTLY);
    mContent.measure(contentWidthSpec, contentHeightSpec);

    mFolderName.measure(
        contentWidthSpec, MeasureSpec.makeMeasureSpec(mFolderNameHeight, MeasureSpec.EXACTLY));
    setMeasuredDimension(width, height);
  }
예제 #8
0
  void bind(FolderInfo info) {
    mInfo = info;
    ArrayList<ShortcutInfo> children = info.contents;
    ArrayList<ShortcutInfo> overflow = new ArrayList<ShortcutInfo>();
    setupContentForNumItems(children.size());
    int count = 0;
    for (int i = 0; i < children.size(); i++) {
      ShortcutInfo child = (ShortcutInfo) children.get(i);
      if (!createAndAddShortcut(child)) {
        overflow.add(child);
      } else {
        count++;
      }
    }

    // We rearrange the items in case there are any empty gaps
    setupContentForNumItems(count);

    // If our folder has too many items we prune them from the list. This is an issue
    // when upgrading from the old Folders implementation which could contain an unlimited
    // number of items.
    for (ShortcutInfo item : overflow) {
      mInfo.remove(item);
      LauncherModel.deleteItemFromDatabase(mLauncher, item);
    }

    mItemsInvalidated = true;
    updateStyledTextFooFocus();
    mInfo.addListener(this);

    if (!sDefaultFolderName.contentEquals(mInfo.title)) {
      mFolderName.setText(mInfo.title);
    } else {
      mFolderName.setText("");
    }
  }
  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth();
    int height = getFolderHeight();
    int contentAreaWidthSpec =
        MeasureSpec.makeMeasureSpec(getContentAreaWidth(), MeasureSpec.EXACTLY);
    int contentAreaHeightSpec =
        MeasureSpec.makeMeasureSpec(getContentAreaHeight(), MeasureSpec.EXACTLY);

    if (LauncherAppState.isDisableAllApps() || mScrollingFolders) {
      // Don't cap the height of the content to allow scrolling.
      mContent.setFixedSize(getContentAreaWidth(), mContent.getDesiredHeight());
    } else {
      mContent.setFixedSize(getContentAreaWidth(), getContentAreaHeight());
    }

    mScrollView.measure(contentAreaWidthSpec, contentAreaHeightSpec);
    mFolderName.measure(
        contentAreaWidthSpec, MeasureSpec.makeMeasureSpec(mFolderNameHeight, MeasureSpec.EXACTLY));
    setMeasuredDimension(width, height);
  }
  public void animateOpen() {
    if (!(getParent() instanceof DragLayer)) return;

    Animator openFolderAnim = null;
    final Runnable onCompleteRunnable;
    if (!Utilities.isLmpOrAbove()) {
      positionAndSizeAsIcon();
      centerAboutIcon();

      PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1);
      PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX", 1.0f);
      PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY", 1.0f);
      final ObjectAnimator oa =
          LauncherAnimUtils.ofPropertyValuesHolder(this, alpha, scaleX, scaleY);
      oa.setDuration(mExpandDuration);
      openFolderAnim = oa;

      setLayerType(LAYER_TYPE_HARDWARE, null);
      onCompleteRunnable =
          new Runnable() {
            @Override
            public void run() {
              setLayerType(LAYER_TYPE_NONE, null);
            }
          };
    } else {
      prepareReveal();
      centerAboutIcon();

      int width = getPaddingLeft() + getPaddingRight() + mContent.getDesiredWidth();
      int height = getFolderHeight();

      float transX = -0.075f * (width / 2 - getPivotX());
      float transY = -0.075f * (height / 2 - getPivotY());
      setTranslationX(transX);
      setTranslationY(transY);
      PropertyValuesHolder tx = PropertyValuesHolder.ofFloat("translationX", transX, 0);
      PropertyValuesHolder ty = PropertyValuesHolder.ofFloat("translationY", transY, 0);

      int rx = (int) Math.max(Math.max(width - getPivotX(), 0), getPivotX());
      int ry = (int) Math.max(Math.max(height - getPivotY(), 0), getPivotY());
      float radius = (float) Math.sqrt(rx * rx + ry * ry);
      AnimatorSet anim = LauncherAnimUtils.createAnimatorSet();
      Animator reveal =
          LauncherAnimUtils.createCircularReveal(
              this, (int) getPivotX(), (int) getPivotY(), 0, radius);
      reveal.setDuration(mMaterialExpandDuration);
      reveal.setInterpolator(new LogDecelerateInterpolator(100, 0));

      mContent.setAlpha(0f);
      Animator iconsAlpha = LauncherAnimUtils.ofFloat(mContent, "alpha", 0f, 1f);
      iconsAlpha.setDuration(mMaterialExpandDuration);
      iconsAlpha.setStartDelay(mMaterialExpandStagger);
      iconsAlpha.setInterpolator(new AccelerateInterpolator(1.5f));

      mFolderName.setAlpha(0f);
      Animator textAlpha = LauncherAnimUtils.ofFloat(mFolderName, "alpha", 0f, 1f);
      textAlpha.setDuration(mMaterialExpandDuration);
      textAlpha.setStartDelay(mMaterialExpandStagger);
      textAlpha.setInterpolator(new AccelerateInterpolator(1.5f));

      Animator drift = LauncherAnimUtils.ofPropertyValuesHolder(this, tx, ty);
      drift.setDuration(mMaterialExpandDuration);
      drift.setStartDelay(mMaterialExpandStagger);
      drift.setInterpolator(new LogDecelerateInterpolator(60, 0));

      anim.play(drift);
      anim.play(iconsAlpha);
      anim.play(textAlpha);
      anim.play(reveal);

      openFolderAnim = anim;

      mContent.setLayerType(LAYER_TYPE_HARDWARE, null);
      onCompleteRunnable =
          new Runnable() {
            @Override
            public void run() {
              mContent.setLayerType(LAYER_TYPE_NONE, null);
            }
          };
    }
    openFolderAnim.addListener(
        new AnimatorListenerAdapter() {
          @Override
          public void onAnimationStart(Animator animation) {
            sendCustomAccessibilityEvent(
                AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED,
                String.format(
                    getContext().getString(R.string.folder_opened),
                    mContent.getCountX(),
                    mContent.getCountY()));
            mState = STATE_ANIMATING;
          }

          @Override
          public void onAnimationEnd(Animator animation) {
            mState = STATE_OPEN;

            if (onCompleteRunnable != null) {
              onCompleteRunnable.run();
            }

            setFocusOnFirstChild();
          }
        });
    openFolderAnim.start();

    // Make sure the folder picks up the last drag move even if the finger doesn't move.
    if (mDragController.isDragging()) {
      mDragController.forceTouchMove();
    }
  }
 public void startEditingFolderName() {
   mFolderName.setHint("");
   mIsEditingName = true;
 }
  @Override
  protected void onFinishInflate() {
    super.onFinishInflate();
    mScrollView = (ScrollView) findViewById(R.id.scroll_view);
    mContent = (CellLayout) findViewById(R.id.folder_content);

    mFocusIndicatorHandler = new FocusIndicatorView(getContext());
    mContent.addView(mFocusIndicatorHandler, 0);
    mFocusIndicatorHandler.getLayoutParams().height = FocusIndicatorView.DEFAULT_LAYOUT_SIZE;
    mFocusIndicatorHandler.getLayoutParams().width = FocusIndicatorView.DEFAULT_LAYOUT_SIZE;

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

    mContent.setCellDimensions(grid.folderCellWidthPx, grid.folderCellHeightPx);
    mContent.setGridSize(0, 0);
    mContent.getShortcutsAndWidgets().setMotionEventSplittingEnabled(false);
    mContent.setInvertIfRtl(true);
    mFolderName = (FolderEditText) findViewById(R.id.folder_name);
    mFolderName.setFolder(this);
    if (mLauncher.getLockWorkspace()) {
      mFolderName.setKeyListener(null);
      mFolderName.setFocusable(false);
    } else {
      mFolderName.setOnFocusChangeListener(this);
    }

    // We find out how tall the text view wants to be (it is set to wrap_content), so that
    // we can allocate the appropriate amount of space for it.
    int measureSpec = MeasureSpec.UNSPECIFIED;
    mFolderName.measure(measureSpec, measureSpec);
    mFolderNameHeight = mFolderName.getMeasuredHeight();

    // We disable action mode for now since it messes up the view on phones
    mFolderName.setCustomSelectionActionModeCallback(mActionModeCallback);
    mFolderName.setOnEditorActionListener(this);
    mFolderName.setSelectAllOnFocus(true);
    mFolderName.setInputType(
        mFolderName.getInputType()
            | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS
            | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
    mAutoScrollHelper = new FolderAutoScrollHelper(mScrollView);

    boolean hideFolderName =
        SettingsProvider.getBoolean(mLauncher, SettingsProvider.HIDE_FOLDER_NAME, false);
    if (hideFolderName) {
      mFolderName.setVisibility(View.GONE);
      mFolderNameHeight = 0;
    }
  }