Last active
August 29, 2015 14:19
-
-
Save mariotaku/9a44afabea5789aef515 to your computer and use it in GitHub Desktop.
An evil snippet to guess mouse scrolling direction for Android
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.annotation.SuppressLint; | |
import android.content.Context; | |
import android.support.v4.view.MotionEventCompat; | |
import android.view.InputDevice; | |
import android.view.MotionEvent; | |
import android.view.View; | |
import android.widget.HorizontalScrollView; | |
import android.widget.ScrollView; | |
/** | |
* Warning! Evil code ahead! | |
* Guess mouse scroll direction by calculating scroll offset of system ScrollView | |
*/ | |
public class MouseScrollDirectionDecider { | |
private final float factor; | |
private final View verticalView, horizontalView; | |
private int horizontalDirection = 0, verticalDirection = 0; | |
private float horizontalScroll, verticalScroll; | |
public MouseScrollDirectionDecider(Context context, float factor) { | |
this.factor = factor; | |
this.verticalView = new InternalScrollView(context, this); | |
this.horizontalView = new InternalHorizontalScrollView(context, this); | |
} | |
public float getHorizontalDirection() { | |
return horizontalDirection; | |
} | |
public boolean isHorizontalAvailable() { | |
return horizontalDirection != 0; | |
} | |
public boolean isVerticalAvailable() { | |
return verticalDirection != 0; | |
} | |
private void setHorizontalDirection(int direction) { | |
horizontalDirection = direction; | |
} | |
public float getVerticalDirection() { | |
return verticalDirection; | |
} | |
private void setVerticalDirection(int direction) { | |
verticalDirection = direction; | |
} | |
public boolean guessDirection(MotionEvent event) { | |
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) == 0) { | |
return false; | |
} | |
if (event.getAction() != MotionEventCompat.ACTION_SCROLL) return false; | |
verticalScroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL); | |
horizontalScroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL); | |
verticalView.onGenericMotionEvent(event); | |
horizontalView.onGenericMotionEvent(event); | |
return verticalScroll != 0 || horizontalScroll != 0; | |
} | |
@SuppressLint("ViewConstructor") | |
private static class InternalScrollView extends ScrollView { | |
private final int factor; | |
private final MouseScrollDirectionDecider decider; | |
public InternalScrollView(Context context, MouseScrollDirectionDecider decider) { | |
super(context); | |
this.decider = decider; | |
final View view = new View(context); | |
addView(view); | |
this.factor = Math.round(decider.factor); | |
view.setTop(-factor); | |
view.setBottom(factor); | |
} | |
@Override | |
protected void onScrollChanged(int l, int t, int oldl, int oldt) { | |
super.scrollTo(0, factor); | |
if (t != factor) { | |
float value = (t - oldt) * decider.verticalScroll; | |
if (value > 0) { | |
decider.setVerticalDirection(1); | |
} else if (value < 0) { | |
decider.setVerticalDirection(-1); | |
} else { | |
decider.setVerticalDirection(0); | |
} | |
} | |
} | |
} | |
@SuppressLint("ViewConstructor") | |
private class InternalHorizontalScrollView extends HorizontalScrollView { | |
private final int factor; | |
private final MouseScrollDirectionDecider decider; | |
public InternalHorizontalScrollView(Context context, MouseScrollDirectionDecider decider) { | |
super(context); | |
this.decider = decider; | |
final View view = new View(context); | |
addView(view); | |
this.factor = Math.round(decider.factor); | |
view.setLeft(-factor); | |
view.setRight(factor); | |
} | |
@Override | |
protected void onScrollChanged(int l, int t, int oldl, int oldt) { | |
super.scrollTo(factor, 0); | |
if (t != factor) { | |
float value = (t - oldt) * decider.horizontalScroll; | |
if (value > 0) { | |
decider.setHorizontalDirection(1); | |
} else if (value < 0) { | |
decider.setHorizontalDirection(-1); | |
} else { | |
decider.setHorizontalDirection(0); | |
} | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment