/* * Copyright (C) 2016 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.internal.widget; import android.annotation.ColorInt; import android.annotation.Nullable; import android.content.Context; import android.content.res.ColorStateList; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.util.AttributeSet; import android.view.RemotableViewMethod; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityNodeInfo; import android.widget.Button; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.RemoteViews; import android.widget.TextView; import com.android.internal.R; import java.util.Locale; /** * An expand button in a notification */ @RemoteViews.RemoteView public class NotificationExpandButton extends FrameLayout { private Drawable mPillDrawable; private TextView mNumberView; private ImageView mIconView; private boolean mExpanded; private int mNumber; private int mDefaultPillColor; private int mDefaultTextColor; private int mHighlightPillColor; private int mHighlightTextColor; public NotificationExpandButton(Context context) { this(context, null, 0, 0); } public NotificationExpandButton(Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0, 0); } public NotificationExpandButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { this(context, attrs, defStyleAttr, 0); } public NotificationExpandButton(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override protected void onFinishInflate() { super.onFinishInflate(); final View pillView = findViewById(R.id.expand_button_pill); final LayerDrawable layeredPill = (LayerDrawable) pillView.getBackground(); mPillDrawable = layeredPill.findDrawableByLayerId(R.id.expand_button_pill_colorized_layer); mNumberView = findViewById(R.id.expand_button_number); mIconView = findViewById(R.id.expand_button_icon); } /** * Show the touchable area of the view for a11y. * If the parent is the touch container, then that view's bounds are the touchable area. */ @Override public void getBoundsOnScreen(Rect outRect, boolean clipToParent) { ViewGroup parent = (ViewGroup) getParent(); if (parent != null && parent.getId() == R.id.expand_button_touch_container) { parent.getBoundsOnScreen(outRect, clipToParent); } else { super.getBoundsOnScreen(outRect, clipToParent); } } /** * Determined if the given point should be touchable. * If the parent is the touch container, then any point in that view should be touchable. */ @Override public boolean pointInView(float localX, float localY, float slop) { ViewGroup parent = (ViewGroup) getParent(); if (parent != null && parent.getId() == R.id.expand_button_touch_container) { // If our parent is checking with us, then the point must be within its bounds. return true; } return super.pointInView(localX, localY, slop); } @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); info.setClassName(Button.class.getName()); } /** * Update the button's drawable, content description, and color for the given expanded state. */ @RemotableViewMethod public void setExpanded(boolean expanded) { mExpanded = expanded; updateExpandedState(); } private void updateExpandedState() { int drawableId; int contentDescriptionId; if (mExpanded) { drawableId = R.drawable.ic_collapse_notification; contentDescriptionId = R.string.expand_button_content_description_expanded; } else { drawableId = R.drawable.ic_expand_notification; contentDescriptionId = R.string.expand_button_content_description_collapsed; } setContentDescription(mContext.getText(contentDescriptionId)); mIconView.setImageDrawable(getContext().getDrawable(drawableId)); // changing the expanded state can affect the number display updateNumber(); } private void updateNumber() { if (shouldShowNumber()) { CharSequence text = mNumber >= 100 ? getResources().getString(R.string.unread_convo_overflow, 99) : String.format(Locale.getDefault(), "%d", mNumber); mNumberView.setText(text); mNumberView.setVisibility(VISIBLE); } else { mNumberView.setVisibility(GONE); } // changing number can affect the color updateColors(); } private void updateColors() { if (shouldShowNumber()) { if (mHighlightPillColor != 0) { mPillDrawable.setTintList(ColorStateList.valueOf(mHighlightPillColor)); } mIconView.setColorFilter(mHighlightTextColor); if (mHighlightTextColor != 0) { mNumberView.setTextColor(mHighlightTextColor); } } else { if (mDefaultPillColor != 0) { mPillDrawable.setTintList(ColorStateList.valueOf(mDefaultPillColor)); } mIconView.setColorFilter(mDefaultTextColor); if (mDefaultTextColor != 0) { mNumberView.setTextColor(mDefaultTextColor); } } } private boolean shouldShowNumber() { return !mExpanded && mNumber > 1; } /** * Set the color used for the expand chevron and the text */ @RemotableViewMethod public void setDefaultTextColor(int color) { mDefaultTextColor = color; updateColors(); } /** * Sets the color used to for the expander when there is no number shown */ @RemotableViewMethod public void setDefaultPillColor(@ColorInt int color) { mDefaultPillColor = color; updateColors(); } /** * Set the color used for the expand chevron and the text */ @RemotableViewMethod public void setHighlightTextColor(int color) { mHighlightTextColor = color; updateColors(); } /** * Sets the color used to highlight the expander when there is a number shown */ @RemotableViewMethod public void setHighlightPillColor(@ColorInt int color) { mHighlightPillColor = color; updateColors(); } /** * Sets the number shown inside the expand button. * This only appears when the expand button is collapsed, and when greater than 1. */ @RemotableViewMethod public void setNumber(int number) { if (mNumber != number) { mNumber = number; updateNumber(); } } }