Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 865847b1 authored by Brian Attwell's avatar Brian Attwell
Browse files

Improvements to multi select

* selection bar now uses an <- instead of X icon
* FAB animates away when entering either selection or search mode
* allow selection mode to be entered once already in search mode

Demo: https://drive.google.com/a/google.com/file/d/0B-vjphxTdjuANERMUDF6Y2NyQXc/view?usp=sharing

Bug: 19549465
Change-Id: I657bf564c8e6cdfca6f7779918c4807e09e78d9b
parent 07adabf2
Loading
Loading
Loading
Loading
+7 −3
Original line number Diff line number Diff line
@@ -17,5 +17,9 @@

<ripple xmlns:android="http://schemas.android.com/apk/res/android"
     android:color="@color/contacts_accent_color">
    <item android:drawable="@drawable/fab_blue" />
     <item android:id="@android:id/mask">
          <shape android:shape="oval">
               <solid android:color="@android:color/white" />
          </shape>
     </item>
</ripple>
 No newline at end of file
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
    android:layout_height="@dimen/floating_action_button_height"
    android:layout_marginEnd="@dimen/floating_action_button_margin_right"
    android:layout_marginBottom="@dimen/floating_action_button_margin_bottom"
    android:background="@drawable/fab_blue"
    android:layout_alignParentEnd="true"
    android:layout_alignParentBottom="true">

+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@
        android:id="@+id/selection_close"
        android:layout_width="48dp"
        android:layout_height="48dp"
        android:src="@drawable/ic_close_dk"
        android:src="@drawable/ic_back_arrow"
        android:background="?android:attr/selectableItemBackgroundBorderless"
        android:contentDescription="@string/action_menu_back_from_search"
        android:layout_gravity="center_vertical|start"
+18 −12
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ public class ActionBarAdapter implements OnCloseListener {
            public static final int START_SEARCH_MODE = 1;
            public static final int START_SELECTION_MODE = 2;
            public static final int STOP_SEARCH_AND_SELECTION_MODE = 3;
            public static final int BEGIN_STOPPING_SEARCH_AND_SELECTION_MODE = 4;
        }

        void onAction(int action);
@@ -347,7 +348,7 @@ public class ActionBarAdapter implements OnCloseListener {
        if (mShowHomeIcon && !isSearchOrSelectionMode) {
            newFlags |= ActionBar.DISPLAY_SHOW_HOME;
        }
        if (mSearchMode) {
        if (mSearchMode && !mSelectionMode) {
            // The search container is placed inside the toolbar. So we need to disable the
            // Toolbar's content inset in order to allow the search container to be the width of
            // the window.
@@ -384,6 +385,8 @@ public class ActionBarAdapter implements OnCloseListener {

        final boolean isSelectionModeChanging
                = (mSelectionContainer.getParent() == null) == mSelectionMode;
        final boolean isSwitchingFromSearchToSelection =
                mSearchMode && isSelectionModeChanging || mSearchMode && mSelectionMode;
        final boolean isSearchModeChanging
                = (mSearchContainer.getParent() == null) == mSearchMode;
        final boolean isTabHeightChanging = isSearchModeChanging || isSelectionModeChanging;
@@ -391,21 +394,19 @@ public class ActionBarAdapter implements OnCloseListener {
        // When skipAnimation=true, it is possible that we will switch from search mode
        // to selection mode directly. So we need to remove the undesired container in addition
        // to adding the desired container.
        if (skipAnimation) {
            if (isTabHeightChanging) {
        if (skipAnimation || isSwitchingFromSearchToSelection) {
            if (isTabHeightChanging || isSwitchingFromSearchToSelection) {
                mToolbar.removeView(mLandscapeTabs);
                if (mSearchMode) {
                    setPortraitTabHeight(0);
                mToolbar.removeView(mSearchContainer);
                mToolBarFrame.removeView(mSelectionContainer);
                    addSearchContainer();
                } else if (mSelectionMode) {
                if (mSelectionMode) {
                    setPortraitTabHeight(0);
                    mToolbar.removeView(mSearchContainer);
                    addSelectionContainer();
                } else if (mSearchMode) {
                    setPortraitTabHeight(0);
                    addSearchContainer();
                } else {
                    setPortraitTabHeight(mMaxPortraitTabHeight);
                    mToolbar.removeView(mSearchContainer);
                    mToolBarFrame.removeView(mSelectionContainer);
                    addLandscapeViewPagerTabs();
                }
                updateDisplayOptions(isSearchModeChanging);
@@ -423,6 +424,9 @@ public class ActionBarAdapter implements OnCloseListener {
                animateTabHeightChange(mMaxPortraitTabHeight, 0);
                updateDisplayOptions(isSearchModeChanging);
            } else {
                if (mListener != null) {
                    mListener.onAction(Action.BEGIN_STOPPING_SEARCH_AND_SELECTION_MODE);
                }
                mSelectionContainer.setAlpha(1);
                animateTabHeightChange(0, mMaxPortraitTabHeight);
                mSelectionContainer.animate().alpha(0).withEndAction(new Runnable() {
@@ -491,15 +495,17 @@ public class ActionBarAdapter implements OnCloseListener {
    private void addSearchContainer() {
        mToolbar.removeView(mSearchContainer);
        mToolbar.addView(mSearchContainer);
        mSearchContainer.setAlpha(1);
    }

    private void addSelectionContainer() {
        mToolBarFrame.removeView(mSelectionContainer);
        mToolBarFrame.addView(mSelectionContainer, 0);
        mSelectionContainer.setAlpha(1);
    }

    private void updateDisplayOptions(boolean isSearchModeChanging) {
        if (mSearchMode) {
        if (mSearchMode && !mSelectionMode) {
            setFocusOnSearchView();
            // Since we have the {@link SearchView} in a custom action bar, we must manually handle
            // expanding the {@link SearchView} when a search is initiated. Note that a side effect
+45 −9
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import com.android.contacts.activities.ActionBarAdapter.TabState;
import com.android.contacts.common.ContactsUtils;
import com.android.contacts.common.dialog.ClearFrequentsDialog;
import com.android.contacts.common.util.ImplicitIntentsUtil;
import com.android.contacts.common.widget.FloatingActionButtonController;
import com.android.contacts.editor.EditorIntents;
import com.android.contacts.interactions.ContactDeletionInteraction;
import com.android.contacts.common.interactions.ImportExportDialogFragment;
@@ -119,6 +120,9 @@ public class PeopleActivity extends ContactsActivity implements
    private ContactsRequest mRequest;

    private ActionBarAdapter mActionBarAdapter;
    private FloatingActionButtonController mFloatingActionButtonController;
    private View mFloatingActionButtonContainer;
    private boolean wasLastFabAnimationScaleIn = false;

    private ContactTileListFragment.Listener mFavoritesFragmentListener =
            new StrequentContactListFragmentListener();
@@ -366,12 +370,14 @@ public class PeopleActivity extends ContactsActivity implements
        // Add shadow under toolbar
        ViewUtil.addRectangularOutlineProvider(findViewById(R.id.toolbar_parent), getResources());

        // Configure action button
        final View floatingActionButtonContainer = findViewById(
                R.id.floating_action_button_container);
        ViewUtil.setupFloatingActionButton(floatingActionButtonContainer, getResources());
        final ImageButton floatingActionButton = (ImageButton) findViewById(R.id.floating_action_button);
        // Configure floating action button
        mFloatingActionButtonContainer = findViewById(R.id.floating_action_button_container);
        final ImageButton floatingActionButton
                = (ImageButton) findViewById(R.id.floating_action_button);
        floatingActionButton.setOnClickListener(this);
        initializeFabVisibility();
        mFloatingActionButtonController = new FloatingActionButtonController(this,
                mFloatingActionButtonContainer, floatingActionButton);

        invalidateOptionsMenuIfNeeded();
    }
@@ -494,6 +500,33 @@ public class PeopleActivity extends ContactsActivity implements
        invalidateOptionsMenuIfNeeded();
    }

    private void initializeFabVisibility() {
        final boolean hideFab = mActionBarAdapter.isSearchMode()
                || mActionBarAdapter.isSelectionMode();
        mFloatingActionButtonContainer.setVisibility(hideFab ? View.GONE : View.VISIBLE);
        wasLastFabAnimationScaleIn = !hideFab;
    }

    private void showFabWithAnimation(boolean showFab) {
        if (mFloatingActionButtonContainer == null) {
            return;
        }
        if (showFab) {
            if (!wasLastFabAnimationScaleIn) {
                mFloatingActionButtonContainer.setVisibility(View.VISIBLE);
                mFloatingActionButtonController.scaleIn(0);
            }
            wasLastFabAnimationScaleIn = true;

        } else {
            if (wasLastFabAnimationScaleIn) {
                mFloatingActionButtonContainer.setVisibility(View.VISIBLE);
                mFloatingActionButtonController.scaleOut();
            }
            wasLastFabAnimationScaleIn = false;
        }
    }

    @Override
    public void onContactListFilterChanged() {
        if (mAllFragment == null || !mAllFragment.isAdded()) {
@@ -519,11 +552,16 @@ public class PeopleActivity extends ContactsActivity implements
                configureFragments(false /* from request */);
                updateFragmentsVisibility();
                invalidateOptionsMenu();
                showFabWithAnimation(/* showFabWithAnimation = */ false);
                break;
            case ActionBarAdapter.Listener.Action.BEGIN_STOPPING_SEARCH_AND_SELECTION_MODE:
                showFabWithAnimation(/* showFabWithAnimation = */ true);
                break;
            case ActionBarAdapter.Listener.Action.STOP_SEARCH_AND_SELECTION_MODE:
                setQueryTextToFragment("");
                updateFragmentsVisibility();
                invalidateOptionsMenu();
                showFabWithAnimation(/* showFabWithAnimation = */ true);
                break;
            case ActionBarAdapter.Listener.Action.CHANGE_SEARCH_QUERY:
                final String queryString = mActionBarAdapter.getQueryString();
@@ -935,11 +973,9 @@ public class PeopleActivity extends ContactsActivity implements
    private final class CheckBoxListListener implements OnCheckBoxListActionListener {
        @Override
        public void onStartDisplayingCheckBoxes() {
            if (!mActionBarAdapter.isSearchMode()) {
            mActionBarAdapter.setSelectionMode(true);
            invalidateOptionsMenu();
        }
        }

        @Override
        public void onSelectedContactIdsChanged() {