Sharesheet - Move work profile text into list
Move the profile switching logic into the scrollable list area. Fix visual artifact due to reusing drawable. Bug: 130353935 Test: atest ChooserActivityTest + visual inspection Change-Id: I0666b0e61ea696017c2da4854e407d502b7b556c
This commit is contained in:
@@ -199,7 +199,6 @@ public class ChooserActivity extends ResolverActivity {
|
||||
|
||||
private ChooserListAdapter mChooserListAdapter;
|
||||
private ChooserRowAdapter mChooserRowAdapter;
|
||||
private Drawable mChooserRowLayer;
|
||||
private int mChooserRowServiceSpacing;
|
||||
|
||||
/** {@link ChooserActivity#getBaseScore} */
|
||||
@@ -465,7 +464,6 @@ public class ChooserActivity extends ResolverActivity {
|
||||
.registerPredictionUpdates(this.getMainExecutor(), mAppPredictorCallback);
|
||||
}
|
||||
|
||||
mChooserRowLayer = getResources().getDrawable(R.drawable.chooser_row_layer_list, null);
|
||||
mChooserRowServiceSpacing = getResources()
|
||||
.getDimensionPixelSize(R.dimen.chooser_service_spacing);
|
||||
|
||||
@@ -1908,6 +1906,7 @@ public class ChooserActivity extends ResolverActivity {
|
||||
|
||||
int offset = 0;
|
||||
int rowsToShow = mChooserRowAdapter.getContentPreviewRowCount()
|
||||
+ mChooserRowAdapter.getProfileRowCount()
|
||||
+ mChooserRowAdapter.getServiceTargetRowCount()
|
||||
+ mChooserRowAdapter.getCallerAndRankedTargetRowCount();
|
||||
|
||||
@@ -1927,7 +1926,7 @@ public class ChooserActivity extends ResolverActivity {
|
||||
}
|
||||
|
||||
int lastHeight = 0;
|
||||
rowsToShow = Math.max(3, rowsToShow);
|
||||
rowsToShow = Math.min(4, rowsToShow);
|
||||
for (int i = 0; i < Math.min(rowsToShow, mAdapterView.getChildCount()); i++) {
|
||||
lastHeight = mAdapterView.getChildAt(i).getHeight();
|
||||
offset += lastHeight;
|
||||
@@ -2403,6 +2402,7 @@ public class ChooserActivity extends ResolverActivity {
|
||||
private static final int VIEW_TYPE_DIRECT_SHARE = 0;
|
||||
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 MAX_TARGETS_PER_ROW_PORTRAIT = 4;
|
||||
private static final int MAX_TARGETS_PER_ROW_LANDSCAPE = 8;
|
||||
@@ -2458,9 +2458,9 @@ public class ChooserActivity extends ResolverActivity {
|
||||
|
||||
@Override
|
||||
public int getCount() {
|
||||
|
||||
return (int) (
|
||||
getContentPreviewRowCount()
|
||||
+ getProfileRowCount()
|
||||
+ getServiceTargetRowCount()
|
||||
+ getCallerAndRankedTargetRowCount()
|
||||
+ Math.ceil(
|
||||
@@ -2481,6 +2481,10 @@ public class ChooserActivity extends ResolverActivity {
|
||||
return 1;
|
||||
}
|
||||
|
||||
public int getProfileRowCount() {
|
||||
return mChooserListAdapter.getOtherProfile() == null ? 0 : 1;
|
||||
}
|
||||
|
||||
public int getCallerAndRankedTargetRowCount() {
|
||||
return (int) Math.ceil(
|
||||
((float) mChooserListAdapter.getCallerTargetCount()
|
||||
@@ -2516,6 +2520,10 @@ public class ChooserActivity extends ResolverActivity {
|
||||
return createContentPreviewView(convertView, parent);
|
||||
}
|
||||
|
||||
if (viewType == VIEW_TYPE_PROFILE) {
|
||||
return createProfileView(convertView, parent);
|
||||
}
|
||||
|
||||
if (convertView == null) {
|
||||
holder = createViewHolder(viewType, parent);
|
||||
} else {
|
||||
@@ -2533,6 +2541,10 @@ public class ChooserActivity extends ResolverActivity {
|
||||
return VIEW_TYPE_CONTENT_PREVIEW;
|
||||
}
|
||||
|
||||
if (getProfileRowCount() == 1 && position == getContentPreviewRowCount()) {
|
||||
return VIEW_TYPE_PROFILE;
|
||||
}
|
||||
|
||||
final int start = getFirstRowPosition(position);
|
||||
final int startType = mChooserListAdapter.getPositionTargetType(start);
|
||||
|
||||
@@ -2545,7 +2557,7 @@ public class ChooserActivity extends ResolverActivity {
|
||||
|
||||
@Override
|
||||
public int getViewTypeCount() {
|
||||
return 3;
|
||||
return 4;
|
||||
}
|
||||
|
||||
private ViewGroup createContentPreviewView(View convertView, ViewGroup parent) {
|
||||
@@ -2561,6 +2573,17 @@ public class ChooserActivity extends ResolverActivity {
|
||||
(ViewGroup) convertView, parent);
|
||||
}
|
||||
|
||||
private View createProfileView(View convertView, ViewGroup parent) {
|
||||
View profileRow = convertView != null ? convertView : mLayoutInflater.inflate(
|
||||
R.layout.chooser_profile_row, parent, false);
|
||||
profileRow.setBackground(
|
||||
getResources().getDrawable(R.drawable.chooser_row_layer_list, null));
|
||||
mProfileView = profileRow.findViewById(R.id.profile_button);
|
||||
mProfileView.setOnClickListener(ChooserActivity.this::onProfileClick);
|
||||
bindProfileView();
|
||||
return profileRow;
|
||||
}
|
||||
|
||||
private RowViewHolder loadViewsIntoRow(RowViewHolder holder) {
|
||||
final int spec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
|
||||
final int exactSpec = MeasureSpec.makeMeasureSpec(mChooserTargetWidth,
|
||||
@@ -2679,8 +2702,10 @@ public class ChooserActivity extends ResolverActivity {
|
||||
|
||||
final ViewGroup row = holder.getViewGroup();
|
||||
|
||||
if (startType != lastStartType || rowPosition == getContentPreviewRowCount()) {
|
||||
row.setBackground(mChooserRowLayer);
|
||||
if (startType != lastStartType
|
||||
|| rowPosition == getContentPreviewRowCount() + getProfileRowCount()) {
|
||||
row.setBackground(
|
||||
getResources().getDrawable(R.drawable.chooser_row_layer_list, null));
|
||||
} else {
|
||||
row.setBackground(null);
|
||||
}
|
||||
@@ -2730,7 +2755,7 @@ public class ChooserActivity extends ResolverActivity {
|
||||
}
|
||||
|
||||
int getFirstRowPosition(int row) {
|
||||
row -= getContentPreviewRowCount();
|
||||
row -= getContentPreviewRowCount() + getProfileRowCount();
|
||||
|
||||
final int serviceCount = mChooserListAdapter.getServiceTargetCount();
|
||||
final int serviceRows = (int) Math.ceil((float) serviceCount
|
||||
|
||||
@@ -108,7 +108,7 @@ public class ResolverActivity extends Activity {
|
||||
private Button mAlwaysButton;
|
||||
private Button mOnceButton;
|
||||
private Button mSettingsButton;
|
||||
private View mProfileView;
|
||||
protected View mProfileView;
|
||||
private int mIconDpi;
|
||||
private int mLastSelected = AbsListView.INVALID_POSITION;
|
||||
private boolean mResolvingHome = false;
|
||||
@@ -142,9 +142,7 @@ public class ResolverActivity extends Activity {
|
||||
private final PackageMonitor mPackageMonitor = new PackageMonitor() {
|
||||
@Override public void onSomePackagesChanged() {
|
||||
mAdapter.handlePackagesChanged();
|
||||
if (mProfileView != null) {
|
||||
bindProfileView();
|
||||
}
|
||||
bindProfileView();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -336,21 +334,7 @@ public class ResolverActivity extends Activity {
|
||||
|
||||
mProfileView = findViewById(R.id.profile_button);
|
||||
if (mProfileView != null) {
|
||||
mProfileView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
final DisplayResolveInfo dri = mAdapter.getOtherProfile();
|
||||
if (dri == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not show the profile switch message anymore.
|
||||
mProfileSwitchMessageId = -1;
|
||||
|
||||
onTargetSelected(dri, false);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
mProfileView.setOnClickListener(this::onProfileClick);
|
||||
bindProfileView();
|
||||
}
|
||||
|
||||
@@ -367,6 +351,19 @@ public class ResolverActivity extends Activity {
|
||||
+ (categories != null ? Arrays.toString(categories.toArray()) : ""));
|
||||
}
|
||||
|
||||
protected void onProfileClick(View v) {
|
||||
final DisplayResolveInfo dri = mAdapter.getOtherProfile();
|
||||
if (dri == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do not show the profile switch message anymore.
|
||||
mProfileSwitchMessageId = -1;
|
||||
|
||||
onTargetSelected(dri, false);
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
@@ -445,7 +442,11 @@ public class ResolverActivity extends Activity {
|
||||
return R.layout.resolver_list;
|
||||
}
|
||||
|
||||
void bindProfileView() {
|
||||
protected void bindProfileView() {
|
||||
if (mProfileView == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final DisplayResolveInfo dri = mAdapter.getOtherProfile();
|
||||
if (dri != null) {
|
||||
mProfileView.setVisibility(View.VISIBLE);
|
||||
@@ -709,9 +710,7 @@ public class ResolverActivity extends Activity {
|
||||
mRegistered = true;
|
||||
}
|
||||
mAdapter.handlePackagesChanged();
|
||||
if (mProfileView != null) {
|
||||
bindProfileView();
|
||||
}
|
||||
bindProfileView();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1737,9 +1736,7 @@ public class ResolverActivity extends Activity {
|
||||
@Override
|
||||
protected void onPostExecute(List<ResolvedComponentInfo> sortedComponents) {
|
||||
processSortedList(sortedComponents);
|
||||
if (mProfileView != null) {
|
||||
bindProfileView();
|
||||
}
|
||||
bindProfileView();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
};
|
||||
@@ -2148,7 +2145,7 @@ public class ResolverActivity extends Activity {
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Drawable d) {
|
||||
if (mProfileView != null && mAdapter.getOtherProfile() == mDisplayResolveInfo) {
|
||||
if (mAdapter.getOtherProfile() == mDisplayResolveInfo) {
|
||||
bindProfileView();
|
||||
} else {
|
||||
mDisplayResolveInfo.setDisplayIcon(d);
|
||||
|
||||
@@ -41,21 +41,6 @@
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_alignParentTop="true" />
|
||||
|
||||
<TextView android:id="@+id/profile_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:visibility="gone"
|
||||
style="?attr/borderlessButtonStyle"
|
||||
android:textAppearance="?attr/textAppearanceButton"
|
||||
android:textColor="?attr/colorAccent"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_below="@id/drag"
|
||||
android:layout_alignParentRight="true"
|
||||
android:singleLine="true"/>
|
||||
|
||||
<TextView android:id="@+id/title"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
@@ -67,7 +52,7 @@
|
||||
android:paddingBottom="@dimen/chooser_view_spacing"
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingRight="24dp"
|
||||
android:layout_below="@id/profile_button"
|
||||
android:layout_below="@id/drag"
|
||||
android:layout_centerHorizontal="true"/>
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
32
core/res/res/layout/chooser_profile_row.xml
Normal file
32
core/res/res/layout/chooser_profile_row.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
** Copyright 2019, 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.
|
||||
*/
|
||||
-->
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center">
|
||||
<TextView
|
||||
android:id="@+id/profile_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
style="?attr/borderlessButtonStyle"
|
||||
android:textAppearance="?attr/textAppearanceButton"
|
||||
android:textColor="?attr/colorAccent"
|
||||
android:singleLine="true"/>
|
||||
</LinearLayout>
|
||||
|
||||
@@ -2793,6 +2793,7 @@
|
||||
<java-symbol type="drawable" name="scroll_indicator_material" />
|
||||
|
||||
<java-symbol type="layout" name="chooser_row" />
|
||||
<java-symbol type="layout" name="chooser_profile_row" />
|
||||
<java-symbol type="color" name="chooser_row_divider" />
|
||||
<java-symbol type="layout" name="chooser_row_direct_share" />
|
||||
<java-symbol type="bool" name="config_supportDoubleTapWake" />
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.internal.app;
|
||||
|
||||
import static androidx.test.espresso.Espresso.onView;
|
||||
import static androidx.test.espresso.action.ViewActions.click;
|
||||
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
|
||||
import static androidx.test.espresso.assertion.ViewAssertions.matches;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withId;
|
||||
@@ -62,9 +63,6 @@ import com.android.internal.app.ResolverActivity.ResolvedComponentInfo;
|
||||
import com.android.internal.logging.MetricsLogger;
|
||||
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.function.Function;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
@@ -74,7 +72,10 @@ import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* Chooser activity instrumentation tests
|
||||
@@ -245,7 +246,7 @@ public class ChooserActivityTest {
|
||||
waitForIdle();
|
||||
|
||||
assertThat(activity.getAdapter().getCount(), is(2));
|
||||
onView(withId(R.id.profile_button)).check(matches(not(isDisplayed())));
|
||||
onView(withId(R.id.profile_button)).check(doesNotExist());
|
||||
|
||||
ResolveInfo[] chosen = new ResolveInfo[1];
|
||||
sOverrides.onSafelyStartCallback = targetInfo -> {
|
||||
|
||||
Reference in New Issue
Block a user