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 }