summaryrefslogtreecommitdiffstats
path: root/core/java/android/view/accessibility
diff options
context:
space:
mode:
authorSvetoslav Ganov <svetoslavganov@google.com>2011-06-26 17:55:44 -0700
committerSvetoslav Ganov <svetoslavganov@google.com>2011-06-26 21:35:22 -0700
commita0156177cdc809795dd8bc5a19943dd2b6f82b66 (patch)
treed7d3404c94b3f4af1fb9e71595f2443aa2ab8925 /core/java/android/view/accessibility
parentc18e7e73158f794064fed5017c6c1c9a288673bd (diff)
downloadframeworks_base-a0156177cdc809795dd8bc5a19943dd2b6f82b66.zip
frameworks_base-a0156177cdc809795dd8bc5a19943dd2b6f82b66.tar.gz
frameworks_base-a0156177cdc809795dd8bc5a19943dd2b6f82b66.tar.bz2
Added scroll and text selection change accessibility events.
1. Added scrolling accessibility event to provicde feedback when a view is scrolled. Note: We need scroll events for ICS since even though we have touch exploration the user does not know when something is scrollable and not feedback is provided while scrolling. bug:4902097 2. Added a text selection change event to provide feedback for selection changes including cursor movement. Note: We need the text selection change events for ICS since even though the IME supports navigation in text fields the user receives no feedback for the current selection/ cursor position. bug:4586186 3. Added a scrollable property to both AccessibilityEvent and AccessibilityNodeInfo. The info has to describe the source in terms of all properties that make sense for accessibility purposes and the event has this property (kinda duplicated) since clients will aways want to know if the source is scrollable to provided clue to the user and we want to avoid pulling the info of the source for every accessibility event. Change-Id: I232d6825da78e6a12d52125f51320217e6fadb11
Diffstat (limited to 'core/java/android/view/accessibility')
-rw-r--r--core/java/android/view/accessibility/AccessibilityEvent.java227
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java24
-rw-r--r--core/java/android/view/accessibility/AccessibilityRecord.java110
3 files changed, 286 insertions, 75 deletions
diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java
index 30d6489..90452eb 100644
--- a/core/java/android/view/accessibility/AccessibilityEvent.java
+++ b/core/java/android/view/accessibility/AccessibilityEvent.java
@@ -56,76 +56,132 @@ import java.util.List;
* <b>View clicked</b> - represents the event of clicking on a {@link android.view.View}
* like {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc. <br>
* Type:{@link #TYPE_VIEW_CLICKED} <br>
- * Properties:
- * {@link #getClassName()},
- * {@link #getPackageName()},
- * {@link #getEventTime()},
- * {@link #getText()},
- * {@link #isChecked()},
- * {@link #isEnabled()},
- * {@link #isPassword()},
- * {@link #getItemCount()},
- * {@link #getCurrentItemIndex()}
+ * Properties:</br>
+ * <ul>
+ * <li>{@link #getSource()} - The source info (for registered clients).</li> *
+ * <li>{@link #getClassName()} - The class name of the source.</li>
+ * <li>{@link #getPackageName()} - The package name of the source.</li>
+ * <li>{@link #getEventTime()} - The event time.</li>
+ * <li>{@link #getText()} - The text of the source.</li>
+ * <li>{@link #isEnabled()} - Whether the source is enabled.</li>
+ * <li>{@link #isPassword()} - Whether the source is password.</li>
+ * <li>{@link #isChecked()} - Whether the source is checked.</li>
+ * </ul>
* <p>
* <b>View long clicked</b> - represents the event of long clicking on a {@link android.view.View}
* like {@link android.widget.Button}, {@link android.widget.CompoundButton}, etc. <br>
* Type:{@link #TYPE_VIEW_LONG_CLICKED} <br>
- * Properties:
- * {@link #getClassName()},
- * {@link #getPackageName()},
- * {@link #getEventTime()},
- * {@link #getText()},
- * {@link #isChecked()},
- * {@link #isEnabled()},
- * {@link #isPassword()},
- * {@link #getItemCount()},
- * {@link #getCurrentItemIndex()}
+ * Properties:</br>
+ * <ul>
+ * <li>{@link #getSource()} - The source info (for registered clients).</li> *
+ * <li>{@link #getClassName()} - The class name of the source.</li>
+ * <li>{@link #getPackageName()} - The package name of the source.</li>
+ * <li>{@link #getEventTime()} - The event time.</li>
+ * <li>{@link #getText()} - The text of the source.</li>
+ * <li>{@link #isEnabled()} - Whether the source is enabled.</li>
+ * <li>{@link #isPassword()} - Whether the source is password.</li>
+ * <li>{@link #isChecked()} - Whether the source is checked.</li>
+ * </ul>
* <p>
* <b>View selected</b> - represents the event of selecting an item usually in
* the context of an {@link android.widget.AdapterView}. <br>
* Type: {@link #TYPE_VIEW_SELECTED} <br>
- * Properties:
- * {@link #getClassName()},
- * {@link #getPackageName()},
- * {@link #getEventTime()},
- * {@link #getText()},
- * {@link #isChecked()},
- * {@link #isEnabled()},
- * {@link #isPassword()},
- * {@link #getItemCount()},
- * {@link #getCurrentItemIndex()}
+ * Properties:</br>
+ * <ul>
+ * <li>{@link #getSource()} - The source info (for registered clients).</li> *
+ * <li>{@link #getClassName()} - The class name of the source.</li>
+ * <li>{@link #getPackageName()} - The package name of the source.</li>
+ * <li>{@link #getEventTime()} - The event time.</li>
+ * <li>{@link #getText()} - The text of the source.</li>
+ * <li>{@link #isEnabled()} - Whether the source is enabled.</li>
+ * <li>{@link #isPassword()} - Whether the source is password.</li>
+ * <li>{@link #isChecked()} - Whether the source is checked.</li>
+ * <li>{@link #getItemCount()} -The number of selectable items of the source.</li>
+ * <li>{@link #getCurrentItemIndex()} - The currently selected item index.</li>
+ * </ul>
+ * <p>
* <p>
* <b>View focused</b> - represents the event of focusing a
* {@link android.view.View}. <br>
* Type: {@link #TYPE_VIEW_FOCUSED} <br>
- * Properties:
- * {@link #getClassName()},
- * {@link #getPackageName()},
- * {@link #getEventTime()},
- * {@link #getText()},
- * {@link #isChecked()},
- * {@link #isEnabled()},
- * {@link #isPassword()},
- * {@link #getItemCount()},
- * {@link #getCurrentItemIndex()}
+ * Properties:</br>
+ * <ul>
+ * <li>{@link #getSource()} - The source info (for registered clients).</li> *
+ * <li>{@link #getClassName()} - The class name of the source.</li>
+ * <li>{@link #getPackageName()} - The package name of the source.</li>
+ * <li>{@link #getEventTime()} - The event time.</li>
+ * <li>{@link #getText()} - The text of the source.</li>
+ * <li>{@link #isEnabled()} - Whether the source is enabled.</li>
+ * <li>{@link #isPassword()} - Whether the source is password.</li>
+ * <li>{@link #isChecked()} - Whether the source is checked.</li>
+ * <li>{@link #getItemCount()} -The number of focusable items on the screen.</li>
+ * <li>{@link #getCurrentItemIndex()} - The currently focused item index.</li>
+ * </ul>
* <p>
* <b>View text changed</b> - represents the event of changing the text of an
* {@link android.widget.EditText}. <br>
* Type: {@link #TYPE_VIEW_TEXT_CHANGED} <br>
- * Properties:
- * {@link #getClassName()},
- * {@link #getPackageName()},
- * {@link #getEventTime()},
- * {@link #getText()},
- * {@link #isChecked()},
- * {@link #isEnabled()},
- * {@link #isPassword()},
- * {@link #getItemCount()},
- * {@link #getCurrentItemIndex()},
- * {@link #getFromIndex()},
- * {@link #getAddedCount()},
- * {@link #getRemovedCount()},
- * {@link #getBeforeText()}
+ * Properties:</br>
+ * <ul>
+ * <li>{@link #getSource()} - The source info (for registered clients).</li> *
+ * <li>{@link #getClassName()} - The class name of the source.</li>
+ * <li>{@link #getPackageName()} - The package name of the source.</li>
+ * <li>{@link #getEventTime()} - The event time.</li>
+ * <li>{@link #getText()} - The text of the source.</li>
+ * <li>{@link #isEnabled()} - Whether the source is enabled.</li>
+ * <li>{@link #isPassword()} - Whether the source is password.</li>
+ * <li>{@link #isChecked()} - Whether the source is checked.</li>
+ * <li>{@link #getFromIndex()} - The text change start index.</li>
+ * <li>{@link #getAddedCount()} - The number of added characters.</li>
+ * <li>{@link #getRemovedCount()} - The number of removed characters.</li>
+ * <li>{@link #getBeforeText()} - The text of the source before the change.</li>
+ * </ul>
+ * <p>
+ * <b>View text selection changed</b> - represents the event of changing the text
+ * selection of an {@link android.widget.EditText}.<br>
+ * Type: {@link #TYPE_VIEW_TEXT_SELECTION_CHANGED} <br>
+ * Properties:</br>
+ * <ul>
+ * <li>{@link #getSource()} - The source info (for registered clients).</li> *
+ * <li>{@link #getClassName()} - The class name of the source.</li>
+ * <li>{@link #getPackageName()} - The package name of the source.</li>
+ * <li>{@link #getEventTime()} - The event time.</li>
+ * <li>{@link #getText()} - The text of the source.</li>
+ * <li>{@link #isEnabled()} - Whether the source is enabled.</li>
+ * <li>{@link #isPassword()} - Whether the source is password.</li>
+ * <li>{@link #getFromIndex()} - The selection start index.</li>
+ * <li>{@link #getToIndex()} - The selection end index.</li>
+ * <li>{@link #getItemCount()} - The length of the source text.</li>
+ * <ul>
+ * <p>
+ * <b>View scrolled</b> - represents the event of scrolling a view. If
+ * the source is a descendant of {@link android.widget.AdapterView} the
+ * scroll is reported in terms of visible items - the first visible item,
+ * the last visible item, and the total items - because the the source
+ * is unaware if its pixel size since its adapter is responsible for
+ * creating views. In all other cases the scroll is reported as the current
+ * scroll on the X and Y axis respectively plus the height of the source in
+ * pixels.<br>
+ * Type: {@link #TYPE_VIEW_SCROLLED} <br>
+ * Properties:</br>
+ * <ul>
+ * <li>{@link #getSource()} - The source info (for registered clients).</li> *
+ * <li>{@link #getClassName()} - The class name of the source.</li>
+ * <li>{@link #getPackageName()} - The package name of the source.</li>
+ * <li>{@link #getEventTime()} - The event time.</li>
+ * <li>{@link #getText()} - The text of the source.</li>
+ * <li>{@link #isEnabled()} - Whether the source is enabled.</li>
+ * <li>{@link #getScrollX())} - The horizontal offset of the source
+ * (without descendants of AdapterView)).</li>
+ * <li>{@link #getScrollY())} - The vertical offset of the source
+ * (without descendants of AdapterView)).</li>
+ * <li>{@link #getFromIndex()} - The index of the first visible item of the source
+ * (for descendants of AdapterView).</li>
+ * <li>{@link #getToIndex()} - The index of the last visible item of the source
+ * (for descendants of AdapterView).</li>
+ * <li>{@link #getItemCount()} - The total items of the source (for descendants of AdapterView)
+ * or the height of the source in pixels (all other cases).</li>
+ * <ul>
* <p>
* <b>TRANSITION TYPES</b> <br>
* <p>
@@ -133,33 +189,40 @@ import java.util.List;
* {@link android.widget.PopupWindow}, {@link android.view.Menu},
* {@link android.app.Dialog}, etc. <br>
* Type: {@link #TYPE_WINDOW_STATE_CHANGED} <br>
- * Properties:
- * {@link #getClassName()},
- * {@link #getPackageName()},
- * {@link #getEventTime()},
- * {@link #getText()}
+ * Properties:</br>
+ * <ul>
+ * <li>{@link #getSource()} - The source info (for registered clients).</li> *
+ * <li>{@link #getClassName()} - The class name of the source.</li>
+ * <li>{@link #getPackageName()} - The package name of the source.</li>
+ * <li>{@link #getEventTime()} - The event time.</li>
+ * <li>{@link #getText()} - The text of the source.</li>
+ * </ul>
* <p>
* <b>Window content changed</b> - represents the event of change in the
* content of a window. This change can be adding/removing view, changing
* a view size, etc.<br>
* Type: {@link #TYPE_WINDOW_CONTENT_CHANGED} <br>
- * Properties:
- * {@link #getClassName()},
- * {@link #getPackageName()},
- * {@link #getEventTime()},
- * {@link #getText()}
+ * Properties:</br>
+ * <ul>
+ * <li>{@link #getSource()} - The source info (for registered clients).</li> *
+ * <li>{@link #getClassName()} - The class name of the source.</li>
+ * <li>{@link #getPackageName()} - The package name of the source.</li>
+ * <li>{@link #getEventTime()} - The event time.</li>
+ * <ul>
* <p>
* <b>NOTIFICATION TYPES</b> <br>
* <p>
* <b>Notification state changed</b> - represents the event showing/hiding
* {@link android.app.Notification}.
* Type: {@link #TYPE_NOTIFICATION_STATE_CHANGED} <br>
- * Properties:
- * {@link #getClassName()},
- * {@link #getPackageName()},
- * {@link #getEventTime()},
- * {@link #getText()}
- * {@link #getParcelableData()}
+ * Properties:</br>
+ * <ul>
+ * <li>{@link #getClassName()} - The class name of the source.</li>
+ * <li>{@link #getPackageName()} - The package name of the source.</li>
+ * <li>{@link #getEventTime()} - The event time.</li>
+ * <li>{@link #getText()} - The text of the source.</li>
+ * <li>{@link #getParcelableData()} - The posted {@link android.app.Notification}.</li>
+ * </ul>
* <p>
* <b>Security note</b>
* <p>
@@ -258,6 +321,16 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
public static final int TYPE_WINDOW_CONTENT_CHANGED = 0x00000800;
/**
+ * Represents the event of scrolling a view.
+ */
+ public static final int TYPE_VIEW_SCROLLED = 0x00001000;
+
+ /**
+ * Represents the event of changing the selection in an {@link android.widget.EditText}.
+ */
+ public static final int TYPE_VIEW_TEXT_SELECTION_CHANGED = 0x00002000;
+
+ /**
* Mask for {@link AccessibilityEvent} all types.
*
* @see #TYPE_VIEW_CLICKED
@@ -564,6 +637,9 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
record.mCurrentItemIndex = parcel.readInt();
record.mItemCount = parcel.readInt();
record.mFromIndex = parcel.readInt();
+ record.mToIndex = parcel.readInt();
+ record.mScrollX = parcel.readInt();
+ record.mScrollY = parcel.readInt();
record.mAddedCount = parcel.readInt();
record.mRemovedCount = parcel.readInt();
record.mClassName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
@@ -613,6 +689,9 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
parcel.writeInt(record.mCurrentItemIndex);
parcel.writeInt(record.mItemCount);
parcel.writeInt(record.mFromIndex);
+ parcel.writeInt(record.mToIndex);
+ parcel.writeInt(record.mScrollX);
+ parcel.writeInt(record.mScrollY);
parcel.writeInt(record.mAddedCount);
parcel.writeInt(record.mRemovedCount);
TextUtils.writeToParcel(record.mClassName, parcel, flags);
@@ -657,8 +736,12 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
builder.append("; IsPassword: " + record.isPassword());
builder.append("; IsChecked: " + record.isChecked());
builder.append("; IsFullScreen: " + record.isFullScreen());
+ builder.append("; Scrollable: " + record.isScrollable());
builder.append("; BeforeText: " + record.mBeforeText);
builder.append("; FromIndex: " + record.mFromIndex);
+ builder.append("; ToIndex: " + record.mToIndex);
+ builder.append("; ScrollX: " + record.mScrollX);
+ builder.append("; ScrollY: " + record.mScrollY);
builder.append("; AddedCount: " + record.mAddedCount);
builder.append("; RemovedCount: " + record.mRemovedCount);
builder.append("; ParcelableData: " + record.mParcelableData);
@@ -704,6 +787,10 @@ public final class AccessibilityEvent extends AccessibilityRecord implements Par
return "TYPE_TOUCH_EXPLORATION_GESTURE_END";
case TYPE_WINDOW_CONTENT_CHANGED:
return "TYPE_WINDOW_CONTENT_CHANGED";
+ case TYPE_VIEW_TEXT_SELECTION_CHANGED:
+ return "TYPE_VIEW_TEXT_SELECTION_CHANGED";
+ case TYPE_VIEW_SCROLLED:
+ return "TYPE_VIEW_SCROLLED";
default:
return null;
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 555667b..dbbe7be 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -83,6 +83,8 @@ public class AccessibilityNodeInfo implements Parcelable {
private static final int PROPERTY_PASSWORD = 0x00000100;
+ private static final int PROPERTY_SCROLLABLE = 0x00000200;
+
// Readable representations - lazily initialized.
private static SparseArray<String> sActionSymbolicNames;
@@ -570,6 +572,27 @@ public class AccessibilityNodeInfo implements Parcelable {
}
/**
+ * Gets if the node is scrollable.
+ *
+ * @return True if the node is scrollable, false otherwise.
+ */
+ public boolean isScrollable() {
+ return getBooleanProperty(PROPERTY_SCROLLABLE);
+ }
+
+ /**
+ * Sets if the node is scrollable.
+ *
+ * @param scrollable True if the node is scrollable, false otherwise.
+ *
+ * @throws IllegalStateException If called from an AccessibilityService.
+ */
+ public void setScrollable(boolean scrollable) {
+ enforceNotSealed();
+ setBooleanProperty(PROPERTY_SCROLLABLE, scrollable);
+ }
+
+ /**
* Gets the package this node comes from.
*
* @return The package name.
@@ -1017,6 +1040,7 @@ public class AccessibilityNodeInfo implements Parcelable {
builder.append("; longClickable: ").append(isLongClickable());
builder.append("; enabled: ").append(isEnabled());
builder.append("; password: ").append(isPassword());
+ builder.append("; scrollable: " + isScrollable());
builder.append("; [");
diff --git a/core/java/android/view/accessibility/AccessibilityRecord.java b/core/java/android/view/accessibility/AccessibilityRecord.java
index 9c495e2..836899f 100644
--- a/core/java/android/view/accessibility/AccessibilityRecord.java
+++ b/core/java/android/view/accessibility/AccessibilityRecord.java
@@ -40,6 +40,7 @@ public class AccessibilityRecord {
private static final int PROPERTY_ENABLED = 0x00000002;
private static final int PROPERTY_PASSWORD = 0x00000004;
private static final int PROPERTY_FULL_SCREEN = 0x00000080;
+ private static final int PROPERTY_SCROLLABLE = 0x00000100;
// Housekeeping
private static final int MAX_POOL_SIZE = 10;
@@ -54,6 +55,10 @@ public class AccessibilityRecord {
int mCurrentItemIndex;
int mItemCount;
int mFromIndex;
+ int mToIndex;
+ int mScrollX;
+ int mScrollY;
+
int mAddedCount;
int mRemovedCount;
int mSourceViewId = View.NO_ID;
@@ -71,7 +76,6 @@ public class AccessibilityRecord {
* Hide constructor.
*/
AccessibilityRecord() {
-
}
/**
@@ -85,6 +89,9 @@ public class AccessibilityRecord {
mCurrentItemIndex = record.mCurrentItemIndex;
mItemCount = record.mItemCount;
mFromIndex = record.mFromIndex;
+ mToIndex = record.mToIndex;
+ mScrollX = record.mScrollX;
+ mScrollY = record.mScrollY;
mAddedCount = record.mAddedCount;
mRemovedCount = record.mRemovedCount;
mClassName = record.mClassName;
@@ -246,6 +253,27 @@ public class AccessibilityRecord {
}
/**
+ * Gets if the source is scrollable.
+ *
+ * @return True if the source is scrollable, false otherwise.
+ */
+ public boolean isScrollable() {
+ return getBooleanProperty(PROPERTY_SCROLLABLE);
+ }
+
+ /**
+ * Sets if the source is scrollable.
+ *
+ * @param scrollable True if the source is scrollable, false otherwise.
+ *
+ * @throws IllegalStateException If called from an AccessibilityService.
+ */
+ public void setScrollable(boolean scrollable) {
+ enforceNotSealed();
+ setBooleanProperty(PROPERTY_SCROLLABLE, scrollable);
+ }
+
+ /**
* Gets the number of items that can be visited.
*
* @return The number of items.
@@ -288,18 +316,24 @@ public class AccessibilityRecord {
}
/**
- * Gets the index of the first character of the changed sequence.
+ * Gets the index of the first character of the changed sequence,
+ * or the beginning of a text selection or the index of the first
+ * visible item when scrolling.
*
- * @return The index of the first character.
+ * @return The index of the first character or selection
+ * start or the first visible item.
*/
public int getFromIndex() {
return mFromIndex;
}
/**
- * Sets the index of the first character of the changed sequence.
+ * Sets the index of the first character of the changed sequence
+ * or the beginning of a text selection or the index of the first
+ * visible item when scrolling.
*
- * @param fromIndex The index of the first character.
+ * @param fromIndex The index of the first character or selection
+ * start or the first visible item.
*
* @throws IllegalStateException If called from an AccessibilityService.
*/
@@ -309,6 +343,65 @@ public class AccessibilityRecord {
}
/**
+ * Gets the index of text selection end or the index of the last
+ * visible item when scrolling.
+ *
+ * @return The index of selection end or last item index.
+ */
+ public int getToIndex() {
+ return mToIndex;
+ }
+
+ /**
+ * Sets the index of text selection end or the index of the last
+ * visible item when scrolling.
+ *
+ * @param toIndex The index of selection end or last item index.
+ */
+ public void setToIndex(int toIndex) {
+ enforceNotSealed();
+ mToIndex = toIndex;
+ }
+
+ /**
+ * Gets the scroll position of the source along the X axis.
+ *
+ * @return The scroll along the X axis.
+ */
+ public int getScrollX() {
+ return mScrollX;
+ }
+
+ /**
+ * Sets the scroll position of the source along the X axis.
+ *
+ * @param scrollX The scroll along the X axis.
+ */
+ public void setScrollX(int scrollX) {
+ enforceNotSealed();
+ mScrollX = scrollX;
+ }
+
+ /**
+ * Gets the scroll position of the source along the Y axis.
+ *
+ * @return The scroll along the Y axis.
+ */
+ public int getScrollY() {
+ return mScrollY;
+ }
+
+ /**
+ * Sets the scroll position of the source along the Y axis.
+ *
+ * @param scrollX The scroll along the Y axis.
+ */
+ public void setScrollY(int scrollY) {
+ enforceNotSealed();
+ mScrollY = scrollY;
+ }
+
+ /**
* Gets the number of added characters.
*
* @return The number of added characters.
@@ -576,6 +669,9 @@ public class AccessibilityRecord {
mCurrentItemIndex = INVALID_POSITION;
mItemCount = 0;
mFromIndex = 0;
+ mToIndex = 0;
+ mScrollX = 0;
+ mScrollY = 0;
mAddedCount = 0;
mRemovedCount = 0;
mClassName = null;
@@ -599,8 +695,12 @@ public class AccessibilityRecord {
builder.append("; IsPassword: " + getBooleanProperty(PROPERTY_PASSWORD));
builder.append("; IsChecked: " + getBooleanProperty(PROPERTY_CHECKED));
builder.append("; IsFullScreen: " + getBooleanProperty(PROPERTY_FULL_SCREEN));
+ builder.append("; Scrollable: " + getBooleanProperty(PROPERTY_SCROLLABLE));
builder.append("; BeforeText: " + mBeforeText);
builder.append("; FromIndex: " + mFromIndex);
+ builder.append("; ToIndex: " + mToIndex);
+ builder.append("; ScrollX: " + mScrollX);
+ builder.append("; ScrollY: " + mScrollY);
builder.append("; AddedCount: " + mAddedCount);
builder.append("; RemovedCount: " + mRemovedCount);
builder.append("; ParcelableData: " + mParcelableData);