From 70b34a1e0525c8e13f431c2e6c9d37d1954de1b2 Mon Sep 17 00:00:00 2001 From: Gilles Debunne Date: Thu, 27 Oct 2011 11:10:14 -0700 Subject: [PATCH] Scroll performance improved in multiline TextEdit Measuring line widths, glyph by glyph slows down the scrolling process for long text (for some reason, width measure efficiency is affectedi by text length, maybe because the whole text has to be passed to JNI layers). This optimization avoids this computation in the case where there is no possible horizontal scroll. This is a cherry pick of 145957 into ICS-MR1 Change-Id: I2082e3d0eedace1a86122a03e4b21f90f3bc8522 --- core/java/android/text/method/Touch.java | 40 +++++++++++++++++------- core/java/android/widget/TextView.java | 11 +++++++ 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/core/java/android/text/method/Touch.java b/core/java/android/text/method/Touch.java index 106a80190b36b..3dfd44d90e4dd 100644 --- a/core/java/android/text/method/Touch.java +++ b/core/java/android/text/method/Touch.java @@ -35,22 +35,30 @@ public class Touch { * Y position. */ public static void scrollTo(TextView widget, Layout layout, int x, int y) { - final int verticalPadding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom(); - final int top = layout.getLineForVertical(y); - final int bottom = layout.getLineForVertical(y + widget.getHeight() - verticalPadding); + final int horizontalPadding = widget.getTotalPaddingLeft() + widget.getTotalPaddingRight(); + final int availableWidth = widget.getWidth() - horizontalPadding; - int left = Integer.MAX_VALUE; - int right = 0; + final int top = layout.getLineForVertical(y); Alignment a = layout.getParagraphAlignment(top); boolean ltr = layout.getParagraphDirection(top) > 0; - for (int i = top; i <= bottom; i++) { - left = (int) Math.min(left, layout.getLineLeft(i)); - right = (int) Math.max(right, layout.getLineRight(i)); + int left, right; + if (widget.getHorizontallyScrolling()) { + final int verticalPadding = widget.getTotalPaddingTop() + widget.getTotalPaddingBottom(); + final int bottom = layout.getLineForVertical(y + widget.getHeight() - verticalPadding); + + left = Integer.MAX_VALUE; + right = 0; + + for (int i = top; i <= bottom; i++) { + left = (int) Math.min(left, layout.getLineLeft(i)); + right = (int) Math.max(right, layout.getLineRight(i)); + } + } else { + left = 0; + right = availableWidth; } - final int hoizontalPadding = widget.getTotalPaddingLeft() + widget.getTotalPaddingRight(); - final int availableWidth = widget.getWidth() - hoizontalPadding; final int actualWidth = right - left; if (actualWidth < availableWidth) { @@ -166,16 +174,24 @@ public class Touch { return false; } + /** + * @param widget The text view. + * @param buffer The text buffer. + */ public static int getInitialScrollX(TextView widget, Spannable buffer) { DragState[] ds = buffer.getSpans(0, buffer.length(), DragState.class); return ds.length > 0 ? ds[0].mScrollX : -1; } - + + /** + * @param widget The text view. + * @param buffer The text buffer. + */ public static int getInitialScrollY(TextView widget, Spannable buffer) { DragState[] ds = buffer.getSpans(0, buffer.length(), DragState.class); return ds.length > 0 ? ds[0].mScrollY : -1; } - + private static class DragState implements NoCopySpan { public float mX; public float mY; diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 0f1b43bf5ab23..56d1b0743a95a 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -2580,6 +2580,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } + /** + * Returns whether the text is allowed to be wider than the View is. + * If false, the text will be wrapped to the width of the View. + * + * @attr ref android.R.styleable#TextView_scrollHorizontally + * @hide + */ + public boolean getHorizontallyScrolling() { + return mHorizontallyScrolling; + } + /** * Makes the TextView at least this many lines tall. *