MotionEventCompat.java revision 0574ca37da4619afe4e26753f5a1b4de314b6565
1/*
2 * Copyright (C) 2011 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
17package android.support.v4.view;
18
19import android.view.MotionEvent;
20
21/**
22 * Helper for accessing features in {@link MotionEvent} introduced
23 * after API level 4 in a backwards compatible fashion.
24 */
25public class MotionEventCompat {
26    /**
27     * Interface for the full API.
28     */
29    interface MotionEventVersionImpl {
30        public int findPointerIndex(MotionEvent event, int pointerId);
31        public int getPointerId(MotionEvent event, int pointerIndex);
32        public float getX(MotionEvent event, int pointerIndex);
33        public float getY(MotionEvent event, int pointerIndex);
34    }
35
36    /**
37     * Interface implementation that doesn't use anything about v4 APIs.
38     */
39    static class BaseMotionEventVersionImpl implements MotionEventVersionImpl {
40        @Override
41        public int findPointerIndex(MotionEvent event, int pointerId) {
42            if (pointerId == 0) {
43                // id 0 == index 0 and vice versa.
44                return 0;
45            }
46            return -1;
47        }
48        @Override
49        public int getPointerId(MotionEvent event, int pointerIndex) {
50            if (pointerIndex == 0) {
51                // index 0 == id 0 and vice versa.
52                return 0;
53            }
54            throw new IndexOutOfBoundsException("Pre-Eclair does not support multiple pointers");
55        }
56        @Override
57        public float getX(MotionEvent event, int pointerIndex) {
58            if (pointerIndex == 0) {
59                return event.getX();
60            }
61            throw new IndexOutOfBoundsException("Pre-Eclair does not support multiple pointers");
62        }
63        @Override
64        public float getY(MotionEvent event, int pointerIndex) {
65            if (pointerIndex == 0) {
66                return event.getY();
67            }
68            throw new IndexOutOfBoundsException("Pre-Eclair does not support multiple pointers");
69        }
70    }
71
72    /**
73     * Interface implementation for devices with at least v11 APIs.
74     */
75    static class EclairMotionEventVersionImpl implements MotionEventVersionImpl {
76        @Override
77        public int findPointerIndex(MotionEvent event, int pointerId) {
78            return MotionEventCompatEclair.findPointerIndex(event, pointerId);
79        }
80        @Override
81        public int getPointerId(MotionEvent event, int pointerIndex) {
82            return MotionEventCompatEclair.getPointerId(event, pointerIndex);
83        }
84        @Override
85        public float getX(MotionEvent event, int pointerIndex) {
86            return MotionEventCompatEclair.getX(event, pointerIndex);
87        }
88        @Override
89        public float getY(MotionEvent event, int pointerIndex) {
90            return MotionEventCompatEclair.getY(event, pointerIndex);
91        }
92    }
93
94    /**
95     * Select the correct implementation to use for the current platform.
96     */
97    static final MotionEventVersionImpl IMPL;
98    static {
99        if (android.os.Build.VERSION.SDK_INT >= 5) {
100            IMPL = new EclairMotionEventVersionImpl();
101        } else {
102            IMPL = new BaseMotionEventVersionImpl();
103        }
104    }
105
106    // -------------------------------------------------------------------
107
108    /**
109     * Synonym for {@link MotionEvent#ACTION_MASK}.
110     */
111    public static final int ACTION_MASK = 0xff;
112
113    /**
114     * Synonym for {@link MotionEvent#ACTION_POINTER_DOWN}.
115     */
116    public static final int ACTION_POINTER_DOWN = 5;
117
118    /**
119     * Synonym for {@link MotionEvent#ACTION_POINTER_UP}.
120     */
121    public static final int ACTION_POINTER_UP = 6;
122
123    /**
124     * Synonym for {@link MotionEvent#ACTION_HOVER_MOVE}.
125     */
126    public static final int ACTION_HOVER_MOVE = 7;
127
128    /**
129     * Synonym for {@link MotionEvent#ACTION_SCROLL}.
130     */
131    public static final int ACTION_SCROLL = 8;
132
133    /**
134     * Synonym for {@link MotionEvent#ACTION_POINTER_INDEX_MASK}.
135     */
136    public static final int ACTION_POINTER_INDEX_MASK  = 0xff00;
137
138    /**
139     * Synonym for {@link MotionEvent#ACTION_POINTER_INDEX_SHIFT}.
140     */
141    public static final int ACTION_POINTER_INDEX_SHIFT = 8;
142
143    /**
144     * Call {@link MotionEvent#getAction}, returning only the {@link #ACTION_MASK}
145     * portion.
146     */
147    public static int getActionMasked(MotionEvent event) {
148        return event.getAction() & ACTION_MASK;
149    }
150
151    /**
152     * Call {@link MotionEvent#getAction}, returning only the pointer index
153     * portion
154     */
155    public static int getActionIndex(MotionEvent event) {
156        return (event.getAction() & ACTION_POINTER_INDEX_MASK)
157                >> ACTION_POINTER_INDEX_SHIFT;
158    }
159
160    /**
161     * Call {@link MotionEvent#findPointerIndex(int)}.
162     * If running on a pre-{@link android.os.Build.VERSION_CODES#ECLAIR} device,
163     * does nothing and returns -1.
164     */
165    public static int findPointerIndex(MotionEvent event, int pointerId) {
166        return IMPL.findPointerIndex(event, pointerId);
167    }
168
169    /**
170     * Call {@link MotionEvent#getPointerId(int)}.
171     * If running on a pre-{@link android.os.Build.VERSION_CODES#ECLAIR} device,
172     * {@link IndexOutOfBoundsException} is thrown.
173     */
174    public static int getPointerId(MotionEvent event, int pointerIndex) {
175        return IMPL.getPointerId(event, pointerIndex);
176    }
177
178    /**
179     * Call {@link MotionEvent#getX(int)}.
180     * If running on a pre-{@link android.os.Build.VERSION_CODES#ECLAIR} device,
181     * {@link IndexOutOfBoundsException} is thrown.
182     */
183    public static float getX(MotionEvent event, int pointerIndex) {
184        return IMPL.getX(event, pointerIndex);
185    }
186
187    /**
188     * Call {@link MotionEvent#getY(int)}.
189     * If running on a pre-{@link android.os.Build.VERSION_CODES#ECLAIR} device,
190     * {@link IndexOutOfBoundsException} is thrown.
191     */
192    public static float getY(MotionEvent event, int pointerIndex) {
193        return IMPL.getY(event, pointerIndex);
194    }
195}
196