From ae730b1f074f9c206c1baeabf7dc940b605a4eb3 Mon Sep 17 00:00:00 2001 From: Mike Digman Date: Thu, 25 Apr 2019 11:10:31 -0700 Subject: [PATCH 1/2] Sharesheet - add a-z list label New users may not understand what the a-z list is, as demoed in user testing. Add a label above the list that describes the contents. Bug: 130349817 Test: manual Change-Id: I64bee605ab33dd486ef6cd95346c46f4eff62269 --- .../android/internal/app/ChooserActivity.java | 57 ++++++++++++++----- core/res/res/layout/chooser_az_label_row.xml | 31 ++++++++++ core/res/res/values/strings.xml | 3 + core/res/res/values/symbols.xml | 2 + 4 files changed, 78 insertions(+), 15 deletions(-) create mode 100644 core/res/res/layout/chooser_az_label_row.xml diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 204012f04cba6..4e2c619f8aa3b 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -2496,6 +2496,7 @@ public class ChooserActivity extends ResolverActivity { private static final int VIEW_TYPE_NORMAL = 1; private static final int VIEW_TYPE_CONTENT_PREVIEW = 2; private static final int VIEW_TYPE_PROFILE = 3; + private static final int VIEW_TYPE_AZ_LABEL = 4; private static final int MAX_TARGETS_PER_ROW_PORTRAIT = 4; private static final int MAX_TARGETS_PER_ROW_LANDSCAPE = 8; @@ -2556,6 +2557,7 @@ public class ChooserActivity extends ResolverActivity { + getProfileRowCount() + getServiceTargetRowCount() + getCallerAndRankedTargetRowCount() + + getAzLabelRowCount() + Math.ceil( (float) mChooserListAdapter.getAlphaTargetCount() / getMaxTargetsPerRow()) @@ -2593,6 +2595,11 @@ public class ChooserActivity extends ResolverActivity { return 0; } + public int getAzLabelRowCount() { + // Only show a label if the a-z list is showing + return mChooserListAdapter.getAlphaTargetCount() > 0 ? 1 : 0; + } + @Override public Object getItem(int position) { // We have nothing useful to return here. @@ -2617,6 +2624,10 @@ public class ChooserActivity extends ResolverActivity { return createProfileView(convertView, parent); } + if (viewType == VIEW_TYPE_AZ_LABEL) { + return createAzLabelView(parent); + } + if (convertView == null) { holder = createViewHolder(viewType, parent); } else { @@ -2630,27 +2641,29 @@ public class ChooserActivity extends ResolverActivity { @Override public int getItemViewType(int position) { - if (position == 0 && getContentPreviewRowCount() == 1) { - return VIEW_TYPE_CONTENT_PREVIEW; - } + int count; - if (getProfileRowCount() == 1 && position == getContentPreviewRowCount()) { - return VIEW_TYPE_PROFILE; - } + int countSum = (count = getContentPreviewRowCount()); + if (count > 0 && position < countSum) return VIEW_TYPE_CONTENT_PREVIEW; - final int start = getFirstRowPosition(position); - final int startType = mChooserListAdapter.getPositionTargetType(start); + countSum += (count = getProfileRowCount()); + if (count > 0 && position < countSum) return VIEW_TYPE_PROFILE; - if (startType == ChooserListAdapter.TARGET_SERVICE) { - return VIEW_TYPE_DIRECT_SHARE; - } + countSum += (count = getServiceTargetRowCount()); + if (count > 0 && position < countSum) return VIEW_TYPE_DIRECT_SHARE; + + countSum += (count = getCallerAndRankedTargetRowCount()); + if (count > 0 && position < countSum) return VIEW_TYPE_NORMAL; + + countSum += (count = getAzLabelRowCount()); + if (count > 0 && position < countSum) return VIEW_TYPE_AZ_LABEL; return VIEW_TYPE_NORMAL; } @Override public int getViewTypeCount() { - return 4; + return 5; } private ViewGroup createContentPreviewView(View convertView, ViewGroup parent) { @@ -2677,6 +2690,10 @@ public class ChooserActivity extends ResolverActivity { return profileRow; } + private View createAzLabelView(ViewGroup parent) { + return mLayoutInflater.inflate(R.layout.chooser_az_label_row, parent, false); + } + private RowViewHolder loadViewsIntoRow(RowViewHolder holder) { final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED); final int exactSpec = MeasureSpec.makeMeasureSpec(mChooserTargetWidth, @@ -2775,16 +2792,24 @@ public class ChooserActivity extends ResolverActivity { } /** - * Need to merge CALLER + ranked STANDARD into a single row. All other types - * are placed into their own row as determined by their target type, and dividers - * are added in the list to separate each type. + * Need to merge CALLER + ranked STANDARD into a single row and prevent a separator from + * showing on top of the AZ list if the AZ label is visible. All other types are placed into + * their own row as determined by their target type, and dividers are added in the list to + * separate each type. */ int getRowType(int rowPosition) { + // Merge caller and ranked standard into a single row int positionType = mChooserListAdapter.getPositionTargetType(rowPosition); if (positionType == ChooserListAdapter.TARGET_CALLER) { return ChooserListAdapter.TARGET_STANDARD; } + // If an the A-Z label is shown, prevent a separator from appearing by making the A-Z + // row type the same as the suggestion row type + if (getAzLabelRowCount() > 0 && positionType == ChooserListAdapter.TARGET_STANDARD_AZ) { + return ChooserListAdapter.TARGET_STANDARD; + } + return positionType; } @@ -2864,6 +2889,8 @@ public class ChooserActivity extends ResolverActivity { return serviceCount + (row - serviceRows) * getMaxTargetsPerRow(); } + row -= getAzLabelRowCount(); + return callerAndRankedCount + serviceCount + (row - callerAndRankedRows - serviceRows) * getMaxTargetsPerRow(); } diff --git a/core/res/res/layout/chooser_az_label_row.xml b/core/res/res/layout/chooser_az_label_row.xml new file mode 100644 index 0000000000000..1b733fc907cc1 --- /dev/null +++ b/core/res/res/layout/chooser_az_label_row.xml @@ -0,0 +1,31 @@ + + + + + + diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index ef834aa01a360..75fd3a0c04b74 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -5373,4 +5373,7 @@ Direct share not available + + Apps list + diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 7cf03feaf889c..fae0526a6949c 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -3771,4 +3771,6 @@ + + From 849a9d13f0a6b7b010bbc61a1027309a86064da3 Mon Sep 17 00:00:00 2001 From: Mike Digman Date: Mon, 29 Apr 2019 11:20:48 -0700 Subject: [PATCH 2/2] Sharesheet - make az list label disappear with use Following example set by launcher, eventually make a-z list label disappear after n expansions. Done with the Sharedpref associated with ChooserActivity. Test: manual Fixes: 130349817 Change-Id: I2b05982654265804bbc1b3e4821f05ced1e011cd --- .../android/internal/app/ChooserActivity.java | 34 ++++++++++++++++++- .../internal/widget/ResolverDrawerLayout.java | 28 ++++++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 4e2c619f8aa3b..13cbb9b32863b 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -114,6 +114,7 @@ import com.android.internal.config.sysui.SystemUiDeviceConfigFlags; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.util.ImageUtils; +import com.android.internal.widget.ResolverDrawerLayout; import com.google.android.collect.Lists; @@ -143,6 +144,8 @@ public class ChooserActivity extends ResolverActivity { public static final String EXTRA_PRIVATE_RETAIN_IN_ON_STOP = "com.android.internal.app.ChooserActivity.EXTRA_PRIVATE_RETAIN_IN_ON_STOP"; + private static final String PREF_NUM_SHEET_EXPANSIONS = "pref_num_sheet_expansions"; + private static final boolean DEBUG = false; /** @@ -502,6 +505,21 @@ public class ChooserActivity extends ResolverActivity { chooserHeader.setElevation(defaultElevation); } }); + + mResolverDrawerLayout.setOnCollapsedChangedListener( + new ResolverDrawerLayout.OnCollapsedChangedListener() { + + // Only consider one expansion per activity creation + private boolean mWrittenOnce = false; + + @Override + public void onCollapsedChanged(boolean isCollapsed) { + if (!isCollapsed && !mWrittenOnce) { + incrementNumSheetExpansions(); + mWrittenOnce = true; + } + } + }); } if (DEBUG) { @@ -881,6 +899,15 @@ public class ChooserActivity extends ResolverActivity { return CONTENT_PREVIEW_TEXT; } + private int getNumSheetExpansions() { + return getPreferences(Context.MODE_PRIVATE).getInt(PREF_NUM_SHEET_EXPANSIONS, 0); + } + + private void incrementNumSheetExpansions() { + getPreferences(Context.MODE_PRIVATE).edit().putInt(PREF_NUM_SHEET_EXPANSIONS, + getNumSheetExpansions() + 1).apply(); + } + @Override protected void onDestroy() { super.onDestroy(); @@ -2491,6 +2518,7 @@ public class ChooserActivity extends ResolverActivity { private DirectShareViewHolder mDirectShareViewHolder; private int mChooserTargetWidth = 0; + private boolean mShowAzLabelIfPoss; private static final int VIEW_TYPE_DIRECT_SHARE = 0; private static final int VIEW_TYPE_NORMAL = 1; @@ -2501,10 +2529,14 @@ public class ChooserActivity extends ResolverActivity { private static final int MAX_TARGETS_PER_ROW_PORTRAIT = 4; private static final int MAX_TARGETS_PER_ROW_LANDSCAPE = 8; + private static final int NUM_EXPANSIONS_TO_HIDE_AZ_LABEL = 20; + public ChooserRowAdapter(ChooserListAdapter wrappedAdapter) { mChooserListAdapter = wrappedAdapter; mLayoutInflater = LayoutInflater.from(ChooserActivity.this); + mShowAzLabelIfPoss = getNumSheetExpansions() < NUM_EXPANSIONS_TO_HIDE_AZ_LABEL; + wrappedAdapter.registerDataSetObserver(new DataSetObserver() { @Override public void onChanged() { @@ -2597,7 +2629,7 @@ public class ChooserActivity extends ResolverActivity { public int getAzLabelRowCount() { // Only show a label if the a-z list is showing - return mChooserListAdapter.getAlphaTargetCount() > 0 ? 1 : 0; + return (mShowAzLabelIfPoss && mChooserListAdapter.getAlphaTargetCount() > 0) ? 1 : 0; } @Override diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java index 6b0d85ef0b95c..3adb36f5e54bf 100644 --- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java +++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java @@ -104,6 +104,7 @@ public class ResolverDrawerLayout extends ViewGroup { private OnDismissedListener mOnDismissedListener; private RunOnDismissedListener mRunOnDismissedListener; + private OnCollapsedChangedListener mOnCollapsedChangedListener; private boolean mDismissLocked; @@ -267,6 +268,10 @@ public class ResolverDrawerLayout extends ViewGroup { return mOnDismissedListener != null && !mDismissLocked; } + public void setOnCollapsedChangedListener(OnCollapsedChangedListener listener) { + mOnCollapsedChangedListener = listener; + } + @Override public boolean onInterceptTouchEvent(MotionEvent ev) { final int action = ev.getActionMasked(); @@ -548,6 +553,10 @@ public class ResolverDrawerLayout extends ViewGroup { if (mScrollIndicatorDrawable != null) { setWillNotDraw(!isCollapsed); } + + if (mOnCollapsedChangedListener != null) { + mOnCollapsedChangedListener.onCollapsedChanged(isCollapsed); + } } void dispatchOnDismissed() { @@ -1078,8 +1087,25 @@ public class ResolverDrawerLayout extends ViewGroup { }; } + /** + * Listener for sheet dismissed events. + */ public interface OnDismissedListener { - public void onDismissed(); + /** + * Callback when the sheet is dismissed by the user. + */ + void onDismissed(); + } + + /** + * Listener for sheet collapsed / expanded events. + */ + public interface OnCollapsedChangedListener { + /** + * Callback when the sheet is either fully expanded or collapsed. + * @param isCollapsed true when collapsed, false when expanded. + */ + void onCollapsedChanged(boolean isCollapsed); } private class RunOnDismissedListener implements Runnable {