Merge "Fix flicker of QS footer actions when restarting SystemUI (1/2)" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
5818342a25
@@ -120,6 +120,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
|
||||
private final QSLogger mLogger;
|
||||
private final FooterActionsController mFooterActionsController;
|
||||
private final FooterActionsViewModel.Factory mFooterActionsViewModelFactory;
|
||||
private final FooterActionsViewBinder mFooterActionsViewBinder;
|
||||
private final ListeningAndVisibilityLifecycleOwner mListeningAndVisibilityLifecycleOwner;
|
||||
private boolean mShowCollapsedOnKeyguard;
|
||||
private boolean mLastKeyguardAndExpanded;
|
||||
@@ -177,6 +178,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
|
||||
DumpManager dumpManager, QSLogger qsLogger,
|
||||
FooterActionsController footerActionsController,
|
||||
FooterActionsViewModel.Factory footerActionsViewModelFactory,
|
||||
FooterActionsViewBinder footerActionsViewBinder,
|
||||
LargeScreenShadeInterpolator largeScreenShadeInterpolator,
|
||||
FeatureFlags featureFlags) {
|
||||
mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
|
||||
@@ -193,6 +195,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
|
||||
mDumpManager = dumpManager;
|
||||
mFooterActionsController = footerActionsController;
|
||||
mFooterActionsViewModelFactory = footerActionsViewModelFactory;
|
||||
mFooterActionsViewBinder = footerActionsViewBinder;
|
||||
mListeningAndVisibilityLifecycleOwner = new ListeningAndVisibilityLifecycleOwner();
|
||||
}
|
||||
|
||||
@@ -285,7 +288,7 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
|
||||
|
||||
if (!ComposeFacade.INSTANCE.isComposeAvailable()) {
|
||||
Log.d(TAG, "Binding the View implementation of the QS footer actions");
|
||||
FooterActionsViewBinder.bind(footerActionsView, mQSFooterActionsViewModel,
|
||||
mFooterActionsViewBinder.bind(footerActionsView, mQSFooterActionsViewModel,
|
||||
mListeningAndVisibilityLifecycleOwner);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -33,27 +33,27 @@ import androidx.lifecycle.repeatOnLifecycle
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.animation.Expandable
|
||||
import com.android.systemui.common.ui.binder.IconViewBinder
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.lifecycle.repeatWhenAttached
|
||||
import com.android.systemui.people.ui.view.PeopleViewBinder.bind
|
||||
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsButtonViewModel
|
||||
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsForegroundServicesButtonViewModel
|
||||
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsSecurityButtonViewModel
|
||||
import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsViewModel
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.roundToInt
|
||||
import kotlinx.coroutines.flow.collect
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/** A ViewBinder for [FooterActionsViewBinder]. */
|
||||
object FooterActionsViewBinder {
|
||||
@SysUISingleton
|
||||
class FooterActionsViewBinder @Inject constructor() {
|
||||
/** Create a view that can later be [bound][bind] to a [FooterActionsViewModel]. */
|
||||
@JvmStatic
|
||||
fun create(context: Context): LinearLayout {
|
||||
return LayoutInflater.from(context).inflate(R.layout.footer_actions, /* root= */ null)
|
||||
as LinearLayout
|
||||
}
|
||||
|
||||
/** Bind [view] to [viewModel]. */
|
||||
@JvmStatic
|
||||
fun bind(
|
||||
view: LinearLayout,
|
||||
viewModel: FooterActionsViewModel,
|
||||
@@ -98,6 +98,11 @@ object FooterActionsViewBinder {
|
||||
var previousForegroundServices: FooterActionsForegroundServicesButtonViewModel? = null
|
||||
var previousUserSwitcher: FooterActionsButtonViewModel? = null
|
||||
|
||||
// Set the initial visibility on the View directly so that we don't briefly show it for a
|
||||
// few frames before [viewModel.isVisible] is collected.
|
||||
view.isInvisible = !viewModel.isVisible.value
|
||||
|
||||
// Listen for ViewModel updates when the View is attached.
|
||||
view.repeatWhenAttached {
|
||||
val attachedScope = this.lifecycleScope
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ class FooterActionsViewModel(
|
||||
* the UI should still participate to the layout it is included in (i.e. in the View world it
|
||||
* should be INVISIBLE, not GONE).
|
||||
*/
|
||||
private val _isVisible = MutableStateFlow(true)
|
||||
private val _isVisible = MutableStateFlow(false)
|
||||
val isVisible: StateFlow<Boolean> = _isVisible.asStateFlow()
|
||||
|
||||
/** The alpha the UI rendering this ViewModel should have. */
|
||||
|
||||
@@ -106,6 +106,7 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
|
||||
@Mock private QSSquishinessController mSquishinessController;
|
||||
@Mock private FooterActionsViewModel mFooterActionsViewModel;
|
||||
@Mock private FooterActionsViewModel.Factory mFooterActionsViewModelFactory;
|
||||
@Mock private FooterActionsViewBinder mFooterActionsViewBinder;
|
||||
@Mock private LargeScreenShadeInterpolator mLargeScreenShadeInterpolator;
|
||||
@Mock private FeatureFlags mFeatureFlags;
|
||||
private View mQsFragmentView;
|
||||
@@ -558,6 +559,7 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
|
||||
mock(QSLogger.class),
|
||||
mock(FooterActionsController.class),
|
||||
mFooterActionsViewModelFactory,
|
||||
mFooterActionsViewBinder,
|
||||
mLargeScreenShadeInterpolator,
|
||||
mFeatureFlags);
|
||||
}
|
||||
@@ -584,7 +586,7 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
|
||||
when(mQsFragmentView.findViewById(R.id.header)).thenReturn(mHeader);
|
||||
when(mQsFragmentView.findViewById(android.R.id.edit)).thenReturn(new View(mContext));
|
||||
when(mQsFragmentView.findViewById(R.id.qs_footer_actions)).thenAnswer(
|
||||
invocation -> FooterActionsViewBinder.create(mContext));
|
||||
invocation -> new FooterActionsViewBinder().create(mContext));
|
||||
}
|
||||
|
||||
private void setUpInflater() {
|
||||
|
||||
@@ -376,13 +376,13 @@ class FooterActionsViewModelTest : SysuiTestCase() {
|
||||
@Test
|
||||
fun isVisible() {
|
||||
val underTest = utils.footerActionsViewModel()
|
||||
assertThat(underTest.isVisible.value).isTrue()
|
||||
|
||||
underTest.onVisibilityChangeRequested(visible = false)
|
||||
assertThat(underTest.isVisible.value).isFalse()
|
||||
|
||||
underTest.onVisibilityChangeRequested(visible = true)
|
||||
assertThat(underTest.isVisible.value).isTrue()
|
||||
|
||||
underTest.onVisibilityChangeRequested(visible = false)
|
||||
assertThat(underTest.isVisible.value).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user