Merge "Scroll to the selected widget picker row after headers are clicked" into sc-dev am: f15214597e

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/14800533

Change-Id: I1107db2070a28d7de9ae2450760c9ac38108ee59
This commit is contained in:
Stevie Kideckel 2021-06-03 14:30:05 +00:00 committed by Automerger Merge Worker
commit f94a93ad2c
1 changed files with 51 additions and 4 deletions

View File

@ -25,6 +25,7 @@ import android.view.View.OnLongClickListener;
import android.view.ViewGroup;
import android.widget.TableRow;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.Adapter;
@ -48,8 +49,10 @@ import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.OptionalInt;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
/**
* Recycler view adapter for the widget tray.
@ -87,6 +90,7 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
|| new PackageUserKey(entry.mPkgItem.packageName, entry.mPkgItem.user)
.equals(mWidgetsContentVisiblePackageUserKey);
@Nullable private Predicate<WidgetsListBaseEntry> mFilter = null;
@Nullable private RecyclerView mRecyclerView;
public WidgetsListAdapter(Context context, LayoutInflater layoutInflater,
WidgetPreviewLoader widgetPreviewLoader, IconCache iconCache,
@ -106,6 +110,16 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
layoutInflater, /*onHeaderClickListener=*/ this, /* listAdapter= */ this));
}
@Override
public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) {
mRecyclerView = recyclerView;
}
@Override
public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) {
mRecyclerView = null;
}
public void setFilter(Predicate<WidgetsListBaseEntry> filter) {
mFilter = filter;
}
@ -168,12 +182,10 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
mAllEntries.forEach(entry -> {
if (entry instanceof WidgetsListHeaderEntry) {
((WidgetsListHeaderEntry) entry).setIsWidgetListShown(
new PackageUserKey(entry.mPkgItem.packageName, entry.mPkgItem.user)
.equals(mWidgetsContentVisiblePackageUserKey));
isHeaderForVisibleContent(entry));
} else if (entry instanceof WidgetsListSearchHeaderEntry) {
((WidgetsListSearchHeaderEntry) entry).setIsWidgetListShown(
new PackageUserKey(entry.mPkgItem.packageName, entry.mPkgItem.user)
.equals(mWidgetsContentVisiblePackageUserKey));
isHeaderForVisibleContent(entry));
}
});
List<WidgetsListBaseEntry> newVisibleEntries = mAllEntries.stream()
@ -183,6 +195,13 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
mDiffReporter.process(mVisibleEntries, newVisibleEntries, mRowComparator);
}
private boolean isHeaderForVisibleContent(WidgetsListBaseEntry entry) {
return (entry instanceof WidgetsListHeaderEntry
|| entry instanceof WidgetsListSearchHeaderEntry)
&& new PackageUserKey(entry.mPkgItem.packageName, entry.mPkgItem.user)
.equals(mWidgetsContentVisiblePackageUserKey);
}
/**
* Resets any expanded widget header.
*/
@ -247,12 +266,40 @@ public class WidgetsListAdapter extends Adapter<ViewHolder> implements OnHeaderC
if (showWidgets) {
mWidgetsContentVisiblePackageUserKey = packageUserKey;
updateVisibleEntries();
// Scroll the layout manager to the header position to keep it anchored to the same
// position.
scrollToSelectedHeaderPosition();
} else if (packageUserKey.equals(mWidgetsContentVisiblePackageUserKey)) {
mWidgetsContentVisiblePackageUserKey = null;
updateVisibleEntries();
}
}
private void scrollToSelectedHeaderPosition() {
OptionalInt selectedHeaderPosition =
IntStream.range(0, mVisibleEntries.size())
.filter(index -> isHeaderForVisibleContent(mVisibleEntries.get(index)))
.findFirst();
RecyclerView.LayoutManager layoutManager =
mRecyclerView == null ? null : mRecyclerView.getLayoutManager();
if (!selectedHeaderPosition.isPresent() || layoutManager == null) {
return;
}
// Scroll to the selected header position. LinearLayoutManager scrolls the minimum distance
// necessary, so this will keep the selected header in place during clicks, without
// interrupting the animation.
int position = selectedHeaderPosition.getAsInt();
if (position == mVisibleEntries.size() - 2) {
// If the selected header is in the last position (-1 for the content), then scroll to
// the final position so the last list of widgets will show.
layoutManager.scrollToPosition(mVisibleEntries.size() - 1);
} else {
// Otherwise, scroll to the position of the selected header.
layoutManager.scrollToPosition(position);
}
}
/**
* Sets the max horizontal spans that are allowed for grouping more than one widgets in a table
* row.