1a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte/* 2a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte * Copyright (C) 2017 The Android Open Source Project 3a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte * 4a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte * Licensed under the Apache License, Version 2.0 (the "License"); 5a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte * you may not use this file except in compliance with the License. 6a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte * You may obtain a copy of the License at 7a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte * 8a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte * http://www.apache.org/licenses/LICENSE-2.0 9a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte * 10a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte * Unless required by applicable law or agreed to in writing, software 11a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte * distributed under the License is distributed on an "AS IS" BASIS, 12a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte * See the License for the specific language governing permissions and 14a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte * limitations under the License. 15a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte */ 16a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 17a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whytepackage android.support.v7.widget; 18a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 19a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyteimport static org.junit.Assert.assertEquals; 20a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyteimport static org.junit.Assert.assertNotEquals; 21a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 22a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyteimport android.content.Context; 23a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyteimport android.support.test.InstrumentationRegistry; 24a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyteimport android.support.test.filters.SmallTest; 25a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyteimport android.support.test.runner.AndroidJUnit4; 26a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyteimport android.support.v4.view.InputDeviceCompat; 27a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyteimport android.support.v4.view.MotionEventCompat; 28a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyteimport android.support.v4.view.ViewConfigurationCompat; 29a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyteimport android.view.MotionEvent; 30a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyteimport android.view.View; 31a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyteimport android.view.ViewConfiguration; 32a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyteimport android.view.ViewGroup; 33a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyteimport android.widget.TextView; 34a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 35a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyteimport org.junit.Before; 36a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyteimport org.junit.Test; 37a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyteimport org.junit.runner.RunWith; 38a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 39a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte@SmallTest 40a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte@RunWith(AndroidJUnit4.class) 41a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whytepublic class RecyclerViewOnGenericMotionEventTest { 42a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 43a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte TestRecyclerView mRecyclerView; 44a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 45a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte @Before 46a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte public void setUp() throws Exception { 47a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte mRecyclerView = new TestRecyclerView(getContext()); 48a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 49a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 50a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte private Context getContext() { 51a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte return InstrumentationRegistry.getContext(); 52a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 53a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 54a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte private void layout() { 55a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte mRecyclerView.layout(0, 0, 320, 320); 56a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 57a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 58a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte @Test 59a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte public void rotaryEncoderVerticalScroll() { 60a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte MockLayoutManager layoutManager = new MockLayoutManager(true, true); 61a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte mRecyclerView.setLayoutManager(layoutManager); 62a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte layout(); 63a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte MotionEvent e = obtainScrollMotionEvent( 64a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte MotionEventCompat.AXIS_SCROLL, 2, InputDeviceCompat.SOURCE_ROTARY_ENCODER); 65a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte mRecyclerView.onGenericMotionEvent(e); 66a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte assertTotalScroll(0, (int) (-2f * getScaledVerticalScrollFactor())); 67a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 68a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 69a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte @Test 70a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte public void rotaryEncoderHorizontalScroll() { 71a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte // The encoder is one-dimensional, and can only scroll horizontally if vertical scrolling 72a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte // is not enabled. 73a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte MockLayoutManager layoutManager = new MockLayoutManager(true, false); 74a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte mRecyclerView.setLayoutManager(layoutManager); 75a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte layout(); 76a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte MotionEvent e = obtainScrollMotionEvent( 77a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte MotionEventCompat.AXIS_SCROLL, 2, InputDeviceCompat.SOURCE_ROTARY_ENCODER); 78a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte mRecyclerView.onGenericMotionEvent(e); 79a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte assertTotalScroll((int) (2f * getScaledHorizontalScrollFactor()), 0); 80a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 81a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 82a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte @Test 83a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte public void pointerVerticalScroll() { 84a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte MockLayoutManager layoutManager = new MockLayoutManager(true, true); 85a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte mRecyclerView.setLayoutManager(layoutManager); 86a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte layout(); 87a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte MotionEvent e = obtainScrollMotionEvent( 88a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte MotionEventCompat.AXIS_VSCROLL, 2, InputDeviceCompat.SOURCE_CLASS_POINTER); 89a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte mRecyclerView.onGenericMotionEvent(e); 90a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte assertTotalScroll(0, (int) (-2f * getScaledVerticalScrollFactor())); 91a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 92a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 93a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte @Test 94a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte public void pointerHorizontalScroll() { 95a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte MockLayoutManager layoutManager = new MockLayoutManager(true, true); 96a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte mRecyclerView.setLayoutManager(layoutManager); 97a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte layout(); 98a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte MotionEvent e = obtainScrollMotionEvent( 99a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte MotionEventCompat.AXIS_HSCROLL, 2, InputDeviceCompat.SOURCE_CLASS_POINTER); 100a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte mRecyclerView.onGenericMotionEvent(e); 101a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte assertTotalScroll((int) (2f * getScaledHorizontalScrollFactor()), 0); 102a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 103a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 104a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte @Test 105a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte public void nonZeroScaledVerticalScrollFactor() { 106a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte assertNotEquals(0, getScaledVerticalScrollFactor()); 107a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 108a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 109a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte @Test 110a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte public void nonZeroScaledHorizontalScrollFactor() { 111a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte assertNotEquals(0, getScaledHorizontalScrollFactor()); 112a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 113a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 114a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte private void assertTotalScroll(int x, int y) { 115a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte assertEquals("x total scroll", x, mRecyclerView.mTotalX); 116a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte assertEquals("y total scroll", y, mRecyclerView.mTotalY); 117a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 118a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 119a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte private static MotionEvent obtainScrollMotionEvent(int axis, int axisValue, int inputDevice) { 120a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte MotionEvent.PointerProperties[] pointerProperties = { new MotionEvent.PointerProperties() }; 121a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte MotionEvent.PointerCoords coords = new MotionEvent.PointerCoords(); 122a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte coords.setAxisValue(axis, axisValue); 123a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte MotionEvent.PointerCoords[] pointerCoords = { coords }; 124a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte float xPrecision = 1; 125a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte float yPrecision = 1; 126a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte int deviceId = 0; 127a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte int edgeFlags = 0; 128a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte int flags = 0; 129a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte return MotionEvent.obtain(0, System.currentTimeMillis(), MotionEvent.ACTION_SCROLL, 130a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 1, pointerProperties, pointerCoords, 0, 0, xPrecision, yPrecision, deviceId, 131a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte edgeFlags, inputDevice, flags); 132a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 133a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 134a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte private float getScaledVerticalScrollFactor() { 135a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte return ViewConfigurationCompat.getScaledVerticalScrollFactor( 136a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte ViewConfiguration.get(getContext()), getContext()); 137a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 138a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 139a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte private float getScaledHorizontalScrollFactor() { 140a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte return ViewConfigurationCompat.getScaledHorizontalScrollFactor( 141a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte ViewConfiguration.get(getContext()), getContext()); 142a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 143a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 144a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte static class MockLayoutManager extends RecyclerView.LayoutManager { 145a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 146a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte private final boolean mCanScrollHorizontally; 147a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 148a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte private final boolean mCanScrollVertically; 149a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 150a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte MockLayoutManager(boolean canScrollHorizontally, boolean canScrollVertically) { 151a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte mCanScrollHorizontally = canScrollHorizontally; 152a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte mCanScrollVertically = canScrollVertically; 153a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 154a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 155a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte @Override 156a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte public RecyclerView.LayoutParams generateDefaultLayoutParams() { 157a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte return new RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, 158a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte ViewGroup.LayoutParams.WRAP_CONTENT); 159a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 160a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 161a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte @Override 162a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, 163a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte RecyclerView.State state) { 164a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte return dx; 165a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 166a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 167a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte @Override 168a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, 169a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte RecyclerView.State state) { 170a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte return dy; 171a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 172a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 173a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte @Override 174a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte public boolean canScrollHorizontally() { 175a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte return mCanScrollHorizontally; 176a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 177a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 178a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte @Override 179a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte public boolean canScrollVertically() { 180a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte return mCanScrollVertically; 181a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 182a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 183a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 184a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte static class MockAdapter extends RecyclerView.Adapter { 185a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 186a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte private int mCount = 0; 187a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 188a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte MockAdapter(int count) { 189a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte this.mCount = count; 190a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 191a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 192a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte @Override 193a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 194a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte return new MockViewHolder(new TextView(parent.getContext())); 195a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 196a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 197a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte @Override 198a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { 199a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 200a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 201a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 202a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte @Override 203a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte public int getItemCount() { 204a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte return mCount; 205a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 206a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 207a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 208a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte static class MockViewHolder extends RecyclerView.ViewHolder { 209a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte MockViewHolder(View itemView) { 210a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte super(itemView); 211a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 212a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 213a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 214a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte private static class TestRecyclerView extends RecyclerView { 215a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte int mTotalX = 0; 216a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte int mTotalY = 0; 217a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 218a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte TestRecyclerView(Context context) { 219a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte super(context); 220a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 221a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte 222a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte boolean scrollByInternal(int x, int y, MotionEvent ev) { 223a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte mTotalX += x; 224a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte mTotalY += y; 225a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte return super.scrollByInternal(x, y, ev); 226a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 227a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte } 228a1f3f663034d903cb1a7036defa79bf462fca61cAaron Whyte} 229