Align 'No widgets available' text box properly in Widget picker.
Bug: 186209657
Test: Tested manually
Change-Id: I85fa43cd745a8c9f9601d25ed3a35f512506234d
diff --git a/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java b/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java
index 6781824..6643779 100644
--- a/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java
+++ b/src/com/android/launcher3/widget/picker/SearchAndRecommendationsScrollController.java
@@ -21,6 +21,7 @@
import android.view.View;
import android.view.ViewGroup.MarginLayoutParams;
import android.widget.RelativeLayout;
+import android.widget.TextView;
import androidx.annotation.Nullable;
@@ -39,9 +40,11 @@
private final View mSearchAndRecommendationViewParent;
private final WidgetsRecyclerView mPrimaryRecyclerView;
private final WidgetsRecyclerView mSearchRecyclerView;
+ private final TextView mNoWidgetsView;
private final int mTabsHeight;
private final ValueAnimator mAnimator = ValueAnimator.ofInt(0, 0);
private final Point mTempOffset = new Point();
+ private int mBottomInset;
// The following are only non null if mHasWorkProfile is true.
@Nullable private final WidgetsRecyclerView mWorkRecyclerView;
@@ -81,7 +84,8 @@
@Nullable WidgetsRecyclerView workRecyclerView,
WidgetsRecyclerView searchRecyclerView,
@Nullable View personalWorkTabsView,
- @Nullable PersonalWorkPagedView primaryWorkViewPager) {
+ @Nullable PersonalWorkPagedView primaryWorkViewPager,
+ TextView noWidgetsView) {
mHasWorkProfile = hasWorkProfile;
mViewHolder = viewHolder;
mViewHolder.mContainer.setSearchAndRecommendationScrollController(this);
@@ -92,6 +96,7 @@
mPrimaryWorkTabsView = personalWorkTabsView;
mPrimaryWorkViewPager = primaryWorkViewPager;
mTabsHeight = tabsHeight;
+ mNoWidgetsView = noWidgetsView;
setCurrentRecyclerView(mPrimaryRecyclerView, /* animateReset= */ false);
}
@@ -114,6 +119,15 @@
}
/**
+ * Updates padding of {@link WidgetsFullSheet} contents to include {@code bottomInset} wherever
+ * necessary.
+ */
+ public boolean updateBottomInset(int bottomInset) {
+ mBottomInset = bottomInset;
+ return updateMarginAndPadding();
+ }
+
+ /**
* Updates the margin and padding of {@link WidgetsFullSheet} to accumulate collapsible views.
*
* @return {@code true} if margins or/and padding of views in the search and recommendations
@@ -129,6 +143,8 @@
+ measureHeightWithVerticalMargins(mViewHolder.mRecommendedWidgetsTable);
int topContainerHeight = measureHeightWithVerticalMargins(mViewHolder.mContainer);
+ int noWidgetsViewHeight = topContainerHeight - mBottomInset;
+
if (mHasWorkProfile) {
mCollapsibleHeightForTabs = measureHeightWithVerticalMargins(mViewHolder.mHeaderTitle)
+ measureHeightWithVerticalMargins(mViewHolder.mRecommendedWidgetsTable);
@@ -180,6 +196,10 @@
int topOffsetAfterAllViewsCollapsed =
topContainerHeight + mTabsHeight - mCollapsibleHeightForTabs;
+ if (mPrimaryWorkTabsView.getVisibility() == View.VISIBLE) {
+ noWidgetsViewHeight += mTabsHeight;
+ }
+
RelativeLayout.LayoutParams viewPagerLayoutParams =
(RelativeLayout.LayoutParams) mPrimaryWorkViewPager.getLayoutParams();
if (viewPagerLayoutParams.topMargin != topOffsetAfterAllViewsCollapsed) {
@@ -222,6 +242,14 @@
mSearchRecyclerView.getPaddingBottom());
hasMarginOrPaddingUpdated = true;
}
+ if (mNoWidgetsView.getPaddingTop() != noWidgetsViewHeight) {
+ mNoWidgetsView.setPadding(
+ mNoWidgetsView.getPaddingLeft(),
+ noWidgetsViewHeight,
+ mNoWidgetsView.getPaddingRight(),
+ mNoWidgetsView.getPaddingBottom());
+ hasMarginOrPaddingUpdated = true;
+ }
return hasMarginOrPaddingUpdated;
}
diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
index 42ff249..039cad8 100644
--- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
+++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java
@@ -92,8 +92,8 @@
private final boolean mHasWorkProfile;
private final SparseArray<AdapterHolder> mAdapters = new SparseArray();
private final UserHandle mCurrentUser = Process.myUserHandle();
- private final Predicate<WidgetsListBaseEntry> mPrimaryWidgetsFilter = entry ->
- mCurrentUser.equals(entry.mPkgItem.user);
+ private final Predicate<WidgetsListBaseEntry> mPrimaryWidgetsFilter =
+ entry -> mCurrentUser.equals(entry.mPkgItem.user);
private final Predicate<WidgetsListBaseEntry> mWorkWidgetsFilter =
mPrimaryWidgetsFilter.negate();
private final OnLayoutChangeListener mLayoutChangeListenerToShowTips =
@@ -131,6 +131,7 @@
@Nullable private WidgetsRecyclerView mCurrentWidgetsRecyclerView;
@Nullable private PersonalWorkPagedView mViewPager;
private boolean mIsInSearchMode;
+ private boolean mIsNoWidgetsViewNeeded;
private int mMaxSpansPerRow = 4;
private View mTabsView;
private TextView mNoWidgetsView;
@@ -187,6 +188,7 @@
layoutInflater.inflate(R.layout.widgets_full_sheet_search_and_recommendations, springLayout,
true);
+ mNoWidgetsView = findViewById(R.id.no_widgets_text);
mSearchAndRecommendationViewHolder = new SearchAndRecommendationViewHolder(
findViewById(R.id.search_and_recommendations_container));
mSearchAndRecommendationsScrollController = new SearchAndRecommendationsScrollController(
@@ -197,10 +199,10 @@
mHasWorkProfile ? findViewById(R.id.work_widgets_list_view) : null,
findViewById(R.id.search_widgets_list_view),
mTabsView,
- mViewPager);
+ mViewPager,
+ mNoWidgetsView);
fastScroller.setOnFastScrollChangeListener(mSearchAndRecommendationsScrollController);
- mNoWidgetsView = findViewById(R.id.no_widgets_text);
onRecommendedWidgetsBound();
onWidgetsBound();
@@ -295,6 +297,7 @@
if (mHasWorkProfile) {
setBottomPadding(mAdapters.get(AdapterHolder.WORK).mWidgetsRecyclerView, insets.bottom);
}
+ mSearchAndRecommendationsScrollController.updateBottomInset(insets.bottom);
if (insets.bottom > 0) {
setupNavBarColor();
} else {
@@ -410,6 +413,16 @@
} else {
updateRecyclerViewVisibility(primaryUserAdapterHolder);
}
+ // Update recommended widgets section so that it occupies appropriate space on screen to
+ // leave enough space for presence/absence of mNoWidgetsView.
+ boolean isNoWidgetsViewNeeded =
+ mAdapters.get(AdapterHolder.PRIMARY).mWidgetsListAdapter.getItemCount() == 0
+ || (mHasWorkProfile && mAdapters.get(AdapterHolder.WORK)
+ .mWidgetsListAdapter.getItemCount() == 0);
+ if (mIsNoWidgetsViewNeeded != isNoWidgetsViewNeeded) {
+ mIsNoWidgetsViewNeeded = isNoWidgetsViewNeeded;
+ onRecommendedWidgetsBound();
+ }
}
@Override
@@ -476,9 +489,19 @@
WidgetsRecommendationTableLayout table =
mSearchAndRecommendationViewHolder.mRecommendedWidgetsTable;
if (recommendedWidgets.size() > 0) {
- float maxTableHeight =
- (mActivityContext.getDeviceProfile().availableHeightPx - mTabsHeight
- - getHeaderViewHeight()) * RECOMMENDATION_TABLE_HEIGHT_RATIO;
+ float noWidgetsViewHeight = 0;
+ if (mIsNoWidgetsViewNeeded) {
+ // Make sure recommended section leaves enough space for noWidgetsView.
+ Rect noWidgetsViewTextBounds = new Rect();
+ mNoWidgetsView.getPaint()
+ .getTextBounds(mNoWidgetsView.getText().toString(), /* start= */ 0,
+ mNoWidgetsView.getText().length(), noWidgetsViewTextBounds);
+ noWidgetsViewHeight = noWidgetsViewTextBounds.height();
+ }
+ float maxTableHeight = (mActivityContext.getDeviceProfile().availableHeightPx
+ - mTabsHeight - getHeaderViewHeight() - noWidgetsViewHeight)
+ * RECOMMENDATION_TABLE_HEIGHT_RATIO;
+
List<ArrayList<WidgetItem>> recommendedWidgetsInTable =
WidgetsTableUtils.groupWidgetItemsIntoTable(recommendedWidgets,
mMaxSpansPerRow);