Add rotary encoder support to scrolling containers

Change-Id: I1b7a2a60ac9864f2639af81fff810db601b2fbd4
This commit is contained in:
Ned Burns
2016-08-18 14:22:57 -04:00
parent 2cf3cc82e3
commit 20ad073581
3 changed files with 82 additions and 58 deletions

View File

@@ -617,6 +617,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
private int mTouchSlop; private int mTouchSlop;
private float mDensityScale; private float mDensityScale;
private float mScrollFactor;
private InputConnection mDefInputConnection; private InputConnection mDefInputConnection;
private InputConnectionWrapper mPublicInputConnection; private InputConnectionWrapper mPublicInputConnection;
@@ -874,6 +876,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final ViewConfiguration configuration = ViewConfiguration.get(mContext); final ViewConfiguration configuration = ViewConfiguration.get(mContext);
mTouchSlop = configuration.getScaledTouchSlop(); mTouchSlop = configuration.getScaledTouchSlop();
mScrollFactor = configuration.getScaledScrollFactor();
mMinimumVelocity = configuration.getScaledMinimumFlingVelocity(); mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
mOverscrollDistance = configuration.getScaledOverscrollDistance(); mOverscrollDistance = configuration.getScaledOverscrollDistance();
@@ -4206,21 +4209,26 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
@Override @Override
public boolean onGenericMotionEvent(MotionEvent event) { public boolean onGenericMotionEvent(MotionEvent event) {
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) { switch (event.getAction()) {
switch (event.getAction()) { case MotionEvent.ACTION_SCROLL:
case MotionEvent.ACTION_SCROLL: final float axisValue;
if (mTouchMode == TOUCH_MODE_REST) { if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
final float vscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL); axisValue = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
if (vscroll != 0) { } else if (event.isFromSource(InputDevice.SOURCE_ROTARY_ENCODER)) {
final int delta = (int) (vscroll * getVerticalScrollFactor()); axisValue = event.getAxisValue(MotionEvent.AXIS_SCROLL);
if (!trackMotionScroll(delta, delta)) { } else {
return true; axisValue = 0;
} }
}
}
break;
case MotionEvent.ACTION_BUTTON_PRESS: final int delta = Math.round(axisValue * mScrollFactor);
if (delta != 0) {
if (!trackMotionScroll(delta, delta)) {
return true;
}
}
break;
case MotionEvent.ACTION_BUTTON_PRESS:
if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
int actionButton = event.getActionButton(); int actionButton = event.getActionButton();
if ((actionButton == MotionEvent.BUTTON_STYLUS_PRIMARY if ((actionButton == MotionEvent.BUTTON_STYLUS_PRIMARY
|| actionButton == MotionEvent.BUTTON_SECONDARY) || actionButton == MotionEvent.BUTTON_SECONDARY)
@@ -4230,8 +4238,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
removeCallbacks(mPendingCheckForTap); removeCallbacks(mPendingCheckForTap);
} }
} }
break; }
} break;
} }
return super.onGenericMotionEvent(event); return super.onGenericMotionEvent(event);

View File

@@ -129,6 +129,8 @@ public class HorizontalScrollView extends FrameLayout {
private int mOverscrollDistance; private int mOverscrollDistance;
private int mOverflingDistance; private int mOverflingDistance;
private float mScrollFactor;
/** /**
* ID of the active pointer. This is used to retain consistency during * ID of the active pointer. This is used to retain consistency during
* drags/flings if multiple pointers are used. * drags/flings if multiple pointers are used.
@@ -222,6 +224,7 @@ public class HorizontalScrollView extends FrameLayout {
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
mOverscrollDistance = configuration.getScaledOverscrollDistance(); mOverscrollDistance = configuration.getScaledOverscrollDistance();
mOverflingDistance = configuration.getScaledOverflingDistance(); mOverflingDistance = configuration.getScaledOverflingDistance();
mScrollFactor = configuration.getScaledScrollFactor();
} }
@Override @Override
@@ -724,30 +727,35 @@ public class HorizontalScrollView extends FrameLayout {
@Override @Override
public boolean onGenericMotionEvent(MotionEvent event) { public boolean onGenericMotionEvent(MotionEvent event) {
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) { switch (event.getAction()) {
switch (event.getAction()) { case MotionEvent.ACTION_SCROLL: {
case MotionEvent.ACTION_SCROLL: { if (!mIsBeingDragged) {
if (!mIsBeingDragged) { final float axisValue;
final float hscroll; if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
if ((event.getMetaState() & KeyEvent.META_SHIFT_ON) != 0) { if ((event.getMetaState() & KeyEvent.META_SHIFT_ON) != 0) {
hscroll = -event.getAxisValue(MotionEvent.AXIS_VSCROLL); axisValue = -event.getAxisValue(MotionEvent.AXIS_VSCROLL);
} else { } else {
hscroll = event.getAxisValue(MotionEvent.AXIS_HSCROLL); axisValue = event.getAxisValue(MotionEvent.AXIS_HSCROLL);
} }
if (hscroll != 0) { } else if (event.isFromSource(InputDevice.SOURCE_ROTARY_ENCODER)) {
final int delta = (int) (hscroll * getHorizontalScrollFactor()); axisValue = event.getAxisValue(MotionEvent.AXIS_SCROLL);
final int range = getScrollRange(); } else {
int oldScrollX = mScrollX; axisValue = 0;
int newScrollX = oldScrollX + delta; }
if (newScrollX < 0) {
newScrollX = 0; final int delta = Math.round(axisValue * mScrollFactor);
} else if (newScrollX > range) { if (delta != 0) {
newScrollX = range; final int range = getScrollRange();
} int oldScrollX = mScrollX;
if (newScrollX != oldScrollX) { int newScrollX = oldScrollX + delta;
super.scrollTo(newScrollX, mScrollY); if (newScrollX < 0) {
return true; newScrollX = 0;
} } else if (newScrollX > range) {
newScrollX = range;
}
if (newScrollX != oldScrollX) {
super.scrollTo(newScrollX, mScrollY);
return true;
} }
} }
} }

View File

@@ -135,6 +135,8 @@ public class ScrollView extends FrameLayout {
private int mOverscrollDistance; private int mOverscrollDistance;
private int mOverflingDistance; private int mOverflingDistance;
private int mScrollFactor;
/** /**
* ID of the active pointer. This is used to retain consistency during * ID of the active pointer. This is used to retain consistency during
* drags/flings if multiple pointers are used. * drags/flings if multiple pointers are used.
@@ -248,6 +250,7 @@ public class ScrollView extends FrameLayout {
mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
mOverscrollDistance = configuration.getScaledOverscrollDistance(); mOverscrollDistance = configuration.getScaledOverscrollDistance();
mOverflingDistance = configuration.getScaledOverflingDistance(); mOverflingDistance = configuration.getScaledOverflingDistance();
mScrollFactor = configuration.getScaledScrollFactor();
} }
@Override @Override
@@ -782,30 +785,35 @@ public class ScrollView extends FrameLayout {
@Override @Override
public boolean onGenericMotionEvent(MotionEvent event) { public boolean onGenericMotionEvent(MotionEvent event) {
if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) { switch (event.getAction()) {
switch (event.getAction()) { case MotionEvent.ACTION_SCROLL:
case MotionEvent.ACTION_SCROLL: { final float axisValue;
if (!mIsBeingDragged) { if (event.isFromSource(InputDevice.SOURCE_CLASS_POINTER)) {
final float vscroll = event.getAxisValue(MotionEvent.AXIS_VSCROLL); axisValue = event.getAxisValue(MotionEvent.AXIS_VSCROLL);
if (vscroll != 0) { } else if (event.isFromSource(InputDevice.SOURCE_ROTARY_ENCODER)) {
final int delta = (int) (vscroll * getVerticalScrollFactor()); axisValue = event.getAxisValue(MotionEvent.AXIS_SCROLL);
final int range = getScrollRange(); } else {
int oldScrollY = mScrollY; axisValue = 0;
int newScrollY = oldScrollY - delta; }
if (newScrollY < 0) {
newScrollY = 0; final int delta = Math.round(axisValue * mScrollFactor);
} else if (newScrollY > range) { if (delta != 0) {
newScrollY = range; final int range = getScrollRange();
} int oldScrollY = mScrollY;
if (newScrollY != oldScrollY) { int newScrollY = oldScrollY - delta;
super.scrollTo(mScrollX, newScrollY); if (newScrollY < 0) {
return true; newScrollY = 0;
} } else if (newScrollY > range) {
} newScrollY = range;
}
if (newScrollY != oldScrollY) {
super.scrollTo(mScrollX, newScrollY);
return true;
} }
} }
} break;
} }
return super.onGenericMotionEvent(event); return super.onGenericMotionEvent(event);
} }