1838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri/* 2838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * Copyright (C) 2015 The Android Open Source Project 3838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * 4838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * Licensed under the Apache License, Version 2.0 (the "License"); 5838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * you may not use this file except in compliance with the License. 6838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * You may obtain a copy of the License at 7838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * 8838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * http://www.apache.org/licenses/LICENSE-2.0 9838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * 10838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * Unless required by applicable law or agreed to in writing, software 11838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * distributed under the License is distributed on an "AS IS" BASIS, 12838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * See the License for the specific language governing permissions and 14838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri * limitations under the License. 15838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri */ 16838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 17838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarripackage com.android.internal.view; 18838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 19838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarriimport android.content.Context; 20838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarriimport android.graphics.Rect; 21838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarriimport android.view.ActionMode; 22838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarriimport android.view.Menu; 23838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarriimport android.view.MenuInflater; 24838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarriimport android.view.MenuItem; 25838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarriimport android.view.View; 269e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Tokiimport android.view.ViewConfiguration; 27838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 2815a6c89f46420371115b1648bd2f3925f4bcf7edAbodunrinwa Tokiimport com.android.internal.R; 290d7d4ef56083543d58ef5835ec594865a547347cClara Bayarriimport com.android.internal.util.Preconditions; 30838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarriimport com.android.internal.view.menu.MenuBuilder; 31838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarriimport com.android.internal.widget.FloatingToolbar; 32838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 33c107b0ecdcd4e2f89ae4bec818c3a94f45c3c15eAbodunrinwa Tokiimport java.util.Arrays; 34c107b0ecdcd4e2f89ae4bec818c3a94f45c3c15eAbodunrinwa Toki 35838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarripublic class FloatingActionMode extends ActionMode { 36838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 379e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki private static final int MAX_HIDE_DURATION = 3000; 38fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki private static final int MOVING_HIDE_DELAY = 300; 39fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki 40838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri private final Context mContext; 41838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri private final ActionMode.Callback2 mCallback; 42838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri private final MenuBuilder mMenu; 43838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri private final Rect mContentRect; 44bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa private final Rect mContentRectOnScreen; 45bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa private final Rect mPreviousContentRectOnScreen; 46bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa private final int[] mViewPositionOnScreen; 47bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa private final int[] mPreviousViewPositionOnScreen; 48bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa private final int[] mRootViewPositionOnScreen; 49bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa private final Rect mViewRectOnScreen; 50bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa private final Rect mPreviousViewRectOnScreen; 51a8151e4ef7987faa7d0ee31bc3013a05e5b76a05Abodunrinwa Toki private final Rect mScreenRect; 52838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri private final View mOriginatingView; 5315a6c89f46420371115b1648bd2f3925f4bcf7edAbodunrinwa Toki private final int mBottomAllowance; 54fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki 55fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki private final Runnable mMovingOff = new Runnable() { 56fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki public void run() { 57fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki mFloatingToolbarVisibilityHelper.setMoving(false); 58f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki mFloatingToolbarVisibilityHelper.updateToolbarVisibility(); 59fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki } 60fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki }; 61fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki 629e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki private final Runnable mHideOff = new Runnable() { 63fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki public void run() { 649e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki mFloatingToolbarVisibilityHelper.setHideRequested(false); 65f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki mFloatingToolbarVisibilityHelper.updateToolbarVisibility(); 66fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki } 67fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki }; 68fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki 690d7d4ef56083543d58ef5835ec594865a547347cClara Bayarri private FloatingToolbar mFloatingToolbar; 70fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki private FloatingToolbarVisibilityHelper mFloatingToolbarVisibilityHelper; 71838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 72838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri public FloatingActionMode( 730d7d4ef56083543d58ef5835ec594865a547347cClara Bayarri Context context, ActionMode.Callback2 callback, View originatingView) { 74fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki mContext = Preconditions.checkNotNull(context); 75fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki mCallback = Preconditions.checkNotNull(callback); 76838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri mMenu = new MenuBuilder(context).setDefaultShowAsAction( 77838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri MenuItem.SHOW_AS_ACTION_IF_ROOM); 780d7d4ef56083543d58ef5835ec594865a547347cClara Bayarri setType(ActionMode.TYPE_FLOATING); 791e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri mMenu.setCallback(new MenuBuilder.Callback() { 801e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri @Override 811e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri public void onMenuModeChange(MenuBuilder menu) {} 821e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri 831e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri @Override 841e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri public boolean onMenuItemSelected(MenuBuilder menu, MenuItem item) { 851e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri return mCallback.onActionItemClicked(FloatingActionMode.this, item); 861e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri } 871e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri }); 880d7d4ef56083543d58ef5835ec594865a547347cClara Bayarri mContentRect = new Rect(); 89bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mContentRectOnScreen = new Rect(); 90bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mPreviousContentRectOnScreen = new Rect(); 91bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mViewPositionOnScreen = new int[2]; 92bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mPreviousViewPositionOnScreen = new int[2]; 93bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mRootViewPositionOnScreen = new int[2]; 94bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mViewRectOnScreen = new Rect(); 95bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mPreviousViewRectOnScreen = new Rect(); 96a8151e4ef7987faa7d0ee31bc3013a05e5b76a05Abodunrinwa Toki mScreenRect = new Rect(); 97fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki mOriginatingView = Preconditions.checkNotNull(originatingView); 98bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mOriginatingView.getLocationOnScreen(mViewPositionOnScreen); 9915a6c89f46420371115b1648bd2f3925f4bcf7edAbodunrinwa Toki // Allow the content rect to overshoot a little bit beyond the 10015a6c89f46420371115b1648bd2f3925f4bcf7edAbodunrinwa Toki // bottom view bound if necessary. 10115a6c89f46420371115b1648bd2f3925f4bcf7edAbodunrinwa Toki mBottomAllowance = context.getResources() 10215a6c89f46420371115b1648bd2f3925f4bcf7edAbodunrinwa Toki .getDimensionPixelSize(R.dimen.content_rect_bottom_clip_allowance); 1030d7d4ef56083543d58ef5835ec594865a547347cClara Bayarri } 1040d7d4ef56083543d58ef5835ec594865a547347cClara Bayarri 1050d7d4ef56083543d58ef5835ec594865a547347cClara Bayarri public void setFloatingToolbar(FloatingToolbar floatingToolbar) { 106838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri mFloatingToolbar = floatingToolbar 107838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri .setMenu(mMenu) 108838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { 109838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri @Override 110838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri public boolean onMenuItemClick(MenuItem item) { 1111e821959626ef4171507e4776f629904d8bc6a55Clara Bayarri return mMenu.performItemAction(item, 0); 112838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri } 113838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri }); 114fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki mFloatingToolbarVisibilityHelper = new FloatingToolbarVisibilityHelper(mFloatingToolbar); 115f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki mFloatingToolbarVisibilityHelper.activate(); 116838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri } 117838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 118838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri @Override 119838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri public void setTitle(CharSequence title) {} 120838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 121838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri @Override 122838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri public void setTitle(int resId) {} 123838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 124838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri @Override 125838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri public void setSubtitle(CharSequence subtitle) {} 126838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 127838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri @Override 128838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri public void setSubtitle(int resId) {} 129838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 130838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri @Override 131838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri public void setCustomView(View view) {} 132838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 133838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri @Override 134838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri public void invalidate() { 135fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki checkToolbarInitialized(); 136838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri mCallback.onPrepareActionMode(this, mMenu); 137f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki invalidateContentRect(); // Will re-layout and show the toolbar if necessary. 138838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri } 139838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 140838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri @Override 141838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri public void invalidateContentRect() { 142fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki checkToolbarInitialized(); 143838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri mCallback.onGetContentRect(this, mOriginatingView, mContentRect); 144838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri repositionToolbar(); 145838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri } 146838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 147838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri public void updateViewLocationInWindow() { 148fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki checkToolbarInitialized(); 149c107b0ecdcd4e2f89ae4bec818c3a94f45c3c15eAbodunrinwa Toki 150bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mOriginatingView.getLocationOnScreen(mViewPositionOnScreen); 151bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mOriginatingView.getRootView().getLocationOnScreen(mRootViewPositionOnScreen); 152bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mOriginatingView.getGlobalVisibleRect(mViewRectOnScreen); 153bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mViewRectOnScreen.offset(mRootViewPositionOnScreen[0], mRootViewPositionOnScreen[1]); 154c107b0ecdcd4e2f89ae4bec818c3a94f45c3c15eAbodunrinwa Toki 155bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa if (!Arrays.equals(mViewPositionOnScreen, mPreviousViewPositionOnScreen) 156bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa || !mViewRectOnScreen.equals(mPreviousViewRectOnScreen)) { 157c107b0ecdcd4e2f89ae4bec818c3a94f45c3c15eAbodunrinwa Toki repositionToolbar(); 158bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mPreviousViewPositionOnScreen[0] = mViewPositionOnScreen[0]; 159bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mPreviousViewPositionOnScreen[1] = mViewPositionOnScreen[1]; 160bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mPreviousViewRectOnScreen.set(mViewRectOnScreen); 161c107b0ecdcd4e2f89ae4bec818c3a94f45c3c15eAbodunrinwa Toki } 162838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri } 163838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 164838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri private void repositionToolbar() { 165fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki checkToolbarInitialized(); 166601523ad007923779d156aaa8dc229468773e48cAbodunrinwa Toki 167bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mContentRectOnScreen.set(mContentRect); 168bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mContentRectOnScreen.offset(mViewPositionOnScreen[0], mViewPositionOnScreen[1]); 169a8151e4ef7987faa7d0ee31bc3013a05e5b76a05Abodunrinwa Toki 170a8151e4ef7987faa7d0ee31bc3013a05e5b76a05Abodunrinwa Toki if (isContentRectWithinBounds()) { 171a8151e4ef7987faa7d0ee31bc3013a05e5b76a05Abodunrinwa Toki mFloatingToolbarVisibilityHelper.setOutOfBounds(false); 172f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki // Make sure that content rect is not out of the view's visible bounds. 173bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mContentRectOnScreen.set( 174bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa Math.max(mContentRectOnScreen.left, mViewRectOnScreen.left), 175bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa Math.max(mContentRectOnScreen.top, mViewRectOnScreen.top), 176bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa Math.min(mContentRectOnScreen.right, mViewRectOnScreen.right), 177bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa Math.min(mContentRectOnScreen.bottom, 178bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mViewRectOnScreen.bottom + mBottomAllowance)); 179bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa 180bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa if (!mContentRectOnScreen.equals(mPreviousContentRectOnScreen)) { 181f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki // Content rect is moving. 182f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki mOriginatingView.removeCallbacks(mMovingOff); 183f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki mFloatingToolbarVisibilityHelper.setMoving(true); 1841b57653b50892f143241ae0f0beb2246ca4b2aa7Abodunrinwa Toki mFloatingToolbarVisibilityHelper.updateToolbarVisibility(); 185f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki mOriginatingView.postDelayed(mMovingOff, MOVING_HIDE_DELAY); 186f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki 187bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mFloatingToolbar.setContentRect(mContentRectOnScreen); 188f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki mFloatingToolbar.updateLayout(); 189f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki } 190a8151e4ef7987faa7d0ee31bc3013a05e5b76a05Abodunrinwa Toki } else { 191a8151e4ef7987faa7d0ee31bc3013a05e5b76a05Abodunrinwa Toki mFloatingToolbarVisibilityHelper.setOutOfBounds(true); 1921b57653b50892f143241ae0f0beb2246ca4b2aa7Abodunrinwa Toki mFloatingToolbarVisibilityHelper.updateToolbarVisibility(); 193bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mContentRectOnScreen.setEmpty(); 194a8151e4ef7987faa7d0ee31bc3013a05e5b76a05Abodunrinwa Toki } 195a8151e4ef7987faa7d0ee31bc3013a05e5b76a05Abodunrinwa Toki 196bafc908304d49e8f7f7c5e52772c75da66e4daa3Yohei Yukawa mPreviousContentRectOnScreen.set(mContentRectOnScreen); 197838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri } 198838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 199f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki private boolean isContentRectWithinBounds() { 200f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki mScreenRect.set( 201f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki 0, 202f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki 0, 203f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki mContext.getResources().getDisplayMetrics().widthPixels, 204f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki mContext.getResources().getDisplayMetrics().heightPixels); 205f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki 206f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri return intersectsClosed(mContentRectOnScreen, mScreenRect) 207f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri && intersectsClosed(mContentRectOnScreen, mViewRectOnScreen); 208f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri } 209f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri 210f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri /* 211f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri * Same as Rect.intersects, but includes cases where the rectangles touch. 212f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri */ 213f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri private static boolean intersectsClosed(Rect a, Rect b) { 214f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri return a.left <= b.right && b.left <= a.right 215f95ed10d9da55c25013200fb35af63f0dac65cb4Clara Bayarri && a.top <= b.bottom && b.top <= a.bottom; 216fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki } 217fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki 218fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki @Override 2199e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki public void hide(long duration) { 220fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki checkToolbarInitialized(); 2219e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki 2229e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki if (duration == ActionMode.DEFAULT_HIDE_DURATION) { 2239e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki duration = ViewConfiguration.getDefaultActionModeHideDuration(); 2249e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki } 2259e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki duration = Math.min(MAX_HIDE_DURATION, duration); 2269e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki mOriginatingView.removeCallbacks(mHideOff); 2279e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki if (duration <= 0) { 2289e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki mHideOff.run(); 229fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki } else { 2309e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki mFloatingToolbarVisibilityHelper.setHideRequested(true); 231f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki mFloatingToolbarVisibilityHelper.updateToolbarVisibility(); 2329e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki mOriginatingView.postDelayed(mHideOff, duration); 233fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki } 234fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki } 235fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki 236838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri @Override 237972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki public void onWindowFocusChanged(boolean hasWindowFocus) { 238972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki checkToolbarInitialized(); 239972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki mFloatingToolbarVisibilityHelper.setWindowFocused(hasWindowFocus); 240972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki mFloatingToolbarVisibilityHelper.updateToolbarVisibility(); 241972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki } 242972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki 243972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki @Override 244838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri public void finish() { 245fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki checkToolbarInitialized(); 246fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki reset(); 247838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri mCallback.onDestroyActionMode(this); 248838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri } 249838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 250838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri @Override 251838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri public Menu getMenu() { 252838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri return mMenu; 253838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri } 254838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 255838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri @Override 256838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri public CharSequence getTitle() { 257838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri return null; 258838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri } 259838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 260838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri @Override 261838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri public CharSequence getSubtitle() { 262838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri return null; 263838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri } 264838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 265838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri @Override 266838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri public View getCustomView() { 267838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri return null; 268838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri } 269838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 270838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri @Override 271838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri public MenuInflater getMenuInflater() { 272838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri return new MenuInflater(mContext); 273838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri } 274838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri 275fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki /** 276f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki * @throws IllegalStateException 277fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki */ 278fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki private void checkToolbarInitialized() { 279fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki Preconditions.checkState(mFloatingToolbar != null); 280fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki Preconditions.checkState(mFloatingToolbarVisibilityHelper != null); 281fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki } 282fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki 283fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki private void reset() { 284972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki mFloatingToolbar.dismiss(); 285f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki mFloatingToolbarVisibilityHelper.deactivate(); 286fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki mOriginatingView.removeCallbacks(mMovingOff); 2879e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki mOriginatingView.removeCallbacks(mHideOff); 288fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki } 289fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki 290fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki /** 291f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki * A helper for showing/hiding the floating toolbar depending on certain states. 292fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki */ 293fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki private static final class FloatingToolbarVisibilityHelper { 294fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki 295fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki private final FloatingToolbar mToolbar; 296fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki 2979e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki private boolean mHideRequested; 298fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki private boolean mMoving; 299fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki private boolean mOutOfBounds; 300972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki private boolean mWindowFocused = true; 301fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki 302f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki private boolean mActive; 303f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki 304fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki public FloatingToolbarVisibilityHelper(FloatingToolbar toolbar) { 305fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki mToolbar = Preconditions.checkNotNull(toolbar); 306fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki } 307fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki 308f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki public void activate() { 309f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki mHideRequested = false; 310f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki mMoving = false; 311f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki mOutOfBounds = false; 312972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki mWindowFocused = true; 313f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki 314f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki mActive = true; 315f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki } 316f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki 317f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki public void deactivate() { 318f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki mActive = false; 319f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki mToolbar.dismiss(); 320f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki } 321f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki 3229e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki public void setHideRequested(boolean hide) { 3239e211282d3ee54c9840947951593554c3bd5a77cAbodunrinwa Toki mHideRequested = hide; 324fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki } 325fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki 326fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki public void setMoving(boolean moving) { 327fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki mMoving = moving; 328fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki } 329fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki 330fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki public void setOutOfBounds(boolean outOfBounds) { 331fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki mOutOfBounds = outOfBounds; 332fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki } 333fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki 334972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki public void setWindowFocused(boolean windowFocused) { 335972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki mWindowFocused = windowFocused; 336972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki } 337972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki 338f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki public void updateToolbarVisibility() { 339f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki if (!mActive) { 340f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki return; 341f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki } 342f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki 343972ab4f8588c365cf9c06e1f22b30a96fb0a06fcAbodunrinwa Toki if (mHideRequested || mMoving || mOutOfBounds || !mWindowFocused) { 344fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki mToolbar.hide(); 345f444b5c3ae46f8790c8f2a8481fb688b00a42d3bAbodunrinwa Toki } else { 346fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki mToolbar.show(); 347fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki } 348fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki } 349fd3a3a1163c5096821cef351309fcdd9a4f48002Abodunrinwa Toki } 350838e36cda7af884233c06c5b2b5e43ffbed4715bClara Bayarri} 351