blob: af02e8d0bf60de7a906115c8f88df14a144676a3 [file] [log] [blame]
/*
* Copyright (C) 2011 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.browser;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import com.android.browser.view.Gallery;
/**
* custom view for displaying tabs in the nav screen
*/
public class NavTabGallery extends Gallery {
interface OnRemoveListener {
public void onRemovePosition(int position);
}
// after drag animation velocity in pixels/sec
private static final float MIN_VELOCITY = 1500;
private OnRemoveListener mRemoveListener;
private boolean mBlockUpCallback;
private Animator mAnimator;
public NavTabGallery(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public NavTabGallery(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NavTabGallery(Context context) {
super(context);
}
public void setOnRemoveListener(OnRemoveListener l) {
mRemoveListener = l;
}
protected void setSelection(int ix) {
super.setSelectedPositionInt(ix);
}
protected int getSelectionIndex() {
return getSelectedItemPosition();
}
protected Tab getSelectedItem() {
return (Tab) mAdapter.getItem(getSelectedItemPosition());
}
View getSelectedTab() {
return getSelectedView();
}
@Override
protected void onOrthoDrag(View v, MotionEvent down, MotionEvent move,
float distance) {
if (mAnimator == null) {
offsetView(v, - distance);
}
}
@Override
protected void onOrthoFling(View v, MotionEvent down, MotionEvent move,
float velocity) {
if ((mAnimator == null) && (Math.abs(velocity) > MIN_VELOCITY)) {
mBlockUpCallback = true;
animateOut(v, velocity);
}
}
@Override
protected void onUp(View downView) {
if (mAnimator != null) return;
if (mBlockUpCallback) {
mBlockUpCallback = false;
return;
}
if (mIsOrthoDragged && downView != null) {
// offset
int diff = calculateTop(downView, false) - (mHorizontal ? downView.getTop()
: downView.getLeft());
if (Math.abs(diff) > (mHorizontal ? downView.getHeight() : downView.getWidth()) / 2) {
// remove it
animateOut(downView, - Math.signum(diff) * MIN_VELOCITY);
} else {
// snap back
offsetView(downView, diff);
}
} else {
super.onUp(downView);
}
}
private void offsetView(View v, float distance) {
if (mHorizontal) {
v.offsetTopAndBottom((int) distance);
} else {
v.offsetLeftAndRight((int) distance);
}
}
protected void animateOut(View v) {
animateOut(v, -MIN_VELOCITY);
}
private void animateOut(final View v, float velocity) {
if ((v == null) || (mAnimator != null)) return;
final int position = mFirstPosition + indexOfChild(v);
int target = 0;
if (velocity < 0) {
target = mHorizontal ? -v.getHeight() : - v.getWidth();
} else {
target = mHorizontal ? getHeight() : getWidth();
}
int distance = target - (mHorizontal ? v.getTop() : v.getLeft());
long duration = (long) (Math.abs(distance) * 1000 / Math.abs(velocity));
if (mHorizontal) {
mAnimator = ObjectAnimator.ofFloat(v, TRANSLATION_Y, 0, target);
} else {
mAnimator = ObjectAnimator.ofFloat(v, TRANSLATION_X, 0, target);
}
mAnimator.setDuration(duration);
mAnimator.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator a) {
if (mRemoveListener != null) {
boolean needsGap = position < (mAdapter.getCount() - 1);
if (needsGap) {
setGapPosition(position, mHorizontal ? v.getWidth() : v.getHeight());
}
mRemoveListener.onRemovePosition(position);
if (!needsGap && (position > 0) && (mAdapter.getCount() > 0)) {
scrollToChild(position - 1);
}
mAnimator = null;
}
}
});
mAnimator.start();
}
}