From 61b4a7e489b3a13f0a012c8d338ed63a3d3cf505 Mon Sep 17 00:00:00 2001 From: Joshua Trask Date: Wed, 27 Sep 2023 18:51:45 +0000 Subject: Introduce EmptyStateUiHelper (& initial tests) Based on prototype work in ag/24516421, this CL introduces a new component to handle the empty-state UI implementation details that had previously been implemented in `MultiProfilePagerAdapter`, since those details significantly clutter the implementation of that adapter's other responsibilities. As in ag/24516421 patchset #4, this just sets up the boilerplate and kicks off with some "low-hanging-fruit" operations. Follow-up CLs will continue migrating these responsibilities as in ag/24516421 (except with more incremental testing). Bug: 302311217 Test: IntentResolverUnitTests, CtsSharesheetDeviceTest Change-Id: Ie9bb7f4e97836321521c3cf13c77cafc97b1a461 --- .../intentresolver/MultiProfilePagerAdapter.java | 38 ++++--------- .../emptystate/EmptyStateUiHelper.java | 63 ++++++++++++++++++++++ 2 files changed, 73 insertions(+), 28 deletions(-) create mode 100644 java/src/com/android/intentresolver/emptystate/EmptyStateUiHelper.java (limited to 'java/src/com') diff --git a/java/src/com/android/intentresolver/MultiProfilePagerAdapter.java b/java/src/com/android/intentresolver/MultiProfilePagerAdapter.java index 2c98d89f..8c640dd3 100644 --- a/java/src/com/android/intentresolver/MultiProfilePagerAdapter.java +++ b/java/src/com/android/intentresolver/MultiProfilePagerAdapter.java @@ -29,6 +29,7 @@ import androidx.viewpager.widget.ViewPager; import com.android.intentresolver.emptystate.EmptyState; import com.android.intentresolver.emptystate.EmptyStateProvider; +import com.android.intentresolver.emptystate.EmptyStateUiHelper; import com.android.internal.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; @@ -424,7 +425,7 @@ public class MultiProfilePagerAdapter< clickListener = v -> emptyState.getButtonClickListener().onClick(() -> { ProfileDescriptor descriptor = getItem( userHandleToPageIndex(listAdapter.getUserHandle())); - MultiProfilePagerAdapter.this.showSpinner(descriptor.getEmptyStateView()); + descriptor.mEmptyStateUi.showSpinner(); }); } @@ -451,9 +452,9 @@ public class MultiProfilePagerAdapter< userHandleToPageIndex(activeListAdapter.getUserHandle())); descriptor.mRootView.findViewById( com.android.internal.R.id.resolver_list).setVisibility(View.GONE); + descriptor.mEmptyStateUi.resetViewVisibilities(); + ViewGroup emptyStateView = descriptor.getEmptyStateView(); - resetViewVisibilitiesForEmptyState(emptyStateView); - emptyStateView.setVisibility(View.VISIBLE); View container = emptyStateView.findViewById( com.android.internal.R.id.resolver_empty_state_container); @@ -504,36 +505,12 @@ public class MultiProfilePagerAdapter< paddingBottom)); } - private void showSpinner(View emptyStateView) { - emptyStateView.findViewById(com.android.internal.R.id.resolver_empty_state_title) - .setVisibility(View.INVISIBLE); - emptyStateView.findViewById(com.android.internal.R.id.resolver_empty_state_button) - .setVisibility(View.INVISIBLE); - emptyStateView.findViewById(com.android.internal.R.id.resolver_empty_state_progress) - .setVisibility(View.VISIBLE); - emptyStateView.findViewById(com.android.internal.R.id.empty).setVisibility(View.GONE); - } - - private void resetViewVisibilitiesForEmptyState(View emptyStateView) { - emptyStateView.findViewById(com.android.internal.R.id.resolver_empty_state_title) - .setVisibility(View.VISIBLE); - emptyStateView.findViewById(com.android.internal.R.id.resolver_empty_state_subtitle) - .setVisibility(View.VISIBLE); - emptyStateView.findViewById(com.android.internal.R.id.resolver_empty_state_button) - .setVisibility(View.INVISIBLE); - emptyStateView.findViewById(com.android.internal.R.id.resolver_empty_state_progress) - .setVisibility(View.GONE); - emptyStateView.findViewById(com.android.internal.R.id.empty).setVisibility(View.GONE); - } - protected void showListView(ListAdapterT activeListAdapter) { ProfileDescriptor descriptor = getItem( userHandleToPageIndex(activeListAdapter.getUserHandle())); descriptor.mRootView.findViewById( com.android.internal.R.id.resolver_list).setVisibility(View.VISIBLE); - View emptyStateView = descriptor.mRootView.findViewById( - com.android.internal.R.id.resolver_empty_state); - emptyStateView.setVisibility(View.GONE); + descriptor.mEmptyStateUi.hide(); } public boolean shouldShowEmptyStateScreen(ListAdapterT listAdapter) { @@ -547,6 +524,10 @@ public class MultiProfilePagerAdapter< // should be the owner of all per-profile data (especially now that the API is generic)? private static class ProfileDescriptor { final ViewGroup mRootView; + final EmptyStateUiHelper mEmptyStateUi; + + // TODO: post-refactoring, we may not need to retain these ivars directly (since they may + // be encapsulated within the `EmptyStateUiHelper`?). private final ViewGroup mEmptyStateView; private final SinglePageAdapterT mAdapter; @@ -557,6 +538,7 @@ public class MultiProfilePagerAdapter< mAdapter = adapter; mEmptyStateView = rootView.findViewById(com.android.internal.R.id.resolver_empty_state); mView = (PageViewT) rootView.findViewById(com.android.internal.R.id.resolver_list); + mEmptyStateUi = new EmptyStateUiHelper(rootView); } protected ViewGroup getEmptyStateView() { diff --git a/java/src/com/android/intentresolver/emptystate/EmptyStateUiHelper.java b/java/src/com/android/intentresolver/emptystate/EmptyStateUiHelper.java new file mode 100644 index 00000000..d7ef8c75 --- /dev/null +++ b/java/src/com/android/intentresolver/emptystate/EmptyStateUiHelper.java @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2023 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. + */ +package com.android.intentresolver.emptystate; + +import android.view.View; +import android.view.ViewGroup; + +/** + * Helper for building `MultiProfilePagerAdapter` tab UIs for profile tabs that are "blocked" by + * some empty-state status. + */ +public class EmptyStateUiHelper { + private final View mEmptyStateView; + + public EmptyStateUiHelper(ViewGroup rootView) { + mEmptyStateView = + rootView.requireViewById(com.android.internal.R.id.resolver_empty_state); + } + + public void resetViewVisibilities() { + mEmptyStateView.requireViewById(com.android.internal.R.id.resolver_empty_state_title) + .setVisibility(View.VISIBLE); + mEmptyStateView.requireViewById(com.android.internal.R.id.resolver_empty_state_subtitle) + .setVisibility(View.VISIBLE); + mEmptyStateView.requireViewById(com.android.internal.R.id.resolver_empty_state_button) + .setVisibility(View.INVISIBLE); + mEmptyStateView.requireViewById(com.android.internal.R.id.resolver_empty_state_progress) + .setVisibility(View.GONE); + mEmptyStateView.requireViewById(com.android.internal.R.id.empty) + .setVisibility(View.GONE); + mEmptyStateView.setVisibility(View.VISIBLE); + } + + public void showSpinner() { + mEmptyStateView.requireViewById(com.android.internal.R.id.resolver_empty_state_title) + .setVisibility(View.INVISIBLE); + // TODO: subtitle? + mEmptyStateView.requireViewById(com.android.internal.R.id.resolver_empty_state_button) + .setVisibility(View.INVISIBLE); + mEmptyStateView.requireViewById(com.android.internal.R.id.resolver_empty_state_progress) + .setVisibility(View.VISIBLE); + mEmptyStateView.requireViewById(com.android.internal.R.id.empty) + .setVisibility(View.GONE); + } + + public void hide() { + mEmptyStateView.setVisibility(View.GONE); + } +} + -- cgit v1.2.3-59-g8ed1b