1b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project/* 2b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * 4b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * you may not use this file except in compliance with the License. 6b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * You may obtain a copy of the License at 7b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * 8b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * 10b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * See the License for the specific language governing permissions and 14b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project * limitations under the License. 15b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project */ 16b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 17b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Projectpackage com.android.calculator2; 18b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 19052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikovimport android.content.Context; 20052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikovimport android.util.AttributeSet; 21052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikovimport android.view.GestureDetector; 22b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Projectimport android.view.MotionEvent; 23b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Projectimport android.view.View; 24052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikovimport android.view.animation.Animation; 25052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikovimport android.view.animation.Animation.AnimationListener; 26052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikovimport android.view.animation.TranslateAnimation; 27b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Projectimport android.widget.FrameLayout; 28b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 29052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikovclass PanelSwitcher extends FrameLayout implements AnimationListener { 30b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project private static final int MAJOR_MOVE = 60; 31b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project private static final int ANIM_DURATION = 400; 32b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 33b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project private GestureDetector mGestureDetector; 34b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project private int mCurrentView; 35cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda private View mChildren[] = new View[0]; 36b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 37b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project private int mWidth; 38b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project private TranslateAnimation inLeft; 39b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project private TranslateAnimation outLeft; 40b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 41b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project private TranslateAnimation inRight; 42b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project private TranslateAnimation outRight; 43b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 445a589624ae4c334987e725c710833cd3588b90feChristian Mehlmauer private static final int LEFT = 1; 455a589624ae4c334987e725c710833cd3588b90feChristian Mehlmauer private static final int RIGHT = 2; 46b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project private int mPreviousMove; 47b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 48052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov public interface Listener { 49052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov void onChange(); 50052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov } 51052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov 52052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov private Listener mListener; 53052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov 54b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project public PanelSwitcher(Context context, AttributeSet attrs) { 55b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project super(context, attrs); 56b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project mCurrentView = 0; 57b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() { 58052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov @Override 59b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, 60b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project float velocityY) { 61b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project int dx = (int) (e2.getX() - e1.getX()); 62b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 63b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project // don't accept the fling if it's too short 64b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project // as it may conflict with a button push 65b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project if (Math.abs(dx) > MAJOR_MOVE && Math.abs(velocityX) > Math.abs(velocityY)) { 66b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project if (velocityX > 0) { 67b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project moveRight(); 68b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project } else { 69b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project moveLeft(); 70b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project } 71b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project return true; 72b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project } else { 73b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project return false; 74b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project } 75b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project } 76b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project }); 77b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project } 78b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 79052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov public void setListener(Listener listener) { 80052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov this.mListener = listener; 81052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov } 82052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov 83cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda void setCurrentIndex(int current) { 84052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov boolean changed = mCurrentView != current; 85cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda mCurrentView = current; 86cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda updateCurrentView(); 87052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov if (changed && mListener != null) { 88052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov mListener.onChange(); 89052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov } 90cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda } 91cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda 92cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda private void updateCurrentView() { 93cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda for (int i = mChildren.length-1; i >= 0 ; --i) { 94cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda mChildren[i].setVisibility(i==mCurrentView ? View.VISIBLE : View.GONE); 95cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda } 96cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda } 97cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda 98052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov @Override 99b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project public void onSizeChanged(int w, int h, int oldW, int oldH) { 100b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project mWidth = w; 101b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project inLeft = new TranslateAnimation(mWidth, 0, 0, 0); 102052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov inLeft.setAnimationListener(this); 103052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov outLeft = new TranslateAnimation(0, -mWidth, 0, 0); 104b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project inRight = new TranslateAnimation(-mWidth, 0, 0, 0); 105052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov inRight.setAnimationListener(this); 106b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project outRight = new TranslateAnimation(0, mWidth, 0, 0); 107b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 108b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project inLeft.setDuration(ANIM_DURATION); 109b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project outLeft.setDuration(ANIM_DURATION); 110b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project inRight.setDuration(ANIM_DURATION); 111b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project outRight.setDuration(ANIM_DURATION); 112b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project } 113b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 114052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov @Override 115b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project protected void onFinishInflate() { 116b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project int count = getChildCount(); 117cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda mChildren = new View[count]; 118b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project for (int i = 0; i < count; ++i) { 119cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda mChildren[i] = getChildAt(i); 120b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project } 121cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda updateCurrentView(); 122b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project } 123b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 124b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project @Override 125b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project public boolean onTouchEvent(MotionEvent event) { 126b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project mGestureDetector.onTouchEvent(event); 127b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project return true; 128b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project } 129b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 130b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project @Override 131b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project public boolean onInterceptTouchEvent(MotionEvent event) { 132b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project return mGestureDetector.onTouchEvent(event); 133b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project } 134b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 135b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project void moveLeft() { 136b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project // <-- 137cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda if (mCurrentView < mChildren.length - 1 && mPreviousMove != LEFT) { 138cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda mChildren[mCurrentView+1].setVisibility(View.VISIBLE); 139cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda mChildren[mCurrentView+1].startAnimation(inLeft); 140cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda mChildren[mCurrentView].startAnimation(outLeft); 141cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda mChildren[mCurrentView].setVisibility(View.GONE); 142b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 143b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project mCurrentView++; 144b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project mPreviousMove = LEFT; 145b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project } 146b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project } 147b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 148b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project void moveRight() { 149b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project // --> 150b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project if (mCurrentView > 0 && mPreviousMove != RIGHT) { 151cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda mChildren[mCurrentView-1].setVisibility(View.VISIBLE); 152cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda mChildren[mCurrentView-1].startAnimation(inRight); 153cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda mChildren[mCurrentView].startAnimation(outRight); 154cf3ca321fa8cc1f5427454c5e2501b7978bb3711Mihai Preda mChildren[mCurrentView].setVisibility(View.GONE); 155b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 156b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project mCurrentView--; 157b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project mPreviousMove = RIGHT; 158b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project } 159b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project } 160b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project 161b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project int getCurrentIndex() { 162b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project return mCurrentView; 163b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project } 164052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov 165052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov @Override 166052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov public void onAnimationRepeat(Animation animation) { 167052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov } 168052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov 169052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov @Override 170052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov public void onAnimationStart(Animation animation) { 171052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov } 172052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov 173052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov @Override 174052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov public void onAnimationEnd(Animation animation) { 175052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov if (mListener != null) { 176052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov mListener.onChange(); 177052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov } 178052c92af9b70c42a84c989876c513b456d0a500eDmitri Plotnikov } 179b301ed2e1720fc9190eaf99ab33b5f49eabcebc5The Android Open Source Project} 180