From a3b4eefe09a3d2c358a5e7f39f5b987acc0a667a Mon Sep 17 00:00:00 2001 From: Adrian Ulrich Date: Mon, 4 Apr 2016 20:52:06 +0200 Subject: [PATCH] Introduce FastScrollGuardListView This is a hack to work around androids stupid 48dip fast-scroll area: The framework will hijack any scroll events which happen near (=48 dp) the fast scroll bar. We do not want this as it clashes with our expand buttons. This class intercepts events in the problematic area and rewrites them to a fake event to pretend that the touch did not happen in the fastscroll area --- res/layout/listview.xml | 2 +- .../vanilla/FastScrollGuardedListView.java | 79 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/ch/blinkenlights/android/vanilla/FastScrollGuardedListView.java diff --git a/res/layout/listview.xml b/res/layout/listview.xml index f29f4d3b..84bf7e94 100644 --- a/res/layout/listview.xml +++ b/res/layout/listview.xml @@ -20,7 +20,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --> - + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package ch.blinkenlights.android.vanilla; + +import android.content.Context; +import android.content.res.Resources; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.widget.ListView; + + +public class FastScrollGuardedListView extends ListView { + + /** + * Start edgeProtection at width-start + */ + private static final int PROTECT_START_DP = 50; // AOSP has this set to 48dip in 5.x + /** + * End protection at width-end + */ + private static final int PROTECT_END_DP = 12; + /** + * The calculated start position in pixel + */ + private float mEdgeProtectStartPx = 0; + /** + * The calculated end position in pixel + */ + private float mEdgeProtectEndPx = 0; + + + public FastScrollGuardedListView(Context context) { + super(context); + } + public FastScrollGuardedListView(Context context, AttributeSet attrs) { + super(context, attrs); + } + public FastScrollGuardedListView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + public FastScrollGuardedListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + } + + /** + * Intercepted touch event from ListView + * We will use this callback to send fake X-coord events if + * the actual event happened in the protected area (eg: the hardcoded fastscroll area) + */ + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + if (mEdgeProtectStartPx == 0) + mEdgeProtectStartPx = getWidth() - PROTECT_START_DP * Resources.getSystem().getDisplayMetrics().density; + if (mEdgeProtectEndPx == 0) + mEdgeProtectEndPx = getWidth() - PROTECT_END_DP * Resources.getSystem().getDisplayMetrics().density; + + if (ev.getX() > mEdgeProtectStartPx && ev.getX() < mEdgeProtectEndPx) { + // Cursor is in protected area: simulate an event with a faked x coordinate + ev = MotionEvent.obtain(ev.getDownTime(), ev.getEventTime(), ev.getAction(), mEdgeProtectStartPx, ev.getY(), ev.getMetaState()); + } + return super.onInterceptTouchEvent(ev); + } + +}