summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Viverette <alanv@google.com>2014-10-29 15:46:06 -0700
committerAlan Viverette <alanv@google.com>2014-10-30 00:18:22 +0000
commit154c2c24dc3b741bcc0d54c46d349478d24472ac (patch)
tree4fe24beadc55260a5f43f1bac78fe055cac7dc70
parente2502eb9ad5eafc54ae06f06a72493748616dbd5 (diff)
downloadframeworks_base-154c2c24dc3b741bcc0d54c46d349478d24472ac.zip
frameworks_base-154c2c24dc3b741bcc0d54c46d349478d24472ac.tar.gz
frameworks_base-154c2c24dc3b741bcc0d54c46d349478d24472ac.tar.bz2
Show scroll indicators in AlertDialog
BUG: 16353356 Change-Id: I0307283751ccb23b9d85b0c36cb78b01243e70dd
-rw-r--r--core/java/android/view/View.java36
-rw-r--r--core/java/com/android/internal/app/AlertController.java85
-rw-r--r--core/res/res/layout/alert_dialog_material.xml17
-rw-r--r--core/res/res/values/symbols.xml4
4 files changed, 126 insertions, 16 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e7b98ca..801d9ad 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -3229,6 +3229,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
private ArrayList<OnLayoutChangeListener> mOnLayoutChangeListeners;
+ protected OnScrollChangeListener mOnScrollChangeListener;
+
/**
* Listeners for attach events.
*/
@@ -4606,6 +4608,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * Register a callback to be invoked when the scroll position of this view
+ * changed.
+ *
+ * @param l The callback that will run.
+ * @hide Only used internally.
+ */
+ public void setOnScrollChangeListener(OnScrollChangeListener l) {
+ getListenerInfo().mOnScrollChangeListener = l;
+ }
+
+ /**
* Register a callback to be invoked when focus of this view changed.
*
* @param l The callback that will run.
@@ -9794,6 +9807,29 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
if (ai != null) {
ai.mViewScrollChanged = true;
}
+
+ if (mListenerInfo != null && mListenerInfo.mOnScrollChangeListener != null) {
+ mListenerInfo.mOnScrollChangeListener.onScrollChange(this, l, t, oldl, oldt);
+ }
+ }
+
+ /**
+ * Interface definition for a callback to be invoked when the scroll
+ * position of a view changes.
+ *
+ * @hide Only used internally.
+ */
+ public interface OnScrollChangeListener {
+ /**
+ * Called when the scroll position of a view changes.
+ *
+ * @param v The view whose scroll position has changed.
+ * @param scrollX Current horizontal scroll origin.
+ * @param scrollY Current vertical scroll origin.
+ * @param oldScrollX Previous horizontal scroll origin.
+ * @param oldScrollY Previous vertical scroll origin.
+ */
+ void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY);
}
/**
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index 0183e45..3630cc7 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -26,7 +26,6 @@ import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
-import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
@@ -38,9 +37,11 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
+import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
+import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
@@ -449,11 +450,11 @@ public class AlertController {
}
private void setupView() {
- final LinearLayout contentPanel = (LinearLayout) mWindow.findViewById(R.id.contentPanel);
+ final ViewGroup contentPanel = (ViewGroup) mWindow.findViewById(R.id.contentPanel);
setupContent(contentPanel);
final boolean hasButtons = setupButtons();
- final LinearLayout topPanel = (LinearLayout) mWindow.findViewById(R.id.topPanel);
+ final ViewGroup topPanel = (ViewGroup) mWindow.findViewById(R.id.topPanel);
final TypedArray a = mContext.obtainStyledAttributes(
null, R.styleable.AlertDialog, R.attr.alertDialogStyle, 0);
final boolean hasTitle = setupTitle(topPanel);
@@ -521,13 +522,13 @@ public class AlertController {
a.recycle();
}
- private boolean setupTitle(LinearLayout topPanel) {
+ private boolean setupTitle(ViewGroup topPanel) {
boolean hasTitle = true;
if (mCustomTitleView != null) {
// Add the custom title view directly to the topPanel layout
- LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
+ LayoutParams lp = new LayoutParams(
+ LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
topPanel.addView(mCustomTitleView, 0, lp);
@@ -571,7 +572,7 @@ public class AlertController {
return hasTitle;
}
- private void setupContent(LinearLayout contentPanel) {
+ private void setupContent(ViewGroup contentPanel) {
mScrollView = (ScrollView) mWindow.findViewById(R.id.scrollView);
mScrollView.setFocusable(false);
@@ -588,14 +589,76 @@ public class AlertController {
mScrollView.removeView(mMessageView);
if (mListView != null) {
- contentPanel.removeView(mWindow.findViewById(R.id.scrollView));
- contentPanel.addView(mListView,
- new LinearLayout.LayoutParams(MATCH_PARENT, MATCH_PARENT));
- contentPanel.setLayoutParams(new LinearLayout.LayoutParams(MATCH_PARENT, 0, 1.0f));
+ final int childIndex = mScrollView.indexOfChild(mScrollView);
+ contentPanel.removeViewAt(childIndex);
+ contentPanel.addView(mListView, childIndex,
+ new LayoutParams(MATCH_PARENT, MATCH_PARENT));
} else {
contentPanel.setVisibility(View.GONE);
}
}
+
+ // Set up scroll indicators (if present).
+ final View indicatorUp = mWindow.findViewById(R.id.scrollIndicatorUp);
+ final View indicatorDown = mWindow.findViewById(R.id.scrollIndicatorDown);
+ if (indicatorUp != null || indicatorDown != null) {
+ if (mMessage != null) {
+ // We're just showing the ScrollView, set up listener.
+ mScrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
+ @Override
+ public void onScrollChange(View v, int scrollX, int scrollY,
+ int oldScrollX, int oldScrollY) {
+ manageScrollIndicators(v, indicatorUp, indicatorDown);
+ }
+ });
+ // Set up the indicators following layout.
+ mScrollView.post(new Runnable() {
+ @Override
+ public void run() {
+ manageScrollIndicators(mScrollView, indicatorUp, indicatorDown);
+ }
+ });
+
+ } else if (mListView != null) {
+ // We're just showing the AbsListView, set up listener.
+ mListView.setOnScrollListener(new AbsListView.OnScrollListener() {
+ @Override
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+ // That's cool, I guess?
+ }
+
+ @Override
+ public void onScroll(AbsListView v, int firstVisibleItem,
+ int visibleItemCount, int totalItemCount) {
+ manageScrollIndicators(v, indicatorUp, indicatorDown);
+ }
+ });
+ // Set up the indicators following layout.
+ mListView.post(new Runnable() {
+ @Override
+ public void run() {
+ manageScrollIndicators(mListView, indicatorUp, indicatorDown);
+ }
+ });
+ } else {
+ // We don't have any content to scroll, remove the indicators.
+ if (indicatorUp != null) {
+ contentPanel.removeView(indicatorUp);
+ }
+ if (indicatorDown != null) {
+ contentPanel.removeView(indicatorDown);
+ }
+ }
+ }
+ }
+
+ private static void manageScrollIndicators(View v, View upIndicator, View downIndicator) {
+ if (upIndicator != null) {
+ upIndicator.setVisibility(v.canScrollVertically(-1) ? View.VISIBLE : View.INVISIBLE);
+ }
+ if (downIndicator != null) {
+ downIndicator.setVisibility(v.canScrollVertically(1) ? View.VISIBLE : View.INVISIBLE);
+ }
}
private boolean setupButtons() {
diff --git a/core/res/res/layout/alert_dialog_material.xml b/core/res/res/layout/alert_dialog_material.xml
index 89a47af..5627a2c 100644
--- a/core/res/res/layout/alert_dialog_material.xml
+++ b/core/res/res/layout/alert_dialog_material.xml
@@ -51,12 +51,17 @@
<!-- If the client uses a customTitle, it will be added here. -->
</LinearLayout>
- <LinearLayout android:id="@+id/contentPanel"
+ <FrameLayout android:id="@+id/contentPanel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
- android:orientation="vertical"
android:minHeight="48dp">
+ <View android:id="@+id/scrollIndicatorUp"
+ android:visibility="gone"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_gravity="top"
+ android:background="@drawable/list_divider_material"/>
<ScrollView android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -78,7 +83,13 @@
android:layout_height="@dimen/alert_dialog_padding_top_material" />
</LinearLayout>
</ScrollView>
- </LinearLayout>
+ <View android:id="@+id/scrollIndicatorDown"
+ android:visibility="gone"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_gravity="bottom"
+ android:background="@drawable/list_divider_material"/>
+ </FrameLayout>
<FrameLayout android:id="@+id/customPanel"
android:layout_width="match_parent"
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index d86413f..3cdc1ac 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2090,7 +2090,7 @@
<java-symbol type="bool" name="config_switch_phone_on_voice_reg_state_change" />
<java-symbol type="string" name="whichHomeApplicationNamed" />
<java-symbol type="bool" name="config_sms_force_7bit_encoding" />
-
- <!-- From MSIM Account -->
<java-symbol type="layout" name="simple_account_item" />
+ <java-symbol type="id" name="scrollIndicatorUp" />
+ <java-symbol type="id" name="scrollIndicatorDown" />
</resources>