| /* |
| * Copyright (C) 2008 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.calculator2; |
| |
| import android.content.Context; |
| import android.util.AttributeSet; |
| import android.view.GestureDetector; |
| import android.view.MotionEvent; |
| import android.view.View; |
| import android.view.animation.AccelerateDecelerateInterpolator; |
| import android.view.animation.Animation; |
| import android.view.animation.Animation.AnimationListener; |
| import android.view.animation.TranslateAnimation; |
| import android.widget.FrameLayout; |
| |
| class PanelSwitcher extends FrameLayout implements AnimationListener { |
| private static final int MAJOR_MOVE = 60; |
| private static final int ANIM_DURATION = 400; |
| |
| private GestureDetector mGestureDetector; |
| private int mCurrentView; |
| private View mChildren[] = new View[0]; |
| |
| private int mWidth; |
| private TranslateAnimation inLeft; |
| private TranslateAnimation outLeft; |
| |
| private TranslateAnimation inRight; |
| private TranslateAnimation outRight; |
| |
| private static final int LEFT = 1; |
| private static final int RIGHT = 2; |
| private int mPreviousMove; |
| |
| public interface Listener { |
| void onChange(); |
| } |
| |
| private Listener mListener; |
| |
| public PanelSwitcher(Context context, AttributeSet attrs) { |
| super(context, attrs); |
| mCurrentView = 0; |
| mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { |
| @Override |
| public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, |
| float velocityY) { |
| int dx = (int) (e2.getX() - e1.getX()); |
| |
| // don't accept the fling if it's too short |
| // as it may conflict with a button push |
| if (Math.abs(dx) > MAJOR_MOVE && Math.abs(velocityX) > Math.abs(velocityY)) { |
| if (velocityX > 0) { |
| moveRight(); |
| } else { |
| moveLeft(); |
| } |
| return true; |
| } else { |
| return false; |
| } |
| } |
| }); |
| } |
| |
| public void setListener(Listener listener) { |
| this.mListener = listener; |
| } |
| |
| void setCurrentIndex(int current) { |
| boolean changed = mCurrentView != current; |
| mCurrentView = current; |
| updateCurrentView(); |
| if (changed && mListener != null) { |
| mListener.onChange(); |
| } |
| } |
| |
| private void updateCurrentView() { |
| for (int i = mChildren.length-1; i >= 0 ; --i) { |
| mChildren[i].setVisibility(i==mCurrentView ? View.VISIBLE : View.GONE); |
| } |
| } |
| |
| @Override |
| public void onSizeChanged(int w, int h, int oldW, int oldH) { |
| mWidth = w; |
| inLeft = new TranslateAnimation(mWidth, 0, 0, 0); |
| inLeft.setAnimationListener(this); |
| outLeft = new TranslateAnimation(0, -mWidth, 0, 0); |
| inRight = new TranslateAnimation(-mWidth, 0, 0, 0); |
| inRight.setAnimationListener(this); |
| outRight = new TranslateAnimation(0, mWidth, 0, 0); |
| |
| inLeft.setDuration(ANIM_DURATION); |
| outLeft.setDuration(ANIM_DURATION); |
| inRight.setDuration(ANIM_DURATION); |
| outRight.setDuration(ANIM_DURATION); |
| } |
| |
| @Override |
| protected void onFinishInflate() { |
| int count = getChildCount(); |
| mChildren = new View[count]; |
| for (int i = 0; i < count; ++i) { |
| mChildren[i] = getChildAt(i); |
| } |
| updateCurrentView(); |
| } |
| |
| @Override |
| public boolean onTouchEvent(MotionEvent event) { |
| mGestureDetector.onTouchEvent(event); |
| return true; |
| } |
| |
| @Override |
| public boolean onInterceptTouchEvent(MotionEvent event) { |
| return mGestureDetector.onTouchEvent(event); |
| } |
| |
| void moveLeft() { |
| // <-- |
| if (mCurrentView < mChildren.length - 1 && mPreviousMove != LEFT) { |
| mChildren[mCurrentView+1].setVisibility(View.VISIBLE); |
| mChildren[mCurrentView+1].startAnimation(inLeft); |
| mChildren[mCurrentView].startAnimation(outLeft); |
| mChildren[mCurrentView].setVisibility(View.GONE); |
| |
| mCurrentView++; |
| mPreviousMove = LEFT; |
| } |
| } |
| |
| void moveRight() { |
| // --> |
| if (mCurrentView > 0 && mPreviousMove != RIGHT) { |
| mChildren[mCurrentView-1].setVisibility(View.VISIBLE); |
| mChildren[mCurrentView-1].startAnimation(inRight); |
| mChildren[mCurrentView].startAnimation(outRight); |
| mChildren[mCurrentView].setVisibility(View.GONE); |
| |
| mCurrentView--; |
| mPreviousMove = RIGHT; |
| } |
| } |
| |
| int getCurrentIndex() { |
| return mCurrentView; |
| } |
| |
| @Override |
| public void onAnimationRepeat(Animation animation) { |
| } |
| |
| @Override |
| public void onAnimationStart(Animation animation) { |
| } |
| |
| @Override |
| public void onAnimationEnd(Animation animation) { |
| if (mListener != null) { |
| mListener.onChange(); |
| } |
| } |
| } |