blob: 9bce381b63bdd62f25f890458cba13ab1af00fd0 [file] [log] [blame]
/*
* Copyright (C) 2013 Google Inc.
* Licensed to 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.mail.ui;
import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.app.Fragment;
import android.content.res.Resources;
import android.os.Handler;
import android.view.View;
import com.android.mail.R;
import com.android.mail.utils.Utils;
/**
* <p>Controller to handle showing and hiding progress in the conversation views.</p>
* <br>
* <b>NOTE:</b> This class makes several assumptions about the view hierarchy
* of the conversation view. Use with care.
*/
public class ConversationViewProgressController {
private static int sMinDelay = -1;
private static int sMinShowTime = -1;
private final Handler mHandler;
private final Fragment mFragment;
private long mLoadingShownTime = -1;
private View mProgressView;
private View mBackgroundView;
private final Runnable mDelayedShow;
public ConversationViewProgressController(Fragment fragment, Handler handler) {
mFragment = fragment;
mHandler = handler;
mDelayedShow = new FragmentRunnable("mDelayedShow", mFragment) {
@Override
public void go() {
mLoadingShownTime = System.currentTimeMillis();
mProgressView.setVisibility(View.VISIBLE);
}
};
}
public void instantiateProgressIndicators(View rootView) {
mBackgroundView = rootView.findViewById(R.id.background_view);
mProgressView = rootView.findViewById(R.id.loading_progress);
}
public void showLoadingStatus(boolean isFragmentUserVisible) {
if (!isFragmentUserVisible) {
return;
}
if (sMinDelay == -1) {
Resources res = mFragment.getResources();
sMinDelay = res.getInteger(R.integer.conversationview_show_loading_delay);
sMinShowTime = res.getInteger(R.integer.conversationview_min_show_loading);
}
// If the loading view isn't already showing, show it and remove any
// pending calls to show the loading screen.
mBackgroundView.setVisibility(View.VISIBLE);
mHandler.removeCallbacks(mDelayedShow);
mHandler.postDelayed(mDelayedShow, sMinDelay);
}
protected void dismissLoadingStatus() {
dismissLoadingStatus(null);
}
/**
* Begin the fade-out animation to hide the Progress overlay, either immediately or after some
* timeout (to ensure that the progress minimum time elapses).
*
* @param doAfter an optional Runnable action to execute after the animation completes
*/
protected void dismissLoadingStatus(final Runnable doAfter) {
if (mLoadingShownTime == -1) {
// The runnable hasn't run yet, so just remove it.
mHandler.removeCallbacks(mDelayedShow);
dismiss(doAfter);
return;
}
final long diff = Math.abs(System.currentTimeMillis() - mLoadingShownTime);
if (diff > sMinShowTime) {
dismiss(doAfter);
} else {
mHandler.postDelayed(new FragmentRunnable("dismissLoadingStatus", mFragment) {
@Override
public void go() {
dismiss(doAfter);
}
}, Math.abs(sMinShowTime - diff));
}
}
private void dismiss(final Runnable doAfter) {
// Reset loading shown time.
mLoadingShownTime = -1;
mProgressView.setVisibility(View.GONE);
if (mBackgroundView.getVisibility() == View.VISIBLE) {
animateDismiss(doAfter);
} else {
if (doAfter != null) {
doAfter.run();
}
}
}
private void animateDismiss(final Runnable doAfter) {
// the animation can only work (and is only worth doing) if this fragment is added
// reasons it may not be added: fragment is being destroyed, or in the process of being
// restored
if (!mFragment.isAdded()) {
mBackgroundView.setVisibility(View.GONE);
return;
}
Utils.enableHardwareLayer(mBackgroundView);
final Animator animator = AnimatorInflater.loadAnimator(
mFragment.getActivity().getApplicationContext(), R.anim.fade_out);
animator.setTarget(mBackgroundView);
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
mBackgroundView.setVisibility(View.GONE);
mBackgroundView.setLayerType(View.LAYER_TYPE_NONE, null);
if (doAfter != null) {
doAfter.run();
}
}
});
animator.start();
}
}