blob: 1f4b7b68a80edf9ba0d660b79762f82db3e02a1a [file] [log] [blame]
/*
* 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.car.apps.common;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import java.util.Objects;
/**
* A view where updating the image will show certain animations. Current animations include fading
* in and scaling down the new image.
*/
public class CrossfadeImageView extends FrameLayout {
private final CropAlignedImageView mImageView1;
private final CropAlignedImageView mImageView2;
private CropAlignedImageView mActiveImageView;
private CropAlignedImageView mInactiveImageView;
private Bitmap mCurrentBitmap = null;
private Integer mCurrentColor = null;
private Animation mImageInAnimation;
private Animation mImageOutAnimation;
public CrossfadeImageView(Context context) {
this(context, null);
}
public CrossfadeImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CrossfadeImageView(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public CrossfadeImageView(Context context, AttributeSet attrs,
int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
LayoutParams lp = new LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
ImageView imageViewBackground = new ImageView(context, attrs, defStyleAttr, defStyleRes);
imageViewBackground.setLayoutParams(lp);
imageViewBackground.setBackgroundColor(Color.BLACK);
addView(imageViewBackground);
mImageView1 = new CropAlignedImageView(context, attrs, defStyleAttr, defStyleRes);
mImageView1.setLayoutParams(lp);
addView(mImageView1);
mImageView2 = new CropAlignedImageView(context, attrs, defStyleAttr, defStyleRes);
mImageView2.setLayoutParams(lp);
addView(mImageView2);
mActiveImageView = mImageView1;
mInactiveImageView = mImageView2;
mImageInAnimation = AnimationUtils.loadAnimation(context, R.anim.image_in);
mImageInAnimation.setInterpolator(new DecelerateInterpolator());
mImageOutAnimation = AnimationUtils.loadAnimation(context, R.anim.image_out);
}
/**
* Sets the image to show on this view
*
* @param bitmap image to show
* @param showAnimation whether the transition should be animated or not.
*/
public void setImageBitmap(Bitmap bitmap, boolean showAnimation) {
if (Objects.equals(mCurrentBitmap, bitmap)) {
return;
}
mCurrentBitmap = bitmap;
mCurrentColor = null;
mInactiveImageView.setImageBitmap(bitmap);
if (showAnimation) {
animateViews();
} else {
mActiveImageView.setImageBitmap(bitmap);
}
}
/**
* Sets a plain color as background, with an animated transition
*/
@Override
public void setBackgroundColor(int color) {
if (mCurrentColor != null && mCurrentColor == color) {
return;
}
mInactiveImageView.setImageBitmap(null);
mCurrentBitmap = null;
mCurrentColor = color;
mInactiveImageView.setBackgroundColor(color);
animateViews();
}
private final Animation.AnimationListener mAnimationListener =
new Animation.AnimationListener() {
@Override
public void onAnimationEnd(Animation animation) {
if (mInactiveImageView != null) {
mInactiveImageView.setVisibility(View.GONE);
}
}
@Override
public void onAnimationStart(Animation animation) { }
@Override
public void onAnimationRepeat(Animation animation) { }
};
private void animateViews() {
mInactiveImageView.setVisibility(View.VISIBLE);
mInactiveImageView.startAnimation(mImageInAnimation);
mInactiveImageView.bringToFront();
mActiveImageView.startAnimation(mImageOutAnimation);
mImageOutAnimation.setAnimationListener(mAnimationListener);
if (mActiveImageView == mImageView1) {
mActiveImageView = mImageView2;
mInactiveImageView = mImageView1;
} else {
mActiveImageView = mImageView1;
mInactiveImageView = mImageView2;
}
}
/**
* Sets the additional image scale. See {@link
* com.android.car.apps.common.CropAlignedImageView#setImageAdditionalScale(float)}
* for more details.
*/
public void setImageAdditionalScale(float scale) {
mImageView2.setImageAdditionalScale(scale);
mImageView1.setImageAdditionalScale(scale);
}
}