Tv pip menu design update (1)

PiP window stays where it is instead of moving to the center and
the menu buttons are shown on centered on the pip instead of below
the window.

Additionally disabled menu items are removed to avoid cluttering.

Bug: 201270615
Test: manual
Change-Id: I9af5dc04dd0999d61add88a3475c697b376034d0
This commit is contained in:
Jacqueline Bronger
2021-09-28 10:02:51 +00:00
parent ba5d54e9a2
commit 1eeea7c0c5
14 changed files with 201 additions and 205 deletions

View File

@@ -27,11 +27,11 @@
<!-- The percentage of the screen width to use for the default width or height of
picture-in-picture windows. Regardless of the percent set here, calculated size will never
be smaller than @dimen/default_minimal_size_pip_resizable_task. -->
<item name="config_pictureInPictureDefaultSizePercent" format="float" type="dimen">0.14</item>
<item name="config_pictureInPictureDefaultSizePercent" format="float" type="dimen">0.2</item>
<!-- Default insets [LEFT/RIGHTxTOP/BOTTOM] from the screen edge for picture-in-picture windows.
These values are in DPs and will be converted to pixel sizes internally. -->
<string translatable="false" name="config_defaultPictureInPictureScreenEdgeInsets">56x27</string>
<string translatable="false" name="config_defaultPictureInPictureScreenEdgeInsets">24x24</string>
<!-- The default gravity for the picture-in-picture window.
Currently, this maps to Gravity.BOTTOM | Gravity.RIGHT -->

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2021 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true"
android:color="@color/tv_pip_menu_icon_focused" />
<item android:state_enabled="false"
android:color="@color/tv_pip_menu_icon_disabled" />
<item android:color="@color/tv_pip_menu_icon_unfocused" />
</selector>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2021 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true"
android:color="@color/tv_pip_menu_icon_bg_focused" />
<item android:color="@color/tv_pip_menu_icon_bg_unfocused" />
</selector>

View File

@@ -14,5 +14,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="#9AFFFFFF" android:radius="17dp" />
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/pip_menu_button_radius" />
<solid android:color="@color/tv_pip_menu_icon_bg" />
</shape>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2021 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.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/pip_menu_border_radius" />
<stroke android:width="@dimen/pip_menu_border_width"
android:color="@color/tv_pip_menu_focus_border" />
</shape>

View File

@@ -18,35 +18,54 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tv_pip_menu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#CC000000">
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/tv_pip_menu_action_buttons"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="350dp"
android:orientation="horizontal"
android:alpha="0">
<FrameLayout
android:id="@+id/tv_pip_menu_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:alpha="0" >
<com.android.wm.shell.pip.tv.TvPipMenuActionButton
android:id="@+id/tv_pip_menu_fullscreen_button"
android:layout_width="@dimen/picture_in_picture_button_width"
android:layout_height="wrap_content"
android:src="@drawable/pip_ic_fullscreen_white"
android:text="@string/pip_fullscreen" />
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:gravity="center"
android:scrollbars="none"
android:requiresFadingEdge="vertical"
android:fadingEdgeLength="30dp">
<com.android.wm.shell.pip.tv.TvPipMenuActionButton
android:id="@+id/tv_pip_menu_close_button"
android:layout_width="@dimen/picture_in_picture_button_width"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/picture_in_picture_button_start_margin"
android:src="@drawable/pip_ic_close_white"
android:text="@string/pip_close" />
<LinearLayout
android:id="@+id/tv_pip_menu_action_buttons"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingStart="@dimen/pip_menu_button_wrapper_margin"
android:paddingEnd="@dimen/pip_menu_button_wrapper_margin"
android:gravity="center"
android:orientation="horizontal">
<!-- More TvPipMenuActionButtons may be added here at runtime. -->
<com.android.wm.shell.pip.tv.TvPipMenuActionButton
android:id="@+id/tv_pip_menu_fullscreen_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/pip_ic_fullscreen_white"
android:text="@string/pip_fullscreen" />
</LinearLayout>
<com.android.wm.shell.pip.tv.TvPipMenuActionButton
android:id="@+id/tv_pip_menu_close_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/pip_ic_close_white"
android:text="@string/pip_close" />
<!-- More TvPipMenuActionButtons may be added here at runtime. -->
</LinearLayout>
</HorizontalScrollView>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/tv_pip_menu_border"/>
</FrameLayout>
</FrameLayout>

View File

@@ -15,36 +15,20 @@
limitations under the License.
-->
<!-- Layout for TvPipMenuActionButton -->
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/button"
android:layout_width="@dimen/pip_menu_button_size"
android:layout_height="@dimen/pip_menu_button_size"
android:layout_marginStart="@dimen/pip_menu_button_margin"
android:layout_marginEnd="@dimen/pip_menu_button_margin"
android:background="@drawable/tv_pip_button_bg"
android:focusable="true">
<ImageView android:id="@+id/button"
android:layout_width="34dp"
android:layout_height="34dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:focusable="true"
android:src="@drawable/tv_pip_button_focused"
android:importantForAccessibility="yes" />
<ImageView android:id="@+id/icon"
android:layout_width="34dp"
android:layout_height="34dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:padding="5dp"
android:importantForAccessibility="no" />
<TextView android:id="@+id/desc"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:layout_below="@id/icon"
android:layout_centerHorizontal="true"
android:layout_marginTop="3dp"
android:gravity="center"
android:text="@string/pip_fullscreen"
android:alpha="0"
android:fontFamily="sans-serif"
android:textSize="12sp"
android:textColor="#EEEEEE"
android:importantForAccessibility="no" />
</merge>
<ImageView android:id="@+id/icon"
android:layout_width="@dimen/pip_menu_icon_size"
android:layout_height="@dimen/pip_menu_icon_size"
android:layout_gravity="center"
android:duplicateParentState="true"
android:tint="@color/tv_pip_menu_icon" />
</FrameLayout>

View File

@@ -1,21 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2020 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.
-->
<com.android.wm.shell.pip.tv.TvPipMenuActionButton
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/picture_in_picture_button_width"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/picture_in_picture_button_start_margin" />

View File

@@ -16,7 +16,12 @@
-->
<resources>
<!-- The dimensions to user for picture-in-picture action buttons. -->
<dimen name="picture_in_picture_button_width">100dp</dimen>
<dimen name="picture_in_picture_button_start_margin">-50dp</dimen>
<dimen name="pip_menu_button_size">40dp</dimen>
<dimen name="pip_menu_button_radius">20dp</dimen>
<dimen name="pip_menu_icon_size">20dp</dimen>
<dimen name="pip_menu_button_margin">4dp</dimen>
<dimen name="pip_menu_button_wrapper_margin">26dp</dimen>
<dimen name="pip_menu_border_width">2dp</dimen>
<dimen name="pip_menu_border_radius">0dp</dimen>
</resources>

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (C) 2021 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.
-->
<resources>
<color name="tv_pip_menu_icon_focused">#0E0E0F</color>
<color name="tv_pip_menu_icon_unfocused">#E8EAED</color>
<color name="tv_pip_menu_icon_disabled">#80868B</color>
<color name="tv_pip_menu_icon_bg_focused">#E8EAED</color>
<color name="tv_pip_menu_icon_bg_unfocused">#777777</color>
<color name="tv_pip_menu_focus_border">#CCE8EAED</color>
</resources>

View File

@@ -253,9 +253,6 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
final Rect newBounds;
switch (mState) {
case STATE_PIP_MENU:
newBounds = mPipBoundsState.getExpandedBounds();
break;
case STATE_PIP:
// Let PipBoundsAlgorithm figure out what the correct bounds are at the moment.
// Internally, it will get the "default" bounds from PipBoundsState and adjust them
@@ -336,11 +333,6 @@ public class TvPipController implements PipTransitionController.PipTransitionCal
private void loadConfigurations() {
final Resources res = mContext.getResources();
mResizeAnimationDuration = res.getInteger(R.integer.config_pipResizeAnimationDuration);
// "Cache" bounds for the Pip menu as "expanded" bounds in PipBoundsState. We'll refer back
// to this value in resizePinnedStack(), when we are adjusting Pip task/window position for
// the menu.
mPipBoundsState.setExpandedBounds(
Rect.unflattenFromString(res.getString(R.string.pip_menu_bounds)));
}
private DisplayInfo getDisplayInfo() {

View File

@@ -16,8 +16,6 @@
package com.android.wm.shell.pip.tv;
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
@@ -26,7 +24,6 @@ import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.android.wm.shell.R;
@@ -36,12 +33,7 @@ import com.android.wm.shell.R;
*/
public class TvPipMenuActionButton extends RelativeLayout implements View.OnClickListener {
private final ImageView mIconImageView;
private final ImageView mButtonImageView;
private final TextView mDescriptionTextView;
private Animator mTextFocusGainAnimator;
private Animator mButtonFocusGainAnimator;
private Animator mTextFocusLossAnimator;
private Animator mButtonFocusLossAnimator;
private final View mButtonView;
private OnClickListener mOnClickListener;
public TvPipMenuActionButton(Context context) {
@@ -64,8 +56,7 @@ public class TvPipMenuActionButton extends RelativeLayout implements View.OnClic
inflater.inflate(R.layout.tv_pip_menu_action_button, this);
mIconImageView = findViewById(R.id.icon);
mButtonImageView = findViewById(R.id.button);
mDescriptionTextView = findViewById(R.id.desc);
mButtonView = findViewById(R.id.button);
final int[] values = new int[]{android.R.attr.src, android.R.attr.text};
final TypedArray typedArray = context.obtainStyledAttributes(attrs, values, defStyleAttr,
@@ -76,43 +67,16 @@ public class TvPipMenuActionButton extends RelativeLayout implements View.OnClic
if (textResId != 0) {
setTextAndDescription(getContext().getString(textResId));
}
typedArray.recycle();
}
@Override
public void onFinishInflate() {
super.onFinishInflate();
mButtonImageView.setOnFocusChangeListener((v, hasFocus) -> {
if (hasFocus) {
startFocusGainAnimation();
} else {
startFocusLossAnimation();
}
});
mTextFocusGainAnimator = AnimatorInflater.loadAnimator(getContext(),
R.anim.tv_pip_controls_focus_gain_animation);
mTextFocusGainAnimator.setTarget(mDescriptionTextView);
mButtonFocusGainAnimator = AnimatorInflater.loadAnimator(getContext(),
R.anim.tv_pip_controls_focus_gain_animation);
mButtonFocusGainAnimator.setTarget(mButtonImageView);
mTextFocusLossAnimator = AnimatorInflater.loadAnimator(getContext(),
R.anim.tv_pip_controls_focus_loss_animation);
mTextFocusLossAnimator.setTarget(mDescriptionTextView);
mButtonFocusLossAnimator = AnimatorInflater.loadAnimator(getContext(),
R.anim.tv_pip_controls_focus_loss_animation);
mButtonFocusLossAnimator.setTarget(mButtonImageView);
}
@Override
public void setOnClickListener(OnClickListener listener) {
// We do not want to set an OnClickListener to the TvPipMenuActionButton itself, but only to
// the ImageView. So let's "cash" the listener we've been passed here and set a "proxy"
// listener to the ImageView.
mOnClickListener = listener;
mButtonImageView.setOnClickListener(listener != null ? this : null);
mButtonView.setOnClickListener(listener != null ? this : null);
}
@Override
@@ -143,55 +107,16 @@ public class TvPipMenuActionButton extends RelativeLayout implements View.OnClic
* Sets the text for description the with the given string.
*/
public void setTextAndDescription(CharSequence text) {
mButtonImageView.setContentDescription(text);
mDescriptionTextView.setText(text);
mButtonView.setContentDescription(text);
}
private static void cancelAnimator(Animator animator) {
if (animator.isStarted()) {
animator.cancel();
}
@Override
public void setEnabled(boolean enabled) {
mButtonView.setEnabled(enabled);
}
/**
* Starts the focus gain animation.
*/
public void startFocusGainAnimation() {
cancelAnimator(mButtonFocusLossAnimator);
cancelAnimator(mTextFocusLossAnimator);
mTextFocusGainAnimator.start();
if (mButtonImageView.getAlpha() < 1f) {
// If we had faded out the ripple drawable, run our manual focus change animation.
// See the comment at {@link #startFocusLossAnimation()} for the reason of manual
// animator.
mButtonFocusGainAnimator.start();
}
}
/**
* Starts the focus loss animation.
*/
public void startFocusLossAnimation() {
cancelAnimator(mButtonFocusGainAnimator);
cancelAnimator(mTextFocusGainAnimator);
mTextFocusLossAnimator.start();
if (mButtonImageView.hasFocus()) {
// Button uses ripple that has the default animation for the focus changes.
// However, it doesn't expose the API to fade out while it is focused, so we should
// manually run the fade out animation when PIP controls row loses focus.
mButtonFocusLossAnimator.start();
}
}
/**
* Resets to initial state.
*/
public void reset() {
cancelAnimator(mButtonFocusGainAnimator);
cancelAnimator(mTextFocusGainAnimator);
cancelAnimator(mButtonFocusLossAnimator);
cancelAnimator(mTextFocusLossAnimator);
mButtonImageView.setAlpha(1f);
mDescriptionTextView.setAlpha(mButtonImageView.hasFocus() ? 1f : 0f);
@Override
public boolean isEnabled() {
return mButtonView.isEnabled();
}
}

View File

@@ -24,6 +24,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ParceledListSlice;
import android.graphics.Rect;
import android.os.Handler;
import android.util.Log;
import android.view.SurfaceControl;
@@ -122,19 +123,19 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
if (DEBUG) Log.d(TAG, "showMenu()");
if (mMenuView != null) {
mSystemWindows.updateViewLayout(mMenuView, getPipMenuLayoutParams(MENU_WINDOW_TITLE,
mPipBoundsState.getDisplayBounds().width(),
mPipBoundsState.getDisplayBounds().height()));
Rect pipBounds = mPipBoundsState.getBounds();
mSystemWindows.updateViewLayout(mMenuView, getPipMenuLayoutParams(
MENU_WINDOW_TITLE, pipBounds.width(), pipBounds.height()));
maybeUpdateMenuViewActions();
mMenuView.show();
// By default, SystemWindows views are above everything else.
// Set the relative z-order so the menu is below PiP.
if (mMenuView.getWindowSurfaceControl() != null && mLeash != null) {
SurfaceControl menuSurfaceControl = mSystemWindows.getViewSurface(mMenuView);
if (menuSurfaceControl != null) {
SurfaceControl.Transaction t = new SurfaceControl.Transaction();
t.setRelativeLayer(mMenuView.getWindowSurfaceControl(), mLeash, -1);
t.setRelativeLayer(mMenuView.getWindowSurfaceControl(), mLeash, 1);
t.setPosition(menuSurfaceControl, pipBounds.left, pipBounds.top);
t.apply();
}
mMenuView.show();
}
}
@@ -181,7 +182,15 @@ public class TvPipMenuController implements PipMenuController, TvPipMenuView.Lis
private void onMediaActionsChanged(List<RemoteAction> actions) {
if (DEBUG) Log.d(TAG, "onMediaActionsChanged()");
updateAdditionalActionsList(mMediaActions, actions);
// Hide disabled actions.
List<RemoteAction> enabledActions = new ArrayList<>();
for (RemoteAction remoteAction : actions) {
if (remoteAction.isEnabled()) {
enabledActions.add(remoteAction);
}
}
updateAdditionalActionsList(mMediaActions, enabledActions);
}
private void updateAdditionalActionsList(

View File

@@ -24,9 +24,7 @@ import android.animation.Animator;
import android.app.PendingIntent;
import android.app.RemoteAction;
import android.content.Context;
import android.graphics.Color;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
@@ -55,13 +53,13 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
private static final String TAG = "TvPipMenuView";
private static final boolean DEBUG = TvPipController.DEBUG;
private static final float DISABLED_ACTION_ALPHA = 0.54f;
private final Animator mFadeInAnimation;
private final Animator mFadeOutAnimation;
@Nullable private Listener mListener;
@Nullable
private Listener mListener;
private final LinearLayout mActionButtonsContainer;
private final View mMenuFrameView;
private final List<TvPipMenuActionButton> mAdditionalButtons = new ArrayList<>();
public TvPipMenuView(@NonNull Context context) {
@@ -88,11 +86,12 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
mActionButtonsContainer.findViewById(R.id.tv_pip_menu_close_button)
.setOnClickListener(this);
mMenuFrameView = findViewById(R.id.tv_pip_menu_frame);
mFadeInAnimation = loadAnimator(mContext, R.anim.tv_pip_menu_fade_in_animation);
mFadeInAnimation.setTarget(mActionButtonsContainer);
mFadeInAnimation.setTarget(mMenuFrameView);
mFadeOutAnimation = loadAnimator(mContext, R.anim.tv_pip_menu_fade_out_animation);
mFadeOutAnimation.setTarget(mActionButtonsContainer);
mFadeOutAnimation.setTarget(mMenuFrameView);
}
void setListener(@Nullable Listener listener) {
@@ -103,7 +102,6 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
if (DEBUG) Log.d(TAG, "show()");
mFadeInAnimation.start();
setAlpha(1.0f);
grantWindowFocus(true);
}
@@ -111,12 +109,11 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
if (DEBUG) Log.d(TAG, "hide()");
mFadeOutAnimation.start();
setAlpha(0.0f);
grantWindowFocus(false);
}
boolean isVisible() {
return getAlpha() == 1.0f;
return mMenuFrameView != null && mMenuFrameView.getAlpha() != 0.0f;
}
private void grantWindowFocus(boolean grantFocus) {
@@ -140,9 +137,7 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
// Add buttons until we have enough to display all of the actions.
while (actionsNumber > buttonsNumber) {
final TvPipMenuActionButton button = (TvPipMenuActionButton) layoutInflater.inflate(
R.layout.tv_pip_menu_additional_action_button, mActionButtonsContainer,
false);
TvPipMenuActionButton button = new TvPipMenuActionButton(mContext);
button.setOnClickListener(this);
mActionButtonsContainer.addView(button);
@@ -168,13 +163,8 @@ public class TvPipMenuView extends FrameLayout implements View.OnClickListener {
button.setVisibility(View.VISIBLE); // Ensure the button is visible.
button.setTextAndDescription(action.getContentDescription());
button.setEnabled(action.isEnabled());
button.setAlpha(action.isEnabled() ? 1f : DISABLED_ACTION_ALPHA);
button.setTag(action);
action.getIcon().loadDrawableAsync(mContext, drawable -> {
drawable.setTint(Color.WHITE);
button.setImageDrawable(drawable);
}, mainHandler);
action.getIcon().loadDrawableAsync(mContext, button::setImageDrawable, mainHandler);
}
}