blob: 2e498b5d8ce9210b55c3755c77490733463a4f11 [file] [log] [blame]
/*
* Copyright (C) 2012 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.deskclock.widget;
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.deskclock.R;
/**
* A custom {@link View} that exposes an action to the user.
* <p>
* This is a copy of packages/apps/UnifiedEmail/src/com/android/mail/ui/ActionableToastBar.java
* with minor modifications.
*/
public class ActionableToastBar extends LinearLayout {
private boolean mHidden = false;
private Animator mShowAnimation;
private Animator mHideAnimation;
private final int mBottomMarginSizeInConversation;
/** Icon for the description. */
private ImageView mActionDescriptionIcon;
/** The clickable view */
private View mActionButton;
/** Icon for the action button. */
private View mActionIcon;
/** The view that contains the description. */
private TextView mActionDescriptionView;
/** The view that contains the text for the action button. */
private TextView mActionText;
//private ToastBarOperation mOperation;
public ActionableToastBar(Context context) {
this(context, null);
}
public ActionableToastBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ActionableToastBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mBottomMarginSizeInConversation = context.getResources().getDimensionPixelSize(
R.dimen.toast_bar_bottom_margin_in_conversation);
LayoutInflater.from(context).inflate(R.layout.actionable_toast_row, this, true);
}
@Override
protected void onFinishInflate() {
super.onFinishInflate();
mActionDescriptionIcon = (ImageView) findViewById(R.id.description_icon);
mActionDescriptionView = (TextView) findViewById(R.id.description_text);
mActionButton = findViewById(R.id.action_button);
mActionIcon = findViewById(R.id.action_icon);
mActionText = (TextView) findViewById(R.id.action_text);
}
/**
* Tells the view that it will be appearing in the conversation pane
* and should adjust its layout parameters accordingly.
* @param isInConversationMode true if the view will be shown in the conversation view
*/
public void setConversationMode(boolean isInConversationMode) {
final FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) getLayoutParams();
params.bottomMargin = isInConversationMode ? mBottomMarginSizeInConversation : 0;
setLayoutParams(params);
}
/**
* Displays the toast bar and makes it visible. Allows the setting of
* parameters to customize the display.
* @param listener performs some action when the action button is clicked
* @param descriptionIconResourceId resource ID for the description icon or
* 0 if no icon should be shown
* @param descriptionText a description text to show in the toast bar
* @param showActionIcon if true, the action button icon should be shown
* @param actionTextResource resource ID for the text to show in the action button
* @param replaceVisibleToast if true, this toast should replace any currently visible toast.
* Otherwise, skip showing this toast.
*/
public void show(final ActionClickedListener listener, int descriptionIconResourceId,
CharSequence descriptionText, boolean showActionIcon, int actionTextResource,
boolean replaceVisibleToast) {
if (!mHidden && !replaceVisibleToast) {
return;
}
mActionButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View widget) {
if (listener != null) {
listener.onActionClicked();
}
hide(true);
}
});
// Set description icon.
if (descriptionIconResourceId == 0) {
mActionDescriptionIcon.setVisibility(GONE);
} else {
mActionDescriptionIcon.setVisibility(VISIBLE);
mActionDescriptionIcon.setImageResource(descriptionIconResourceId);
}
mActionDescriptionView.setText(descriptionText);
mActionIcon.setVisibility(showActionIcon ? VISIBLE : GONE);
mActionText.setText(actionTextResource);
mHidden = false;
getShowAnimation().start();
}
/**
* Hides the view and resets the state.
*/
public void hide(boolean animate) {
// Prevent multiple call to hide.
// Also prevent hiding if show animation is going on.
if (!mHidden && !getShowAnimation().isRunning()) {
mHidden = true;
if (getVisibility() == View.VISIBLE) {
mActionDescriptionView.setText("");
mActionButton.setOnClickListener(null);
// Hide view once it's clicked.
if (animate) {
getHideAnimation().start();
} else {
setAlpha(0);
setVisibility(View.GONE);
}
}
}
}
private Animator getShowAnimation() {
if (mShowAnimation == null) {
mShowAnimation = AnimatorInflater.loadAnimator(getContext(),
R.anim.fade_in);
mShowAnimation.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
// There is a tiny change that and hide animation could have finished right
// before the show animation finished. In that case, the hide will mark the
// view as GONE. We need to make sure the last one wins.
setVisibility(View.VISIBLE);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
mShowAnimation.setTarget(this);
}
return mShowAnimation;
}
private Animator getHideAnimation() {
if (mHideAnimation == null) {
mHideAnimation = AnimatorInflater.loadAnimator(getContext(),
R.anim.fade_out);
mHideAnimation.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
setVisibility(View.GONE);
}
@Override
public void onAnimationCancel(Animator animation) {
}
});
mHideAnimation.setTarget(this);
}
return mHideAnimation;
}
public boolean isEventInToastBar(MotionEvent event) {
if (!isShown()) {
return false;
}
int[] xy = new int[2];
float x = event.getX();
float y = event.getY();
getLocationOnScreen(xy);
return (x > xy[0] && x < (xy[0] + getWidth()) && y > xy[1] && y < xy[1] + getHeight());
}
/**
* Classes that wish to perform some action when the action button is clicked
* should implement this interface.
*/
public interface ActionClickedListener {
public void onActionClicked();
}
}