| /* |
| * Copyright (C) 2017 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.car.setupwizardlib; |
| |
| import android.animation.ValueAnimator; |
| import android.annotation.Nullable; |
| import android.content.Context; |
| import android.content.res.TypedArray; |
| import android.graphics.PorterDuff; |
| import android.graphics.Rect; |
| import android.graphics.Typeface; |
| import android.graphics.drawable.Drawable; |
| import android.graphics.drawable.GradientDrawable; |
| import android.graphics.drawable.InsetDrawable; |
| import android.graphics.drawable.RippleDrawable; |
| import android.text.TextUtils; |
| import android.util.AttributeSet; |
| import android.util.Log; |
| import android.util.TypedValue; |
| import android.view.LayoutInflater; |
| import android.view.TouchDelegate; |
| import android.view.View; |
| import android.view.ViewGroup; |
| import android.view.ViewStub; |
| import android.widget.Button; |
| import android.widget.ImageView; |
| import android.widget.LinearLayout; |
| import android.widget.ProgressBar; |
| import android.widget.TextView; |
| |
| import androidx.annotation.StyleRes; |
| import androidx.annotation.VisibleForTesting; |
| |
| import com.android.car.setupwizardlib.partner.PartnerConfig; |
| import com.android.car.setupwizardlib.partner.PartnerConfigHelper; |
| |
| import java.util.Locale; |
| import java.util.Objects; |
| |
| /** |
| * Custom layout for the Car Setup Wizard. Provides accessors for modifying elements such as buttons |
| * and progress bars. Any modifications to elements built by |
| * the CarSetupWizardLayout should be done through methods provided by this class unless that is |
| * not possible so as to keep the state internally consistent. |
| * |
| * @deprecated Use {@link CarSetupWizardCompatLayout} or {@link CarSetupWizardDesignLayout}. |
| */ |
| @Deprecated |
| public class CarSetupWizardLayout extends LinearLayout { |
| private static final String TAG = CarSetupWizardLayout.class.getSimpleName(); |
| private static final int ANIMATION_DURATION_MS = 100; |
| |
| private View mBackButton; |
| private View mTitleBar; |
| private Float mTitleBarElevation; |
| private TextView mToolbarTitle; |
| private PartnerConfigHelper mPartnerConfigHelper; |
| |
| /* <p>The Primary Toolbar Button should always be used when there is only a single action that |
| * moves the wizard to the next screen (e.g. Only need a 'Skip' button). |
| * |
| * When there are two actions that can move the wizard to the next screen (e.g. either 'Skip' |
| * or 'Let's Go' are the two options), then the Primary is used for the positive action |
| * while the Secondary is used for the negative action.</p> |
| */ |
| private Button mPrimaryToolbarButton; |
| |
| /* |
| * Flag to track the primary toolbar button flat state. |
| */ |
| private boolean mPrimaryToolbarButtonFlat; |
| private View.OnClickListener mPrimaryToolbarButtonOnClick; |
| private Button mSecondaryToolbarButton; |
| private ProgressBar mProgressBar; |
| |
| public CarSetupWizardLayout(Context context) { |
| this(context, null); |
| } |
| |
| public CarSetupWizardLayout(Context context, @Nullable AttributeSet attrs) { |
| this(context, attrs, 0); |
| } |
| |
| public CarSetupWizardLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { |
| this(context, attrs, defStyleAttr, 0); |
| } |
| |
| /** |
| * On initialization, the layout gets all of the custom attributes and initializes |
| * the custom views that can be set by the user (e.g. back button, continue button). |
| */ |
| public CarSetupWizardLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr, |
| int defStyleRes) { |
| super(context, attrs, defStyleAttr, defStyleRes); |
| |
| mPartnerConfigHelper = PartnerConfigHelper.get(context); |
| TypedArray attrArray = context.getTheme().obtainStyledAttributes( |
| attrs, |
| R.styleable.CarSetupWizardLayout, |
| 0, 0); |
| |
| init(attrArray); |
| } |
| |
| /** |
| * Inflates the layout and sets the custom views (e.g. back button, continue button). |
| */ |
| private void init(TypedArray attrArray) { |
| boolean showBackButton; |
| |
| boolean showToolbarTitle; |
| String toolbarTitleText; |
| |
| boolean showPrimaryToolbarButton; |
| String primaryToolbarButtonText; |
| boolean primaryToolbarButtonEnabled; |
| |
| boolean showSecondaryToolbarButton; |
| String secondaryToolbarButtonText; |
| boolean secondaryToolbarButtonEnabled; |
| |
| boolean showProgressBar; |
| boolean indeterminateProgressBar; |
| |
| try { |
| showBackButton = attrArray.getBoolean( |
| R.styleable.CarSetupWizardLayout_showBackButton, true); |
| showToolbarTitle = attrArray.getBoolean( |
| R.styleable.CarSetupWizardLayout_showToolbarTitle, false); |
| toolbarTitleText = attrArray.getString( |
| R.styleable.CarSetupWizardLayout_toolbarTitleText); |
| showPrimaryToolbarButton = attrArray.getBoolean( |
| R.styleable.CarSetupWizardLayout_showPrimaryToolbarButton, true); |
| primaryToolbarButtonText = attrArray.getString( |
| R.styleable.CarSetupWizardLayout_primaryToolbarButtonText); |
| primaryToolbarButtonEnabled = attrArray.getBoolean( |
| R.styleable.CarSetupWizardLayout_primaryToolbarButtonEnabled, true); |
| mPrimaryToolbarButtonFlat = attrArray.getBoolean( |
| R.styleable.CarSetupWizardLayout_primaryToolbarButtonFlat, false); |
| showSecondaryToolbarButton = attrArray.getBoolean( |
| R.styleable.CarSetupWizardLayout_showSecondaryToolbarButton, false); |
| secondaryToolbarButtonText = attrArray.getString( |
| R.styleable.CarSetupWizardLayout_secondaryToolbarButtonText); |
| secondaryToolbarButtonEnabled = attrArray.getBoolean( |
| R.styleable.CarSetupWizardLayout_secondaryToolbarButtonEnabled, true); |
| showProgressBar = attrArray.getBoolean( |
| R.styleable.CarSetupWizardLayout_showProgressBar, false); |
| indeterminateProgressBar = attrArray.getBoolean( |
| R.styleable.CarSetupWizardLayout_indeterminateProgressBar, true); |
| } finally { |
| attrArray.recycle(); |
| } |
| |
| LayoutInflater inflater = LayoutInflater.from(getContext()); |
| inflater.inflate(R.layout.car_setup_wizard_layout, this); |
| |
| // Set the back button visibility based on the custom attribute. |
| setBackButton(findViewById(R.id.back_button)); |
| Drawable drawable = mPartnerConfigHelper.getDrawable( |
| getContext(), PartnerConfig.CONFIG_TOOLBAR_BUTTON_ICON_BACK); |
| if (drawable != null) { |
| ((ImageView) mBackButton).setImageDrawable(drawable); |
| } |
| setBackButtonVisible(showBackButton); |
| |
| // Se the title bar. |
| setTitleBar(findViewById(R.id.application_bar)); |
| mTitleBarElevation = |
| getContext().getResources().getDimension(R.dimen.title_bar_drop_shadow_elevation); |
| int toolbarBgColor = |
| mPartnerConfigHelper.getColor(getContext(), PartnerConfig.CONFIG_TOOLBAR_BG_COLOR); |
| if (toolbarBgColor != 0) { |
| mTitleBar.setBackgroundColor(toolbarBgColor); |
| } |
| |
| // Set the toolbar title visibility and text based on the custom attributes. |
| setToolbarTitle(findViewById(R.id.toolbar_title)); |
| if (showToolbarTitle) { |
| setToolbarTitleText(toolbarTitleText); |
| } else { |
| setToolbarTitleVisible(false); |
| } |
| |
| // Set the primary continue button visibility and text based on the custom attributes. |
| ViewStub primaryToolbarButtonStub = |
| (ViewStub) findViewById(R.id.primary_toolbar_button_stub); |
| // Set the button layout to flat if that attribute was set. |
| if (mPrimaryToolbarButtonFlat) { |
| primaryToolbarButtonStub.setLayoutResource(R.layout.flat_button); |
| } |
| primaryToolbarButtonStub.inflate(); |
| setPrimaryToolbarButton(findViewById(R.id.primary_toolbar_button)); |
| if (showPrimaryToolbarButton) { |
| setPrimaryToolbarButtonText(primaryToolbarButtonText); |
| setPrimaryToolbarButtonEnabled(primaryToolbarButtonEnabled); |
| |
| setBackground( |
| mPrimaryToolbarButton, |
| PartnerConfig.CONFIG_TOOLBAR_PRIMARY_BUTTON_BG, |
| PartnerConfig.CONFIG_TOOLBAR_PRIMARY_BUTTON_BG_COLOR); |
| |
| setButtonPadding(mPrimaryToolbarButton); |
| setButtonTypeFace(mPrimaryToolbarButton); |
| setButtonTextSize(mPrimaryToolbarButton); |
| setButtonTextColor( |
| mPrimaryToolbarButton, |
| PartnerConfig.CONFIG_TOOLBAR_PRIMARY_BUTTON_TEXT_COLOR); |
| } else { |
| setPrimaryToolbarButtonVisible(false); |
| } |
| |
| // Set the secondary continue button visibility and text based on the custom attributes. |
| ViewStub secondaryToolbarButtonStub = |
| (ViewStub) findViewById(R.id.secondary_toolbar_button_stub); |
| if (showSecondaryToolbarButton || !TextUtils.isEmpty(secondaryToolbarButtonText)) { |
| secondaryToolbarButtonStub.inflate(); |
| mSecondaryToolbarButton = findViewById(R.id.secondary_toolbar_button); |
| setSecondaryToolbarButtonText(secondaryToolbarButtonText); |
| setSecondaryToolbarButtonEnabled(secondaryToolbarButtonEnabled); |
| setSecondaryToolbarButtonVisible(showSecondaryToolbarButton); |
| } |
| |
| mProgressBar = findViewById(R.id.progress_bar); |
| setProgressBarVisible(showProgressBar); |
| setProgressBarIndeterminate(indeterminateProgressBar); |
| |
| // Set orientation programmatically since the inflated layout uses <merge> |
| setOrientation(LinearLayout.VERTICAL); |
| } |
| |
| /** |
| * Set a given view's visibility. |
| */ |
| @VisibleForTesting |
| void setViewVisible(View view, boolean visible) { |
| view.setVisibility(visible ? View.VISIBLE : View.GONE); |
| } |
| |
| // Add or remove the back button touch delegate depending on whether it is visible. |
| @VisibleForTesting |
| void updateBackButtonTouchDelegate(boolean visible) { |
| if (visible) { |
| // Post this action in the parent's message queue to make sure the parent |
| // lays out its children before getHitRect() is called |
| this.post(() -> { |
| Rect delegateArea = new Rect(); |
| |
| mBackButton.getHitRect(delegateArea); |
| |
| /* |
| * Update the delegate area based on the difference between the current size and |
| * the touch target size |
| */ |
| float touchTargetSize = getResources().getDimension( |
| R.dimen.car_touch_target_size); |
| float primaryIconSize = getResources().getDimension( |
| R.dimen.car_primary_icon_size); |
| |
| int sizeDifference = (int) ((touchTargetSize - primaryIconSize) / 2); |
| |
| delegateArea.right += sizeDifference; |
| delegateArea.bottom += sizeDifference; |
| delegateArea.left -= sizeDifference; |
| delegateArea.top -= sizeDifference; |
| |
| // Set the TouchDelegate on the parent view |
| TouchDelegate touchDelegate = new TouchDelegate(delegateArea, |
| mBackButton); |
| |
| if (View.class.isInstance(mBackButton.getParent())) { |
| ((View) mBackButton.getParent()).setTouchDelegate(touchDelegate); |
| } |
| }); |
| } else { |
| // Set the TouchDelegate to null if the back button is not visible. |
| if (View.class.isInstance(mBackButton.getParent())) { |
| ((View) mBackButton.getParent()).setTouchDelegate(null); |
| } |
| } |
| } |
| |
| /** |
| * Gets the back button. |
| */ |
| public View getBackButton() { |
| return mBackButton; |
| } |
| |
| @VisibleForTesting |
| final void setBackButton(View backButton) { |
| mBackButton = backButton; |
| } |
| |
| /** |
| * Set the back button onClickListener to given listener. Can be null if the listener should |
| * be overridden so no callback is made. |
| */ |
| public void setBackButtonListener(@Nullable View.OnClickListener listener) { |
| mBackButton.setOnClickListener(listener); |
| } |
| |
| /** |
| * Set the back button visibility to the given visibility. |
| */ |
| public void setBackButtonVisible(boolean visible) { |
| setViewVisible(mBackButton, visible); |
| updateBackButtonTouchDelegate(visible); |
| } |
| |
| /** |
| * Gets the toolbar title. |
| */ |
| public TextView getToolbarTitle() { |
| return mToolbarTitle; |
| } |
| |
| @VisibleForTesting |
| final void setToolbarTitle(TextView toolbarTitle) { |
| mToolbarTitle = toolbarTitle; |
| } |
| |
| /** |
| * Sets the header title visibility to given value. |
| */ |
| public void setToolbarTitleVisible(boolean visible) { |
| setViewVisible(mToolbarTitle, visible); |
| } |
| |
| /** |
| * Sets the header title text to the provided text. |
| */ |
| public void setToolbarTitleText(String text) { |
| mToolbarTitle.setText(text); |
| } |
| |
| /** |
| * Sets the style for the toolbar title. |
| */ |
| public void setToolbarTitleStyle(@StyleRes int style) { |
| mToolbarTitle.setTextAppearance(style); |
| } |
| |
| /** |
| * Gets the primary toolbar button. |
| */ |
| public Button getPrimaryToolbarButton() { |
| return mPrimaryToolbarButton; |
| } |
| |
| @VisibleForTesting |
| final void setPrimaryToolbarButton(Button primaryToolbarButton) { |
| mPrimaryToolbarButton = primaryToolbarButton; |
| } |
| |
| /** |
| * Set the primary continue button visibility to the given visibility. |
| */ |
| public void setPrimaryToolbarButtonVisible(boolean visible) { |
| setViewVisible(mPrimaryToolbarButton, visible); |
| } |
| |
| /** |
| * Set whether the primary continue button is enabled. |
| */ |
| public void setPrimaryToolbarButtonEnabled(boolean enabled) { |
| mPrimaryToolbarButton.setEnabled(enabled); |
| } |
| |
| /** |
| * Set the primary continue button text to the given text. |
| */ |
| public void setPrimaryToolbarButtonText(String text) { |
| mPrimaryToolbarButton.setText(text); |
| } |
| |
| /** |
| * Set the primary continue button onClickListener to the given listener. Can be null if the |
| * listener should be overridden so no callback is made. All changes to primary toolbar |
| * button's onClickListener should be made here so they can be stored through changes to the |
| * button. |
| */ |
| public void setPrimaryToolbarButtonListener(@Nullable View.OnClickListener listener) { |
| mPrimaryToolbarButtonOnClick = listener; |
| mPrimaryToolbarButton.setOnClickListener(listener); |
| } |
| |
| /** |
| * Getter for the flatness of the primary toolbar button. |
| */ |
| public boolean getPrimaryToolbarButtonFlat() { |
| return mPrimaryToolbarButtonFlat; |
| } |
| |
| /** |
| * Changes the button in the primary slot to a flat theme, maintaining the text, visibility, |
| * whether it is enabled, and id. |
| * <p>NOTE: that other attributes set manually on the primaryToolbarButton will be lost on calls |
| * to this method as the button will be replaced.</p> |
| */ |
| public void setPrimaryToolbarButtonFlat(boolean isFlat) { |
| // Do nothing if the state isn't changing. |
| if (isFlat == mPrimaryToolbarButtonFlat) { |
| return; |
| } |
| Button newPrimaryButton = createPrimaryToolbarButton(isFlat); |
| |
| ViewGroup parent = (ViewGroup) findViewById(R.id.button_container); |
| int buttonIndex = parent.indexOfChild(mPrimaryToolbarButton); |
| parent.removeViewAt(buttonIndex); |
| parent.addView(newPrimaryButton, buttonIndex); |
| |
| // Update state of layout |
| setPrimaryToolbarButton(newPrimaryButton); |
| mPrimaryToolbarButtonFlat = isFlat; |
| } |
| |
| @VisibleForTesting |
| Button createPrimaryToolbarButton(boolean isFlat) { |
| int layoutId = isFlat ? R.layout.flat_button : R.layout.primary_button; |
| Button newPrimaryButton = (Button) inflate(getContext(), layoutId, null); |
| newPrimaryButton.setId(mPrimaryToolbarButton.getId()); |
| newPrimaryButton.setVisibility(mPrimaryToolbarButton.getVisibility()); |
| newPrimaryButton.setEnabled(mPrimaryToolbarButton.isEnabled()); |
| newPrimaryButton.setText(mPrimaryToolbarButton.getText()); |
| newPrimaryButton.setOnClickListener(mPrimaryToolbarButtonOnClick); |
| newPrimaryButton.setLayoutParams(mPrimaryToolbarButton.getLayoutParams()); |
| |
| return newPrimaryButton; |
| } |
| |
| /** |
| * Gets the secondary toolbar button. |
| */ |
| public Button getSecondaryToolbarButton() { |
| return mSecondaryToolbarButton; |
| } |
| |
| /** |
| * Set the secondary continue button visibility to the given visibility. |
| */ |
| public void setSecondaryToolbarButtonVisible(boolean visible) { |
| // If not setting it visible and it hasn't been inflated yet then don't inflate. |
| if (!visible && mSecondaryToolbarButton == null) { |
| return; |
| } |
| maybeInflateSecondaryToolbarButton(); |
| setViewVisible(mSecondaryToolbarButton, visible); |
| } |
| |
| /** |
| * Sets whether the secondary continue button is enabled. |
| */ |
| public void setSecondaryToolbarButtonEnabled(boolean enabled) { |
| maybeInflateSecondaryToolbarButton(); |
| mSecondaryToolbarButton.setEnabled(enabled); |
| } |
| |
| /** |
| * Sets the secondary continue button text to the given text. |
| */ |
| public void setSecondaryToolbarButtonText(String text) { |
| maybeInflateSecondaryToolbarButton(); |
| mSecondaryToolbarButton.setText(text); |
| } |
| |
| /** |
| * Sets the secondary continue button onClickListener to the given listener. Can be null if the |
| * listener should be overridden so no callback is made. |
| */ |
| public void setSecondaryToolbarButtonListener(@Nullable View.OnClickListener listener) { |
| maybeInflateSecondaryToolbarButton(); |
| mSecondaryToolbarButton.setOnClickListener(listener); |
| } |
| |
| /** |
| * Gets the progress bar. |
| */ |
| public ProgressBar getProgressBar() { |
| return mProgressBar; |
| } |
| |
| /** |
| * Sets the progress bar visibility to the given visibility. |
| */ |
| public void setProgressBarVisible(boolean visible) { |
| setViewVisible(mProgressBar, visible); |
| } |
| |
| /** |
| * Sets the progress bar indeterminate/determinate state. |
| */ |
| public void setProgressBarIndeterminate(boolean indeterminate) { |
| mProgressBar.setIndeterminate(indeterminate); |
| } |
| |
| /** |
| * Sets the progress bar's progress. |
| */ |
| public void setProgressBarProgress(int progress) { |
| setProgressBarIndeterminate(false); |
| mProgressBar.setProgress(progress); |
| } |
| |
| /** |
| * Sets the locale to be used for rendering. |
| */ |
| public void applyLocale(Locale locale) { |
| if (locale == null) { |
| return; |
| } |
| int direction = TextUtils.getLayoutDirectionFromLocale(locale); |
| setLayoutDirection(direction); |
| |
| mToolbarTitle.setTextLocale(locale); |
| mToolbarTitle.setLayoutDirection(direction); |
| |
| mPrimaryToolbarButton.setTextLocale(locale); |
| mPrimaryToolbarButton.setLayoutDirection(direction); |
| |
| mSecondaryToolbarButton.setTextLocale(locale); |
| mSecondaryToolbarButton.setLayoutDirection(direction); |
| } |
| |
| /** |
| * Adds elevation to the title bar in order to produce a drop shadow. An animation can be used |
| * in cases where a direct elevation changes would be too jarring. |
| * |
| * @param animate True when a smooth animation is wanted for the adding of the elevation. |
| */ |
| public void addElevationToTitleBar(boolean animate) { |
| if (animate) { |
| ValueAnimator elevationAnimator = |
| ValueAnimator.ofFloat(mTitleBar.getElevation(), mTitleBarElevation); |
| elevationAnimator |
| .setDuration(ANIMATION_DURATION_MS) |
| .addUpdateListener( |
| animation -> mTitleBar.setElevation( |
| (float) animation.getAnimatedValue())); |
| elevationAnimator.start(); |
| } else { |
| mTitleBar.setElevation(mTitleBarElevation); |
| } |
| } |
| |
| /** |
| * Removes the elevation from the title bar, an animation can be used in cases where a direct |
| * elevation changes would be too jarring. |
| * |
| * @param animate True when a smooth animation is wanted for the removal of the elevation. |
| */ |
| public void removeElevationFromTitleBar(boolean animate) { |
| if (animate) { |
| ValueAnimator elevationAnimator = |
| ValueAnimator.ofFloat(mTitleBar.getElevation(), 0f); |
| elevationAnimator |
| .setDuration(ANIMATION_DURATION_MS) |
| .addUpdateListener( |
| animation -> mTitleBar.setElevation( |
| (float) animation.getAnimatedValue())); |
| elevationAnimator.start(); |
| } else { |
| mTitleBar.setElevation(0f); |
| } |
| } |
| |
| /** |
| * Sets the title bar view. |
| */ |
| private void setTitleBar(View titleBar) { |
| mTitleBar = titleBar; |
| } |
| |
| /** |
| * A method that inflates the SecondaryToolbarButton if it is has not already been |
| * inflated. If it has been inflated already this method will do nothing. |
| */ |
| private void maybeInflateSecondaryToolbarButton() { |
| ViewStub secondaryToolbarButtonStub = findViewById(R.id.secondary_toolbar_button_stub); |
| // If the secondaryToolbarButtonStub is null then the stub has been inflated so there is |
| // nothing to do. |
| if (secondaryToolbarButtonStub != null) { |
| secondaryToolbarButtonStub.inflate(); |
| mSecondaryToolbarButton = findViewById(R.id.secondary_toolbar_button); |
| setSecondaryToolbarButtonVisible(false); |
| |
| setBackground( |
| mSecondaryToolbarButton, |
| PartnerConfig.CONFIG_TOOLBAR_SECONDARY_BUTTON_BG, |
| PartnerConfig.CONFIG_TOOLBAR_SECONDARY_BUTTON_BG_COLOR); |
| |
| setButtonPadding(mSecondaryToolbarButton); |
| setButtonTypeFace(mSecondaryToolbarButton); |
| setButtonTextSize(mSecondaryToolbarButton); |
| setButtonTextColor( |
| mSecondaryToolbarButton, |
| PartnerConfig.CONFIG_TOOLBAR_SECONDARY_BUTTON_TEXT_COLOR); |
| |
| // Set button spacing |
| float marginEnd = PartnerConfigHelper.get(getContext()).getDimension( |
| getContext(), |
| PartnerConfig.CONFIG_TOOLBAR_BUTTON_SPACING); |
| |
| MarginLayoutParams layoutParams = |
| (MarginLayoutParams) mSecondaryToolbarButton.getLayoutParams(); |
| layoutParams.setMarginEnd(Math.round(marginEnd)); |
| } |
| } |
| |
| /** Sets button text color using partner overlay if exists */ |
| @VisibleForTesting |
| void setButtonTextColor(TextView button, PartnerConfig config) { |
| int color = mPartnerConfigHelper.getColor(getContext(), config); |
| if (color != 0) { |
| button.setTextColor(color); |
| } |
| } |
| |
| /** |
| * Sets background using partner overlay if exists. Background color and radius are only |
| * applied if background resource doesn't exist. Otherwise default background color and radius |
| * may override what's set in the background. |
| */ |
| @VisibleForTesting |
| void setBackground(View view, PartnerConfig bgConfig, PartnerConfig bgColorConfig) { |
| Drawable background = mPartnerConfigHelper.getDrawable(getContext(), bgConfig); |
| if (background == null) { |
| if (view instanceof Button) { |
| setButtonRadius((Button) view); |
| } |
| setBackgroundColor(view, bgColorConfig); |
| } else { |
| view.setBackground(background); |
| } |
| } |
| |
| /** Sets button background color using partner overlay if exists */ |
| @VisibleForTesting |
| void setBackgroundColor(View button, PartnerConfig config) { |
| int color = mPartnerConfigHelper.getColor(getContext(), config); |
| if (color != 0) { |
| Drawable background = button.getBackground(); |
| if (background != null) { |
| background.mutate().setColorFilter(color, PorterDuff.Mode.SRC_ATOP); |
| } |
| } |
| } |
| |
| /** Sets button text size using partner overlay if exists */ |
| @VisibleForTesting |
| void setButtonTextSize(TextView button) { |
| float dimension = mPartnerConfigHelper.getDimension( |
| getContext(), |
| PartnerConfig.CONFIG_TOOLBAR_BUTTON_TEXT_SIZE); |
| if (dimension != 0) { |
| button.setTextSize(TypedValue.COMPLEX_UNIT_PX, dimension); |
| } |
| } |
| |
| /** Sets button type face with partner overlay if exists */ |
| private void setButtonTypeFace(TextView button) { |
| String fontFamily = mPartnerConfigHelper.getString( |
| getContext(), |
| PartnerConfig.CONFIG_TOOLBAR_BUTTON_FONT_FAMILY); |
| if (TextUtils.isEmpty(fontFamily)) { |
| return; |
| } |
| |
| Typeface typeface = Typeface.create(fontFamily, Typeface.NORMAL); |
| if (Objects.equals(typeface, Typeface.DEFAULT)) { |
| Log.w(TAG, String.format( |
| "Couldn't find font: %s. Setting default font.", |
| fontFamily)); |
| } |
| button.setTypeface(typeface); |
| } |
| |
| /** Sets button radius using partner overlay if exists */ |
| private void setButtonRadius(Button button) { |
| float radius = mPartnerConfigHelper.getDimension( |
| getContext(), |
| PartnerConfig.CONFIG_TOOLBAR_BUTTON_RADIUS); |
| |
| GradientDrawable gradientDrawable = getGradientDrawable(button); |
| if (gradientDrawable != null) { |
| gradientDrawable.setCornerRadius(radius); |
| } |
| } |
| |
| private void setButtonPadding(Button button) { |
| int hPadding = Math.round( |
| PartnerConfigHelper.get(getContext()).getDimension( |
| getContext(), |
| PartnerConfig.CONFIG_TOOLBAR_BUTTON_PADDING_HORIZONTAL) |
| ); |
| int vPadding = Math.round( |
| PartnerConfigHelper.get(getContext()).getDimension( |
| getContext(), |
| PartnerConfig.CONFIG_TOOLBAR_BUTTON_PADDING_VERTICAL) |
| ); |
| button.setPadding(hPadding, vPadding, hPadding, vPadding); |
| } |
| |
| private GradientDrawable getGradientDrawable(Button button) { |
| Drawable drawable = button.getBackground(); |
| if (drawable instanceof InsetDrawable) { |
| return getGradientDrawableFromInsetDrawable((InsetDrawable) drawable); |
| } |
| |
| if (drawable instanceof RippleDrawable) { |
| drawable = ((RippleDrawable) drawable).getDrawable(0); |
| if (drawable instanceof InsetDrawable) { |
| return getGradientDrawableFromInsetDrawable((InsetDrawable) drawable); |
| } |
| return (GradientDrawable) drawable; |
| } |
| |
| return null; |
| } |
| |
| private GradientDrawable getGradientDrawableFromInsetDrawable(InsetDrawable insetDrawable) { |
| return (GradientDrawable) insetDrawable.getDrawable(); |
| } |
| } |