Created
November 28, 2015 02:35
-
-
Save fyhack/f389b70d6029c0cc6a31 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
著作权归作者所有。 | |
商业转载请联系作者获得授权,非商业转载请注明出处。 | |
作者:Mariotaku | |
链接:https://www.zhihu.com/question/37929529/answer/74172064 | |
来源:知乎 | |
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