From f4de21187d1ad1571008c6a572fbfc782e3af77d Mon Sep 17 00:00:00 2001 From: Joe Steele Date: Sat, 23 Mar 2013 12:50:44 -0400 Subject: [PATCH 1/9] Import NonLockingScrollView from AOSP Email client. As contained in current AOSP master: https://android.googlesource.com/platform/packages/apps/Email/+/b3c37a31ccffe137cc9b1c1068bb99d3d00a2ee4 --- .../email/view/NonLockingScrollView.java | 139 ++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 src/com/android/email/view/NonLockingScrollView.java diff --git a/src/com/android/email/view/NonLockingScrollView.java b/src/com/android/email/view/NonLockingScrollView.java new file mode 100644 index 000000000..832136c89 --- /dev/null +++ b/src/com/android/email/view/NonLockingScrollView.java @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package com.android.email.view; + +import android.content.Context; +import android.graphics.Rect; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.WebView; +import android.widget.ScrollView; + +import java.util.ArrayList; + +/** + * A {@link ScrollView} that will never lock scrolling in a particular direction. + * + * Usually ScrollView will capture all touch events once a drag has begun. In some cases, + * we want to delegate those touches to children as normal, even in the middle of a drag. This is + * useful when there are childviews like a WebView tha handles scrolling in the horizontal direction + * even while the ScrollView drags vertically. + * + * This is only tested to work for ScrollViews where the content scrolls in one direction. + */ +public class NonLockingScrollView extends ScrollView { + public NonLockingScrollView(Context context) { + super(context); + } + public NonLockingScrollView(Context context, AttributeSet attrs) { + super(context, attrs); + } + public NonLockingScrollView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + /** + * Whether or not the contents of this view is being dragged by one of the children in + * {@link #mChildrenNeedingAllTouches}. + */ + private boolean mInCustomDrag = false; + + /** + * The list of children who should always receive touch events, and not have them intercepted. + */ + private final ArrayList mChildrenNeedingAllTouches = new ArrayList(); + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + final int action = ev.getActionMasked(); + final boolean isUp = action == MotionEvent.ACTION_UP; + + if (isUp && mInCustomDrag) { + // An up event after a drag should be intercepted so that child views don't handle + // click events falsely after a drag. + mInCustomDrag = false; + onTouchEvent(ev); + return true; + } + + if (!mInCustomDrag && !isEventOverChild(ev, mChildrenNeedingAllTouches)) { + return super.onInterceptTouchEvent(ev); + } + + // Note the normal scrollview implementation is to intercept all touch events after it has + // detected a drag starting. We will handle this ourselves. + mInCustomDrag = super.onInterceptTouchEvent(ev); + if (mInCustomDrag) { + onTouchEvent(ev); + } + + // Don't intercept events - pass them on to children as normal. + return false; + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + excludeChildrenFromInterceptions(this); + } + + /** + * Traverses the view tree for {@link WebView}s so they can be excluded from touch + * interceptions and receive all events. + */ + private void excludeChildrenFromInterceptions(View node) { + // If additional types of children should be excluded (e.g. horizontal scrolling banners), + // this needs to be modified accordingly. + if (node instanceof WebView) { + mChildrenNeedingAllTouches.add(node); + } else if (node instanceof ViewGroup) { + ViewGroup viewGroup = (ViewGroup) node; + final int childCount = viewGroup.getChildCount(); + for (int i = 0; i < childCount; i++) { + final View child = viewGroup.getChildAt(i); + excludeChildrenFromInterceptions(child); + } + } + } + + private static final Rect sHitFrame = new Rect(); + private static boolean isEventOverChild(MotionEvent ev, ArrayList children) { + final int actionIndex = ev.getActionIndex(); + final float x = ev.getX(actionIndex); + final float y = ev.getY(actionIndex); + + for (View child : children) { + if (!canViewReceivePointerEvents(child)) { + continue; + } + child.getHitRect(sHitFrame); + + // child can receive the motion event. + if (sHitFrame.contains((int) x, (int) y)) { + return true; + } + } + return false; + } + + private static boolean canViewReceivePointerEvents(View child) { + return child.getVisibility() == VISIBLE || (child.getAnimation() != null); + } +} From 94a45853175e5ac4881d7af6d641c8c20fe67a90 Mon Sep 17 00:00:00 2001 From: Joe Steele Date: Sat, 23 Mar 2013 17:53:02 -0400 Subject: [PATCH 2/9] Switch to using NonLockingScrollView This implements the AOSP Email solution for incorporating a Webview inside a ScrollView, while still being able to scroll diagonally. This replaces the functionality of TitleBarWebView (which is now removed). --- res/layout/message.xml | 102 ++-- res/layout/message_view_header.xml | 447 +++++++++--------- src/android/webkit/WebViewClassic.java | 14 - src/com/fsck/k9/view/MessageHeader.java | 4 +- src/com/fsck/k9/view/MessageWebView.java | 5 +- .../k9}/view/NonLockingScrollView.java | 27 +- src/com/fsck/k9/view/SingleMessageView.java | 31 -- .../android/view/web/TitleBarWebView.java | 367 -------------- 8 files changed, 301 insertions(+), 696 deletions(-) delete mode 100644 src/android/webkit/WebViewClassic.java rename src/com/{android/email => fsck/k9}/view/NonLockingScrollView.java (84%) delete mode 100644 src/com/nobu_games/android/view/web/TitleBarWebView.java diff --git a/res/layout/message.xml b/res/layout/message.xml index be224eff9..41fe31257 100644 --- a/res/layout/message.xml +++ b/res/layout/message.xml @@ -7,64 +7,62 @@ android:layout_height="fill_parent" android:layout_weight="1"> - - - - - - - - - - - - - - + android:layout_height="wrap_content"> - - -