Skip to content

Instantly share code, notes, and snippets.

@takahirom
Created June 29, 2015 12:41
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save takahirom/3771c42b5c16ac1e887f to your computer and use it in GitHub Desktop.
Save takahirom/3771c42b5c16ac1e887f to your computer and use it in GitHub Desktop.
ActionMode Froating

Android Framework Code Reading

image

ActionMode Froatingで表示されるまでの流れ

Activity#startActionMode http://tools.oesf.biz/android-MNC/xref/android/app/Activity.java#5768

PhoneWindow#startActionMode http://tools.oesf.biz/android-MNC/xref/com/android/internal/policy/PhoneWindow.java#2723

   2745                 mode = createActionMode(type, wrappedCallback, originatingView);
   2746                 if (mode != null && wrappedCallback.onCreateActionMode(mode, mode.getMenu())) {
   2747                     setHandledActionMode(mode);
   2748                 } else {
   2749                     mode = null;
   2750                 }

http://tools.oesf.biz/android-MNC/xref/com/android/internal/policy/PhoneWindow.java#3393

   3293         private void setHandledActionMode(ActionMode mode) {
   3294             if (mode.getType() == ActionMode.TYPE_PRIMARY) {
   3295                 setHandledPrimaryActionMode(mode);
   3296             } else if (mode.getType() == ActionMode.TYPE_FLOATING) {
   3297                 setHandledFloatingActionMode(mode);
   3298             }
   3299         }
   3393         private void setHandledFloatingActionMode(ActionMode mode) {
   3394             mFloatingActionMode = mode;
   3395             mFloatingToolbar = new FloatingToolbar(mContext, PhoneWindow.this);
   3396             ((FloatingActionMode) mFloatingActionMode).setFloatingToolbar(mFloatingToolbar);
   3397             mFloatingActionMode.invalidate();
   3398             mFloatingToolbar.show();
   3399             mFloatingActionModeOriginatingView.getViewTreeObserver()
   3400                 .addOnPreDrawListener(mFloatingToolbarPreDrawListener);
   3401         }         

http://tools.oesf.biz/android-MNC/xref/com/android/internal/widget/FloatingToolbar.java#153

    150     /**
    151      * Shows this floating toolbar.
    152      */
    153     public FloatingToolbar show() {
    154         List<MenuItem> menuItems = getVisibleAndEnabledMenuItems(mMenu);
    155         if (!isCurrentlyShowing(menuItems) || mWidthChanged) {
    156             mPopup.dismiss();
    157             mPopup.layoutMenuItems(menuItems, mMenuItemClickListener, mSuggestedWidth);
    158             mShowingTitles = getMenuItemTitles(menuItems);
    159         }
    160         refreshCoordinates();
    161         mPopup.setOverflowDirection(mOverflowDirection);
    162         mPopup.updateCoordinates(mCoordinates.x, mCoordinates.y);
    163         if (!mPopup.isShowing()) {
    164             mPopup.show(mCoordinates.x, mCoordinates.y);
    165         }
    166         mWidthChanged = false;
    167         return this;
    168     }

メニューの時のうにゅーを探す

http://tools.oesf.biz/android-MNC/xref/com/android/internal/widget/FloatingToolbar.java#860

    860         /**
    861          * Fits as many menu items in the main panel and returns a list of the menu items that
    862          * were not fit in.
    863          *
    864          * @return The menu items that are not included in this main panel.
    865          */
    866         public List<MenuItem> layoutMenuItems(List<MenuItem> menuItems, int suggestedWidth) {
    867             final int toolbarWidth = getAdjustedToolbarWidth(mContext, suggestedWidth)
    868                     // Reserve space for the "open overflow" button.
    869                     - getEstimatedOpenOverflowButtonWidth(mContext);
    870 
    871             int availableWidth = toolbarWidth;
    872             final LinkedList<MenuItem> remainingMenuItems = new LinkedList<MenuItem>(menuItems);
    873 
    874             mContentView.removeAllViews();
    875 
    876             boolean isFirstItem = true;
    877             while (!remainingMenuItems.isEmpty()) {
    878                 final MenuItem menuItem = remainingMenuItems.peek();
    879                 Button menuItemButton = createMenuItemButton(mContext, menuItem);
    880 
    881                 // Adding additional start padding for the first button to even out button spacing.
    882                 if (isFirstItem) {
    883                     menuItemButton.setPaddingRelative(
    884                             (int) (1.5 * menuItemButton.getPaddingStart()),
    885                             menuItemButton.getPaddingTop(),
    886                             menuItemButton.getPaddingEnd(),
    887                             menuItemButton.getPaddingBottom());
    888                     isFirstItem = false;
    889                 }
    890 
    891                 // Adding additional end padding for the last button to even out button spacing.
    892                 if (remainingMenuItems.size() == 1) {
    893                     menuItemButton.setPaddingRelative(
    894                             menuItemButton.getPaddingStart(),
    895                             menuItemButton.getPaddingTop(),
    896                             (int) (1.5 * menuItemButton.getPaddingEnd()),
    897                             menuItemButton.getPaddingBottom());
    898                 }
    899 
    900                 menuItemButton.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
    901                 int menuItemButtonWidth = Math.min(menuItemButton.getMeasuredWidth(), toolbarWidth);
    902                 if (menuItemButtonWidth <= availableWidth) {
    903                     menuItemButton.setTag(menuItem);
    904                     menuItemButton.setOnClickListener(mMenuItemButtonOnClickListener);
    905                     mContentView.addView(menuItemButton);
    906                     ViewGroup.LayoutParams params = menuItemButton.getLayoutParams();
    907                     params.width = menuItemButtonWidth;
    908                     menuItemButton.setLayoutParams(params);
    909                     availableWidth -= menuItemButtonWidth;
    910                     remainingMenuItems.pop();
    911                 } else {
    912                     if (mOpenOverflowButton == null) {
    913                         mOpenOverflowButton = (ImageButton) LayoutInflater.from(mContext)
    914                                 .inflate(R.layout.floating_popup_open_overflow_button, null);
    915                         mOpenOverflowButton.setOnClickListener(new View.OnClickListener() {
    916                             @Override
    917                             public void onClick(View v) {
    918                                 if (mOpenOverflowButton != null) {
    919                                     mOpenOverflow.run();
    920                                 }
    921                             }
    922                         });
    923                     }
    924                     mContentView.addView(mOpenOverflowButton);
    925                     break;
    926                 }
    927             }
    928             return remainingMenuItems;
    929         }

http://tools.oesf.biz/android-MNC/xref/com/android/internal/widget/FloatingToolbar.java#openOverflow

    578         /**
    579          * Opens the floating toolbar overflow.
    580          * This method should not be called if menu items have not been laid out with
    581          * {@link #layoutMenuItems(java.util.List, MenuItem.OnMenuItemClickListener, int)}.
    582          *
    583          * @throws IllegalStateException if called when menu items have not been laid out.
    584          */
    585         private void openOverflow() {
    586             Preconditions.checkState(mMainPanel != null);
    587             Preconditions.checkState(mOverflowPanel != null);
    588 
    589             mMainPanel.fadeOut(true);
    590             Size overflowPanelSize = mOverflowPanel.measure();
    591             final int targetWidth = overflowPanelSize.getWidth();
    592             final int targetHeight = overflowPanelSize.getHeight();
    593             final boolean morphUpwards = (mOverflowDirection == OVERFLOW_DIRECTION_UP);
    594             final int startWidth = mContentContainer.getWidth();
    595             final int startHeight = mContentContainer.getHeight();
    596             final float startY = mContentContainer.getY();
    597             final float right = mContentContainer.getX() + mContentContainer.getWidth();
    598             Animation widthAnimation = new Animation() {
    599                 @Override
    600                 protected void applyTransformation(float interpolatedTime, Transformation t) {
    601                     ViewGroup.LayoutParams params = mContentContainer.getLayoutParams();
    602                     int deltaWidth = (int) (interpolatedTime * (targetWidth - startWidth));
    603                     params.width = startWidth + deltaWidth;
    604                     mContentContainer.setLayoutParams(params);
    605                     mContentContainer.setX(right - mContentContainer.getWidth());
    606                 }
    607             };
    608             Animation heightAnimation = new Animation() {
    609                 @Override
    610                 protected void applyTransformation(float interpolatedTime, Transformation t) {
    611                     ViewGroup.LayoutParams params = mContentContainer.getLayoutParams();
    612                     int deltaHeight = (int) (interpolatedTime * (targetHeight - startHeight));
    613                     params.height = startHeight + deltaHeight;
    614                     mContentContainer.setLayoutParams(params);
    615                     if (morphUpwards) {
    616                         float y = startY - (mContentContainer.getHeight() - startHeight);
    617                         mContentContainer.setY(y);
    618                     }
    619                 }
    620             };
    621             widthAnimation.setDuration(240);
    622             heightAnimation.setDuration(180);
    623             heightAnimation.setStartOffset(60);
    624             mOpenOverflowAnimation.getAnimations().clear();
    625             mOpenOverflowAnimation.setAnimationListener(mOnOverflowOpened);
    626             mOpenOverflowAnimation.addAnimation(widthAnimation);
    627             mOpenOverflowAnimation.addAnimation(heightAnimation);
    628             mContentContainer.startAnimation(mOpenOverflowAnimation);
    629         }    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment