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

View File

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