1 /* 2 * Copyright (C) 2014 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.deskclock; 18 19 import android.content.Context; 20 import android.support.v4.view.ViewPager; 21 import android.util.AttributeSet; 22 import android.view.MotionEvent; 23 import android.view.View; 24 25 public class VerticalViewPager extends ViewPager { 26 VerticalViewPager(Context context)27 public VerticalViewPager(Context context) { 28 this(context, null); 29 } 30 VerticalViewPager(Context context, AttributeSet attrs)31 public VerticalViewPager(Context context, AttributeSet attrs) { 32 super(context, attrs); 33 init(); 34 } 35 36 /** 37 * @return {@code false} since a vertical view pager can never be scrolled horizontally 38 */ 39 @Override canScrollHorizontally(int direction)40 public boolean canScrollHorizontally(int direction) { 41 return false; 42 } 43 44 /** 45 * @return {@code true} iff a normal view pager would support horizontal scrolling at this time 46 */ 47 @Override canScrollVertically(int direction)48 public boolean canScrollVertically(int direction) { 49 return super.canScrollHorizontally(direction); 50 } 51 init()52 private void init() { 53 // Make page transit vertical 54 setPageTransformer(true, new VerticalPageTransformer()); 55 // Get rid of the overscroll drawing that happens on the left and right (the ripple) 56 setOverScrollMode(View.OVER_SCROLL_NEVER); 57 } 58 59 @Override onInterceptTouchEvent(MotionEvent ev)60 public boolean onInterceptTouchEvent(MotionEvent ev) { 61 final boolean toIntercept = super.onInterceptTouchEvent(flipXY(ev)); 62 // Return MotionEvent to normal 63 flipXY(ev); 64 return toIntercept; 65 } 66 67 @Override onTouchEvent(MotionEvent ev)68 public boolean onTouchEvent(MotionEvent ev) { 69 final boolean toHandle = super.onTouchEvent(flipXY(ev)); 70 // Return MotionEvent to normal 71 flipXY(ev); 72 return toHandle; 73 } 74 flipXY(MotionEvent ev)75 private MotionEvent flipXY(MotionEvent ev) { 76 final float width = getWidth(); 77 final float height = getHeight(); 78 79 final float x = (ev.getY() / height) * width; 80 final float y = (ev.getX() / width) * height; 81 82 ev.setLocation(x, y); 83 84 return ev; 85 } 86 87 private static final class VerticalPageTransformer implements ViewPager.PageTransformer { 88 @Override transformPage(View view, float position)89 public void transformPage(View view, float position) { 90 final int pageWidth = view.getWidth(); 91 final int pageHeight = view.getHeight(); 92 if (position < -1) { 93 // This page is way off-screen to the left. 94 view.setAlpha(0); 95 } else if (position <= 1) { 96 view.setAlpha(1); 97 // Counteract the default slide transition 98 view.setTranslationX(pageWidth * -position); 99 // set Y position to swipe in from top 100 float yPosition = position * pageHeight; 101 view.setTranslationY(yPosition); 102 } else { 103 // This page is way off-screen to the right. 104 view.setAlpha(0); 105 } 106 } 107 } 108 } 109