blob: 626710e52fb74907913f128eb5f04332aeb7e1d0 [file] [log] [blame]
/*
* Copyright (C) 2015 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.documentsui.dirlist;
import android.animation.Animator;
import android.animation.ArgbEvaluator;
import android.animation.ValueAnimator;
import android.content.Context;
import androidx.collection.ArrayMap;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.RecyclerView;
import android.content.res.TypedArray;
import android.util.TypedValue;
import com.android.documentsui.R;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* Performs change animations on Items in DirectoryFragment's RecyclerView. This class overrides
* the way selection animations are normally performed - instead of cross fading the old Item with a
* new Item, this class manually animates a background color change. This enables selected Items to
* correctly maintain focus.
*/
class DirectoryItemAnimator extends DefaultItemAnimator {
private final List<ColorAnimation> mPendingAnimations = new ArrayList<>();
private final Map<RecyclerView.ViewHolder, ColorAnimation> mRunningAnimations =
new ArrayMap<>();
@Override
public void runPendingAnimations() {
super.runPendingAnimations();
for (ColorAnimation anim: mPendingAnimations) {
anim.start();
mRunningAnimations.put(anim.viewHolder, anim);
}
mPendingAnimations.clear();
}
@Override
public void endAnimation(RecyclerView.ViewHolder vh) {
super.endAnimation(vh);
for (int i = mPendingAnimations.size() - 1; i >= 0; --i) {
ColorAnimation anim = mPendingAnimations.get(i);
if (anim.viewHolder == vh) {
mPendingAnimations.remove(i);
anim.end();
}
}
ColorAnimation anim = mRunningAnimations.get(vh);
if (anim != null) {
anim.cancel();
}
}
@Override
public ItemHolderInfo recordPreLayoutInformation(
RecyclerView.State state,
RecyclerView.ViewHolder viewHolder,
@AdapterChanges int changeFlags,
List<Object> payloads) {
ItemInfo info = (ItemInfo) super.recordPreLayoutInformation(state,
viewHolder, changeFlags, payloads);
info.isActivated = viewHolder.itemView.isActivated();
return info;
}
@Override
public ItemHolderInfo recordPostLayoutInformation(
RecyclerView.State state, RecyclerView.ViewHolder viewHolder) {
ItemInfo info = (ItemInfo) super.recordPostLayoutInformation(state,
viewHolder);
info.isActivated = viewHolder.itemView.isActivated();
return info;
}
@Override
public ItemHolderInfo obtainHolderInfo() {
return new ItemInfo();
}
@Override
public boolean canReuseUpdatedViewHolder(RecyclerView.ViewHolder vh) {
return true;
}
class ItemInfo extends DefaultItemAnimator.ItemHolderInfo {
boolean isActivated;
};
/**
* Animates changes in background color.
*/
class ColorAnimation
implements ValueAnimator.AnimatorUpdateListener, Animator.AnimatorListener {
ValueAnimator mValueAnimator;
final RecyclerView.ViewHolder viewHolder;
int mEndColor;
public ColorAnimation(RecyclerView.ViewHolder vh, int startColor, int endColor)
{
viewHolder = vh;
mValueAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), startColor, endColor);
mValueAnimator.addUpdateListener(this);
mValueAnimator.addListener(this);
mEndColor = endColor;
}
public void start() {
mValueAnimator.start();
}
public void cancel() {
mValueAnimator.cancel();
}
public void end() {
mValueAnimator.end();
}
@Override
public void onAnimationUpdate(ValueAnimator animator) {
viewHolder.itemView.setBackgroundColor((Integer)animator.getAnimatedValue());
}
@Override
public void onAnimationEnd(Animator animator) {
viewHolder.itemView.setBackgroundColor(mEndColor);
mRunningAnimations.remove(viewHolder);
dispatchAnimationFinished(viewHolder);
}
@Override
public void onAnimationStart(Animator animation) {
dispatchAnimationStarted(viewHolder);
}
@Override
public void onAnimationCancel(Animator animation) {}
@Override
public void onAnimationRepeat(Animator animation) {}
};
};