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

Commit fd1e93d1 authored by Adam Powell's avatar Adam Powell
Browse files

New new design for ResolverActivity

Switch back to using a list as the grid and differently positioned
activity icons were confusing to users. Keep the distinct "last used"
presentation but align icons and titles with the further choices
below. Adjust this to make the fold more apparent. Remember
open/closed slider state across config changes.

Fix some bugs in nested scrolling and flinging.

Bug 17301272

Change-Id: I175937d5821df27b6ac7ffad7f01cd9a6ed3e3e3
parent 36f32f1b
Loading
Loading
Loading
Loading
+9 −8
Original line number Diff line number Diff line
@@ -3325,8 +3325,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
        }
        if (dispatchNestedPreScroll(0, -rawDeltaY, mScrollConsumed, mScrollOffset)) {
            rawDeltaY += mScrollConsumed[1];
            scrollOffsetCorrection -= mScrollOffset[1];
            scrollConsumedCorrection -= mScrollConsumed[1];
            scrollOffsetCorrection = -mScrollOffset[1];
            scrollConsumedCorrection = mScrollConsumed[1];
            if (vtev != null) {
                vtev.offsetLocation(0, mScrollOffset[1]);
            }
@@ -3437,7 +3437,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                            }
                        }
                    }
                    mMotionY = y + scrollOffsetCorrection;
                    mMotionY = y + lastYCorrection + scrollOffsetCorrection;
                }
                mLastY = y + lastYCorrection + scrollOffsetCorrection;
            }
@@ -3505,10 +3505,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                    mMotionCorrection = 0;
                    View motionView = getChildAt(motionPosition - mFirstPosition);
                    mMotionViewOriginalTop = motionView != null ? motionView.getTop() : 0;
                    mMotionY = y;
                    mMotionY =  y + scrollOffsetCorrection;
                    mMotionPosition = motionPosition;
                }
                mLastY = y;
                mLastY = y + lastYCorrection + scrollOffsetCorrection;
                mDirection = newDirection;
            }
        }
@@ -3876,7 +3876,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                        if (mPositionScroller != null) {
                            mPositionScroller.stop();
                        }
                        if (flingVelocity) {
                        if (flingVelocity && !dispatchNestedPreFling(0, -initialVelocity)) {
                            dispatchNestedFling(0, -initialVelocity, false);
                        }
                    }
@@ -4001,14 +4001,15 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
     * <p>Applications can use this method to manually initiate a fling as if the user
     * initiated it via touch interaction.</p>
     *
     * @param velocityY Vertical velocity in pixels per second
     * @param velocityY Vertical velocity in pixels per second. Note that this is velocity of
     *                  content, not velocity of a touch that initiated the fling.
     */
    public void fling(int velocityY) {
        if (mFlingRunnable == null) {
            mFlingRunnable = new FlingRunnable();
        }
        reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
        mFlingRunnable.start(-velocityY);
        mFlingRunnable.start(velocityY);
    }

    @Override
+32 −29
Original line number Diff line number Diff line
@@ -90,7 +90,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
    private boolean mSafeForwardingMode;
    private boolean mAlwaysUseOption;
    private boolean mShowExtended;
    private GridView mGridView;
    private ListView mListView;
    private Button mAlwaysButton;
    private Button mOnceButton;
    private int mIconDpi;
@@ -228,10 +228,13 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
                mLaunchedFromUid, alwaysUseOption);

        final int layoutId;
        final boolean useHeader;
        if (mAdapter.hasFilteredItem()) {
            layoutId = R.layout.resolver_list_with_default;
            alwaysUseOption = false;
            useHeader = true;
        } else {
            useHeader = false;
            layoutId = R.layout.resolver_list;
        }
        mAlwaysUseOption = alwaysUseOption;
@@ -243,16 +246,19 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
            return;
        } else if (count > 1) {
            setContentView(layoutId);
            mGridView = (GridView) findViewById(R.id.resolver_list);
            mGridView.setAdapter(mAdapter);
            mGridView.setOnItemClickListener(this);
            mGridView.setOnItemLongClickListener(new ItemLongClickListener());
            mListView = (ListView) findViewById(R.id.resolver_list);
            mListView.setAdapter(mAdapter);
            mListView.setOnItemClickListener(this);
            mListView.setOnItemLongClickListener(new ItemLongClickListener());

            if (alwaysUseOption) {
                mGridView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
                mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
            }

            resizeGrid();
            if (useHeader) {
                mListView.addHeaderView(LayoutInflater.from(this).inflate(
                        R.layout.resolver_different_item_header, mListView, false));
            }
        } else if (count == 1) {
            safelyStartActivity(mAdapter.intentForPosition(0, false));
            mPackageMonitor.unregister();
@@ -265,8 +271,8 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
            final TextView empty = (TextView) findViewById(R.id.empty);
            empty.setVisibility(View.VISIBLE);

            mGridView = (GridView) findViewById(R.id.resolver_list);
            mGridView.setVisibility(View.GONE);
            mListView = (ListView) findViewById(R.id.resolver_list);
            mListView.setVisibility(View.GONE);
        }

        final ResolverDrawerLayout rdl = (ResolverDrawerLayout) findViewById(R.id.contentPanel);
@@ -340,11 +346,6 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
        }
    }

    void resizeGrid() {
        final int itemCount = mAdapter.getCount();
        mGridView.setNumColumns(Math.min(itemCount, mMaxColumns));
    }

    void dismiss() {
        if (!isFinishing()) {
            finish();
@@ -419,19 +420,24 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        if (mAlwaysUseOption) {
            final int checkedPos = mGridView.getCheckedItemPosition();
            final int checkedPos = mListView.getCheckedItemPosition();
            final boolean hasValidSelection = checkedPos != ListView.INVALID_POSITION;
            mLastSelected = checkedPos;
            setAlwaysButtonEnabled(hasValidSelection, checkedPos, true);
            mOnceButton.setEnabled(hasValidSelection);
            if (hasValidSelection) {
                mGridView.setSelection(checkedPos);
                mListView.setSelection(checkedPos);
            }
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        position -= mListView.getHeaderViewsCount();
        if (position < 0) {
            // Header views don't count.
            return;
        }
        ResolveInfo resolveInfo = mAdapter.resolveInfoForPosition(position, true);
        if (mResolvingHome && hasManagedProfile()
                && !supportsManagedProfiles(resolveInfo)) {
@@ -441,13 +447,13 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
                    Toast.LENGTH_LONG).show();
            return;
        }
        final int checkedPos = mGridView.getCheckedItemPosition();
        final int checkedPos = mListView.getCheckedItemPosition();
        final boolean hasValidSelection = checkedPos != ListView.INVALID_POSITION;
        if (mAlwaysUseOption && (!hasValidSelection || mLastSelected != checkedPos)) {
            setAlwaysButtonEnabled(hasValidSelection, checkedPos, true);
            mOnceButton.setEnabled(hasValidSelection);
            if (hasValidSelection) {
                mGridView.smoothScrollToPosition(checkedPos);
                mListView.smoothScrollToPosition(checkedPos);
            }
            mLastSelected = checkedPos;
        } else {
@@ -504,7 +510,7 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
    public void onButtonClick(View v) {
        final int id = v.getId();
        startSelected(mAlwaysUseOption ?
                mGridView.getCheckedItemPosition() : mAdapter.getFilteredPosition(),
                mListView.getCheckedItemPosition() : mAdapter.getFilteredPosition(),
                id == R.id.button_always,
                mAlwaysUseOption);
        dismiss();
@@ -714,8 +720,6 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
            if (newItemCount == 0) {
                // We no longer have any items...  just finish the activity.
                finish();
            } else if (newItemCount != oldItemCount) {
                resizeGrid();
            }
        }

@@ -957,19 +961,13 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic
        }

        public View getView(int position, View convertView, ViewGroup parent) {
            View view;
            if (convertView == null) {
            View view = convertView;
            if (view == null) {
                view = mInflater.inflate(
                        com.android.internal.R.layout.resolve_list_item, parent, false);

                final ViewHolder holder = new ViewHolder(view);
                view.setTag(holder);

                // Fix the icon size even if we have different sized resources
                ViewGroup.LayoutParams lp = holder.icon.getLayoutParams();
                lp.width = lp.height = mIconSize;
            } else {
                view = convertView;
            }
            bindView(view, getItem(position));
            return view;
@@ -1007,6 +1005,11 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic

        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
            position -= mListView.getHeaderViewsCount();
            if (position < 0) {
                // Header views don't count.
                return false;
            }
            ResolveInfo ri = mAdapter.resolveInfoForPosition(position, true);
            showAppDetails(ri);
            return true;
+73 −9
Original line number Diff line number Diff line
@@ -20,15 +20,15 @@ package com.android.internal.widget;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;

import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.view.animation.AnimationUtils;
@@ -68,6 +68,7 @@ public class ResolverDrawerLayout extends ViewGroup {

    private boolean mIsDragging;
    private boolean mOpenOnClick;
    private boolean mOpenOnLayout;
    private final int mTouchSlop;
    private final float mMinFlingVelocity;
    private final OverScroller mScroller;
@@ -202,6 +203,8 @@ public class ResolverDrawerLayout extends ViewGroup {
    public boolean onTouchEvent(MotionEvent ev) {
        final int action = ev.getActionMasked();

        mVelocityTracker.addMovement(ev);

        boolean handled = false;
        switch (action) {
            case MotionEvent.ACTION_DOWN: {
@@ -288,6 +291,10 @@ public class ResolverDrawerLayout extends ViewGroup {
            break;

            case MotionEvent.ACTION_CANCEL: {
                if (mIsDragging) {
                    smoothScrollTo(
                            mCollapseOffset < mCollapsibleHeight / 2 ? 0 : mCollapsibleHeight, 0);
                }
                resetTouch();
                return true;
            }
@@ -498,28 +505,39 @@ public class ResolverDrawerLayout extends ViewGroup {
    @Override
    public void onStopNestedScroll(View child) {
        super.onStopNestedScroll(child);
        if (mScroller.isFinished()) {
            smoothScrollTo(mCollapseOffset < mCollapsibleHeight / 2 ? 0 : mCollapsibleHeight, 0);
        }
    }

    @Override
    public void onNestedScroll(View target, int dxConsumed, int dyConsumed,
            int dxUnconsumed, int dyUnconsumed) {
        if (dyUnconsumed > 0) {
        if (dyUnconsumed < 0) {
            performDrag(-dyUnconsumed);
        }
    }

    @Override
    public void onNestedPreScroll(View target, int dx, int dy, int[] consumed) {
        if (dy < 0) {
            consumed[1] = (int) performDrag(-dy);
        if (dy > 0) {
            consumed[1] = (int) -performDrag(-dy);
        }
    }

    @Override
    public boolean onNestedPreFling(View target, float velocityX, float velocityY) {
        if (velocityY > mMinFlingVelocity && mCollapseOffset != 0) {
            smoothScrollTo(0, velocityY);
            return true;
        }
        return false;
    }

    @Override
    public boolean onNestedFling(View target, float velocityX, float velocityY, boolean consumed) {
        if (!consumed && Math.abs(velocityY) > mMinFlingVelocity) {
            smoothScrollTo(velocityY < 0 ? 0 : mCollapsibleHeight, velocityY);
            smoothScrollTo(velocityY > 0 ? 0 : mCollapsibleHeight, velocityY);
            return true;
        }
        return false;
@@ -571,8 +589,8 @@ public class ResolverDrawerLayout extends ViewGroup {
        if (isLaidOut()) {
            mCollapseOffset = Math.min(mCollapseOffset, mCollapsibleHeight);
        } else {
            // Start out collapsed at first
            mCollapseOffset = mCollapsibleHeight;
            // Start out collapsed at first unless we restored state for otherwise
            mCollapseOffset = mOpenOnLayout ? 0 : mCollapsibleHeight;
        }

        mTopOffset = Math.max(0, heightSize - heightUsed) + (int) mCollapseOffset;
@@ -634,6 +652,20 @@ public class ResolverDrawerLayout extends ViewGroup {
        return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
    }

    @Override
    protected Parcelable onSaveInstanceState() {
        final SavedState ss = new SavedState(super.onSaveInstanceState());
        ss.open = mCollapsibleHeight > 0 && mCollapseOffset == 0;
        return ss;
    }

    @Override
    protected void onRestoreInstanceState(Parcelable state) {
        final SavedState ss = (SavedState) state;
        super.onRestoreInstanceState(ss.getSuperState());
        mOpenOnLayout = ss.open;
    }

    public static class LayoutParams extends MarginLayoutParams {
        public boolean alwaysShow;
        public boolean ignoreOffset;
@@ -670,4 +702,36 @@ public class ResolverDrawerLayout extends ViewGroup {
            super(source);
        }
    }

    static class SavedState extends BaseSavedState {
        boolean open;

        SavedState(Parcelable superState) {
            super(superState);
        }

        private SavedState(Parcel in) {
            super(in);
            open = in.readInt() != 0;
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            super.writeToParcel(out, flags);
            out.writeInt(open ? 1 : 0);
        }

        public static final Parcelable.Creator<SavedState> CREATOR =
                new Parcelable.Creator<SavedState>() {
            @Override
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }

            @Override
            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
    }
}
+21 −17
Original line number Diff line number Diff line
@@ -18,9 +18,10 @@
*/
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:orientation="horizontal"
              android:layout_height="wrap_content"
              android:layout_width="match_parent"
              android:minHeight="?attr/listPreferredItemHeightSmall"
              android:paddingTop="4dp"
              android:paddingBottom="4dp"
              android:background="?attr/activatedBackgroundIndicator">
@@ -28,37 +29,40 @@
    <!-- Activity icon when presenting dialog
         Size will be filled in by ResolverActivity -->
    <ImageView android:id="@+id/icon"
               android:layout_width="0dp"
               android:layout_height="0dp"
               android:layout_gravity="center"
               android:layout_margin="4dp"
               android:layout_width="24dp"
               android:layout_height="24dp"
               android:layout_gravity="start|center_vertical"
               android:layout_marginStart="16dp"
               android:layout_marginEnd="16dp"
               android:layout_marginTop="12dp"
               android:layout_marginBottom="12dp"
               android:scaleType="fitCenter" />

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:gravity="center"
              android:gravity="start|center_vertical"
              android:orientation="vertical"
              android:paddingStart="16dp"
              android:paddingEnd="16dp"
              android:layout_height="wrap_content"
              android:layout_width="wrap_content"
              android:layout_gravity="center">
              android:layout_gravity="start|center_vertical">
        <!-- Activity name -->
        <TextView android:id="@android:id/text1"
                  android:textAppearance="?android:attr/textAppearanceSmall"
                  android:fontFamily="sans-serif-condensed"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:gravity="center"
                  android:minLines="2"
                  android:maxLines="2" />
                  android:textAppearance="?attr/textAppearanceMedium"
                  android:textColor="?attr/textColorPrimary"
                  android:minLines="1"
                  android:maxLines="1"
                  android:ellipsize="marquee" />
        <!-- Extended activity info to distinguish between duplicate activity names -->
        <TextView android:id="@android:id/text2"
                  android:textAppearance="?android:attr/textAppearanceSmall"
                  android:fontFamily="sans-serif-condensed"
                  android:layout_width="wrap_content"
                  android:layout_height="wrap_content"
                  android:gravity="center"
                  android:minLines="2"
                  android:maxLines="2"
                  android:paddingTop="4dip" />
                  android:minLines="1"
                  android:maxLines="1"
                  android:ellipsize="marquee" />
    </LinearLayout>
</LinearLayout>
+34 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
 * Copyright 2014, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
-->
<TextView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alwaysShow="true"
    android:text="@string/use_a_different_app"
    android:minHeight="56dp"
    android:textAppearance="?android:attr/textAppearanceMedium"
    android:gravity="start|center_vertical"
    android:paddingStart="16dp"
    android:paddingEnd="16dp"
    android:paddingTop="8dp"
    android:paddingBottom="8dp"
    android:background="@color/white"
    android:elevation="8dp"
    />
Loading