Home | History | Annotate | Download | only in calculator2
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.calculator2;
     18 
     19 import android.content.Context;
     20 import android.util.AttributeSet;
     21 import android.view.GestureDetector;
     22 import android.view.MotionEvent;
     23 import android.view.View;
     24 import android.view.animation.Animation;
     25 import android.view.animation.Animation.AnimationListener;
     26 import android.view.animation.TranslateAnimation;
     27 import android.widget.FrameLayout;
     28 
     29 class PanelSwitcher extends FrameLayout implements AnimationListener {
     30     private static final int MAJOR_MOVE = 60;
     31     private static final int ANIM_DURATION = 400;
     32 
     33     private GestureDetector mGestureDetector;
     34     private int mCurrentView;
     35     private View mChildren[] = new View[0];
     36 
     37     private int mWidth;
     38     private TranslateAnimation inLeft;
     39     private TranslateAnimation outLeft;
     40 
     41     private TranslateAnimation inRight;
     42     private TranslateAnimation outRight;
     43 
     44     private static final int LEFT  = 1;
     45     private static final int RIGHT = 2;
     46     private int mPreviousMove;
     47 
     48     public interface Listener {
     49         void onChange();
     50     }
     51 
     52     private Listener mListener;
     53 
     54     public PanelSwitcher(Context context, AttributeSet attrs) {
     55         super(context, attrs);
     56         mCurrentView = 0;
     57         mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
     58                 @Override
     59                 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
     60                                        float velocityY) {
     61                     int dx = (int) (e2.getX() - e1.getX());
     62 
     63                     // don't accept the fling if it's too short
     64                     // as it may conflict with a button push
     65                     if (Math.abs(dx) > MAJOR_MOVE && Math.abs(velocityX) > Math.abs(velocityY)) {
     66                         if (velocityX > 0) {
     67                             moveRight();
     68                         } else {
     69                             moveLeft();
     70                         }
     71                         return true;
     72                     } else {
     73                         return false;
     74                     }
     75                 }
     76             });
     77     }
     78 
     79     public void setListener(Listener listener) {
     80         this.mListener = listener;
     81     }
     82 
     83     void setCurrentIndex(int current) {
     84         boolean changed = mCurrentView != current;
     85         mCurrentView = current;
     86         updateCurrentView();
     87         if (changed && mListener != null) {
     88             mListener.onChange();
     89         }
     90     }
     91 
     92     private void updateCurrentView() {
     93         for (int i = mChildren.length-1; i >= 0 ; --i) {
     94             mChildren[i].setVisibility(i==mCurrentView ? View.VISIBLE : View.GONE);
     95         }
     96     }
     97 
     98     @Override
     99     public void onSizeChanged(int w, int h, int oldW, int oldH) {
    100         mWidth = w;
    101         inLeft   = new TranslateAnimation(mWidth, 0, 0, 0);
    102         inLeft.setAnimationListener(this);
    103         outLeft  = new TranslateAnimation(0, -mWidth, 0, 0);
    104         inRight  = new TranslateAnimation(-mWidth, 0, 0, 0);
    105         inRight.setAnimationListener(this);
    106         outRight = new TranslateAnimation(0, mWidth, 0, 0);
    107 
    108         inLeft.setDuration(ANIM_DURATION);
    109         outLeft.setDuration(ANIM_DURATION);
    110         inRight.setDuration(ANIM_DURATION);
    111         outRight.setDuration(ANIM_DURATION);
    112     }
    113 
    114     @Override
    115     protected void onFinishInflate() {
    116         int count = getChildCount();
    117         mChildren = new View[count];
    118         for (int i = 0; i < count; ++i) {
    119             mChildren[i] = getChildAt(i);
    120         }
    121         updateCurrentView();
    122     }
    123 
    124     @Override
    125     public boolean onTouchEvent(MotionEvent event) {
    126         mGestureDetector.onTouchEvent(event);
    127         return true;
    128     }
    129 
    130     @Override
    131     public boolean onInterceptTouchEvent(MotionEvent event) {
    132         return mGestureDetector.onTouchEvent(event);
    133     }
    134 
    135     void moveLeft() {
    136         //  <--
    137         if (mCurrentView < mChildren.length - 1 && mPreviousMove != LEFT) {
    138             mChildren[mCurrentView+1].setVisibility(View.VISIBLE);
    139             mChildren[mCurrentView+1].startAnimation(inLeft);
    140             mChildren[mCurrentView].startAnimation(outLeft);
    141             mChildren[mCurrentView].setVisibility(View.GONE);
    142 
    143             mCurrentView++;
    144             mPreviousMove = LEFT;
    145         }
    146     }
    147 
    148     void moveRight() {
    149         //  -->
    150         if (mCurrentView > 0 && mPreviousMove != RIGHT) {
    151             mChildren[mCurrentView-1].setVisibility(View.VISIBLE);
    152             mChildren[mCurrentView-1].startAnimation(inRight);
    153             mChildren[mCurrentView].startAnimation(outRight);
    154             mChildren[mCurrentView].setVisibility(View.GONE);
    155 
    156             mCurrentView--;
    157             mPreviousMove = RIGHT;
    158         }
    159     }
    160 
    161     int getCurrentIndex() {
    162         return mCurrentView;
    163     }
    164 
    165     @Override
    166     public void onAnimationRepeat(Animation animation) {
    167     }
    168 
    169     @Override
    170     public void onAnimationStart(Animation animation) {
    171     }
    172 
    173     @Override
    174     public void onAnimationEnd(Animation animation) {
    175         if (mListener != null) {
    176             mListener.onChange();
    177         }
    178     }
    179 }
    180