| /* |
| * 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. |
| */ |
| |
| package com.android.car.settings.common; |
| |
| import android.content.Context; |
| import android.content.res.Resources; |
| import android.graphics.drawable.Drawable; |
| import android.text.TextUtils; |
| import android.view.View; |
| import android.widget.ImageView; |
| import android.widget.TextView; |
| import android.widget.Toast; |
| |
| import androidx.annotation.DrawableRes; |
| import androidx.annotation.StringRes; |
| import androidx.annotation.VisibleForTesting; |
| |
| import com.android.car.settings.R; |
| import com.android.car.ui.utils.CarUiUtils; |
| |
| import java.lang.ref.WeakReference; |
| |
| /** |
| * Class representing a button item for an {@link ActionButtonsPreference} |
| */ |
| public class ActionButtonInfo { |
| private static final Logger LOG = new Logger(ActionButtonInfo.class); |
| private final Context mContext; |
| private View mButtonView; |
| private ImageView mButtonIconView; |
| private TextView mButtonTextView; |
| private CharSequence mText; |
| private Drawable mIcon; |
| private View.OnClickListener mListener; |
| private boolean mIsPreferenceRestricted = false; |
| private boolean mIsEnabled = true; |
| private boolean mIsVisible = true; |
| private WeakReference<ButtonInfoChangeListener> mButtonInfoChangeListener; |
| private String mMessageToShowWhenUxRestrictedPreferenceClicked; |
| |
| ActionButtonInfo(Context context, ButtonInfoChangeListener changeListener) { |
| mContext = context; |
| mButtonInfoChangeListener = new WeakReference<>(changeListener); |
| mMessageToShowWhenUxRestrictedPreferenceClicked = context.getString( |
| R.string.car_ui_restricted_while_driving); |
| } |
| |
| /** |
| * Set the visibility state. |
| */ |
| public ActionButtonInfo setVisible(boolean isVisible) { |
| if (isVisible != mIsVisible) { |
| mIsVisible = isVisible; |
| update(); |
| } |
| return this; |
| } |
| |
| /** |
| * Sets the text to be displayed. |
| */ |
| public ActionButtonInfo setText(@StringRes int textResId) { |
| final String newText = mContext.getString(textResId); |
| if (!TextUtils.equals(newText, mText)) { |
| mText = newText; |
| update(); |
| } |
| return this; |
| } |
| |
| /** |
| * Sets the drawable to be displayed above of text. |
| */ |
| public ActionButtonInfo setIcon(@DrawableRes int iconResId) { |
| if (iconResId == 0) { |
| return this; |
| } |
| |
| final Drawable icon; |
| try { |
| icon = mContext.getDrawable(iconResId); |
| mIcon = icon; |
| update(); |
| } catch (Resources.NotFoundException exception) { |
| LOG.e("Resource does not exist: " + iconResId); |
| } |
| return this; |
| } |
| |
| /** |
| * Set the enabled state. |
| */ |
| public ActionButtonInfo setEnabled(boolean isEnabled) { |
| if (isEnabled != mIsEnabled) { |
| mIsEnabled = isEnabled; |
| update(); |
| } |
| return this; |
| } |
| |
| /** |
| * Register a callback to be invoked when clicked. |
| */ |
| public ActionButtonInfo setOnClickListener( |
| View.OnClickListener listener) { |
| if (listener != mListener) { |
| mListener = listener; |
| update(); |
| } |
| return this; |
| } |
| |
| ActionButtonInfo setButtonView(View view) { |
| mButtonView = view; |
| return this; |
| } |
| |
| ActionButtonInfo setButtonTextView(TextView textView) { |
| mButtonTextView = textView; |
| return this; |
| } |
| |
| ActionButtonInfo setButtonIconView(ImageView iconView) { |
| mButtonIconView = iconView; |
| return this; |
| } |
| |
| ActionButtonInfo setPreferenceRestricted(boolean isRestricted) { |
| mIsPreferenceRestricted = isRestricted; |
| return this; |
| } |
| |
| /** |
| * Get the current button text. |
| */ |
| @VisibleForTesting |
| public CharSequence getText() { |
| return mText; |
| } |
| |
| /** |
| * Get the current button icon. |
| */ |
| @VisibleForTesting |
| public Drawable getIcon() { |
| return mIcon; |
| } |
| |
| /** |
| * Get the current button click listener. |
| */ |
| @VisibleForTesting |
| public View.OnClickListener getOnClickListener() { |
| return mListener; |
| } |
| |
| /** |
| * Get the current button enabled state. |
| */ |
| @VisibleForTesting |
| public boolean isEnabled() { |
| return mIsEnabled; |
| } |
| |
| /** |
| * Get the current button visibility. |
| */ |
| @VisibleForTesting |
| public boolean isVisible() { |
| return shouldBeVisible(); |
| } |
| |
| void setUpButton() { |
| mButtonTextView.setText(mText); |
| mButtonIconView.setImageDrawable(mIcon); |
| mButtonView.setOnClickListener(this::performClick); |
| |
| boolean enabled = isEnabled() || mIsPreferenceRestricted; |
| mButtonView.setEnabled(enabled); |
| CarUiUtils.makeAllViewsEnabledAndUxRestricted(mButtonView, isEnabled(), |
| mIsPreferenceRestricted); |
| |
| mButtonIconView.setVisibility(mIcon != null ? View.VISIBLE : View.GONE); |
| |
| if (shouldBeVisible()) { |
| mButtonView.setVisibility(View.VISIBLE); |
| } else { |
| mButtonView.setVisibility(View.GONE); |
| } |
| } |
| |
| @VisibleForTesting |
| void performClick(View v) { |
| if (!isEnabled()) { |
| return; |
| } |
| if (mListener == null) { |
| return; |
| } |
| if (mIsPreferenceRestricted) { |
| if (!TextUtils.isEmpty(mMessageToShowWhenUxRestrictedPreferenceClicked)) { |
| Toast.makeText(mContext, mMessageToShowWhenUxRestrictedPreferenceClicked, |
| Toast.LENGTH_LONG).show(); |
| } |
| return; |
| } |
| mListener.onClick(v); |
| } |
| |
| /** |
| * By default, four buttons are visible. |
| * However, there are two cases which button should be invisible. |
| * |
| * 1. User set invisible for this button. ex: mIsVisible = false. |
| * 2. User didn't set any title or icon. |
| */ |
| private boolean shouldBeVisible() { |
| return mIsVisible && (!TextUtils.isEmpty(mText) || mIcon != null); |
| } |
| |
| private void update() { |
| ButtonInfoChangeListener listener = mButtonInfoChangeListener.get(); |
| if (listener != null) { |
| listener.onButtonInfoChange(this); |
| } |
| } |
| |
| /** |
| * Listener that is notified when a button has been updated. |
| */ |
| interface ButtonInfoChangeListener { |
| void onButtonInfoChange(ActionButtonInfo buttonInfo); |
| } |
| } |