summaryrefslogtreecommitdiff
path: root/library/main/src
diff options
context:
space:
mode:
Diffstat (limited to 'library/main/src')
-rw-r--r--library/main/src/com/android/setupwizardlib/GlifLayout.java10
-rw-r--r--library/main/src/com/android/setupwizardlib/GlifListLayout.java6
-rw-r--r--library/main/src/com/android/setupwizardlib/SetupWizardLayout.java27
-rw-r--r--library/main/src/com/android/setupwizardlib/SetupWizardListLayout.java21
-rw-r--r--library/main/src/com/android/setupwizardlib/template/ListViewScrollHandlingDelegate.java87
-rw-r--r--library/main/src/com/android/setupwizardlib/template/RequireScrollMixin.java260
-rw-r--r--library/main/src/com/android/setupwizardlib/template/ScrollViewScrollHandlingDelegate.java80
-rw-r--r--library/main/src/com/android/setupwizardlib/util/AbstractRequireScrollHelper.java78
-rw-r--r--library/main/src/com/android/setupwizardlib/util/ListViewRequireScrollHelper.java81
-rw-r--r--library/main/src/com/android/setupwizardlib/util/RequireScrollHelper.java64
-rw-r--r--library/main/src/com/android/setupwizardlib/view/NavigationBar.java2
11 files changed, 465 insertions, 251 deletions
diff --git a/library/main/src/com/android/setupwizardlib/GlifLayout.java b/library/main/src/com/android/setupwizardlib/GlifLayout.java
index 667d699..f4d52a5 100644
--- a/library/main/src/com/android/setupwizardlib/GlifLayout.java
+++ b/library/main/src/com/android/setupwizardlib/GlifLayout.java
@@ -41,6 +41,8 @@ import com.android.setupwizardlib.template.ColoredHeaderMixin;
import com.android.setupwizardlib.template.HeaderMixin;
import com.android.setupwizardlib.template.IconMixin;
import com.android.setupwizardlib.template.ProgressBarMixin;
+import com.android.setupwizardlib.template.RequireScrollMixin;
+import com.android.setupwizardlib.template.ScrollViewScrollHandlingDelegate;
import com.android.setupwizardlib.view.StatusBarBackgroundLayout;
/**
@@ -106,6 +108,14 @@ public class GlifLayout extends TemplateLayout {
registerMixin(IconMixin.class, new IconMixin(this, attrs, defStyleAttr));
registerMixin(ProgressBarMixin.class, new ProgressBarMixin(this));
registerMixin(ButtonFooterMixin.class, new ButtonFooterMixin(this));
+ final RequireScrollMixin requireScrollMixin = new RequireScrollMixin(this);
+ registerMixin(RequireScrollMixin.class, requireScrollMixin);
+
+ final ScrollView scrollView = getScrollView();
+ if (scrollView != null) {
+ requireScrollMixin.setScrollHandlingDelegate(
+ new ScrollViewScrollHandlingDelegate(requireScrollMixin, scrollView));
+ }
TypedArray a = getContext().obtainStyledAttributes(attrs,
R.styleable.SuwGlifLayout, defStyleAttr, 0);
diff --git a/library/main/src/com/android/setupwizardlib/GlifListLayout.java b/library/main/src/com/android/setupwizardlib/GlifListLayout.java
index 14c7bd7..c6443f9 100644
--- a/library/main/src/com/android/setupwizardlib/GlifListLayout.java
+++ b/library/main/src/com/android/setupwizardlib/GlifListLayout.java
@@ -28,6 +28,8 @@ import android.widget.ListAdapter;
import android.widget.ListView;
import com.android.setupwizardlib.template.ListMixin;
+import com.android.setupwizardlib.template.ListViewScrollHandlingDelegate;
+import com.android.setupwizardlib.template.RequireScrollMixin;
/**
* A GLIF themed layout with a ListView. {@code android:entries} can also be used to specify an
@@ -70,6 +72,10 @@ public class GlifListLayout extends GlifLayout {
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
mListMixin = new ListMixin(this, attrs, defStyleAttr);
registerMixin(ListMixin.class, mListMixin);
+
+ final RequireScrollMixin requireScrollMixin = getMixin(RequireScrollMixin.class);
+ requireScrollMixin.setScrollHandlingDelegate(
+ new ListViewScrollHandlingDelegate(requireScrollMixin, getListView()));
}
@Override
diff --git a/library/main/src/com/android/setupwizardlib/SetupWizardLayout.java b/library/main/src/com/android/setupwizardlib/SetupWizardLayout.java
index 2364e9b..065d2ef 100644
--- a/library/main/src/com/android/setupwizardlib/SetupWizardLayout.java
+++ b/library/main/src/com/android/setupwizardlib/SetupWizardLayout.java
@@ -42,8 +42,8 @@ import android.widget.TextView;
import com.android.setupwizardlib.template.HeaderMixin;
import com.android.setupwizardlib.template.NavigationBarMixin;
import com.android.setupwizardlib.template.ProgressBarMixin;
-import com.android.setupwizardlib.util.RequireScrollHelper;
-import com.android.setupwizardlib.view.BottomScrollView;
+import com.android.setupwizardlib.template.RequireScrollMixin;
+import com.android.setupwizardlib.template.ScrollViewScrollHandlingDelegate;
import com.android.setupwizardlib.view.Illustration;
import com.android.setupwizardlib.view.NavigationBar;
@@ -82,6 +82,14 @@ public class SetupWizardLayout extends TemplateLayout {
registerMixin(HeaderMixin.class, new HeaderMixin(this, attrs, defStyleAttr));
registerMixin(ProgressBarMixin.class, new ProgressBarMixin(this));
registerMixin(NavigationBarMixin.class, new NavigationBarMixin(this));
+ final RequireScrollMixin requireScrollMixin = new RequireScrollMixin(this);
+ registerMixin(RequireScrollMixin.class, requireScrollMixin);
+
+ final ScrollView scrollView = getScrollView();
+ if (scrollView != null) {
+ requireScrollMixin.setScrollHandlingDelegate(
+ new ScrollViewScrollHandlingDelegate(requireScrollMixin, scrollView));
+ }
final TypedArray a = getContext().obtainStyledAttributes(attrs,
R.styleable.SuwSetupWizardLayout, defStyleAttr, 0);
@@ -156,11 +164,7 @@ public class SetupWizardLayout extends TemplateLayout {
final SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
final boolean isProgressBarShown = ss.mIsProgressBarShown;
- if (isProgressBarShown) {
- showProgressBar();
- } else {
- hideProgressBar();
- }
+ setProgressBarShown(isProgressBarShown);
}
@Override
@@ -189,13 +193,12 @@ public class SetupWizardLayout extends TemplateLayout {
}
public void requireScrollToBottom() {
+ final RequireScrollMixin requireScrollMixin = getMixin(RequireScrollMixin.class);
final NavigationBar navigationBar = getNavigationBar();
- final ScrollView scrollView = getScrollView();
- if (navigationBar != null && (scrollView instanceof BottomScrollView)) {
- RequireScrollHelper.requireScroll(navigationBar, (BottomScrollView) scrollView);
+ if (navigationBar != null) {
+ requireScrollMixin.requireScrollWithNavigationBar(navigationBar);
} else {
- Log.e(TAG, "Both suw_layout_navigation_bar and suw_bottom_scroll_view must exist in"
- + " the template to require scrolling.");
+ Log.e(TAG, "Cannot require scroll. Navigation bar is null.");
}
}
diff --git a/library/main/src/com/android/setupwizardlib/SetupWizardListLayout.java b/library/main/src/com/android/setupwizardlib/SetupWizardListLayout.java
index bb96d58..0457451 100644
--- a/library/main/src/com/android/setupwizardlib/SetupWizardListLayout.java
+++ b/library/main/src/com/android/setupwizardlib/SetupWizardListLayout.java
@@ -21,7 +21,6 @@ import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Build.VERSION_CODES;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -29,8 +28,8 @@ import android.widget.ListAdapter;
import android.widget.ListView;
import com.android.setupwizardlib.template.ListMixin;
-import com.android.setupwizardlib.util.ListViewRequireScrollHelper;
-import com.android.setupwizardlib.view.NavigationBar;
+import com.android.setupwizardlib.template.ListViewScrollHandlingDelegate;
+import com.android.setupwizardlib.template.RequireScrollMixin;
public class SetupWizardListLayout extends SetupWizardLayout {
@@ -65,6 +64,10 @@ public class SetupWizardListLayout extends SetupWizardLayout {
private void init(Context context, AttributeSet attrs, int defStyleAttr) {
mListMixin = new ListMixin(this, attrs, defStyleAttr);
registerMixin(ListMixin.class, mListMixin);
+
+ final RequireScrollMixin requireScrollMixin = getMixin(RequireScrollMixin.class);
+ requireScrollMixin.setScrollHandlingDelegate(
+ new ListViewScrollHandlingDelegate(requireScrollMixin, getListView()));
}
@Override
@@ -101,18 +104,6 @@ public class SetupWizardListLayout extends SetupWizardLayout {
return mListMixin.getAdapter();
}
- @Override
- public void requireScrollToBottom() {
- final NavigationBar navigationBar = getNavigationBar();
- final ListView listView = getListView();
- if (navigationBar != null && listView != null) {
- ListViewRequireScrollHelper.requireScroll(navigationBar, listView);
- } else {
- Log.e(TAG, "Both suw_layout_navigation_bar and list must exist in"
- + " the template to require scrolling.");
- }
- }
-
/**
* Sets the start inset of the divider. This will use the default divider drawable set in the
* theme and inset it {@code inset} pixels to the right (or left in RTL layouts).
diff --git a/library/main/src/com/android/setupwizardlib/template/ListViewScrollHandlingDelegate.java b/library/main/src/com/android/setupwizardlib/template/ListViewScrollHandlingDelegate.java
new file mode 100644
index 0000000..f55d06d
--- /dev/null
+++ b/library/main/src/com/android/setupwizardlib/template/ListViewScrollHandlingDelegate.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2017 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.setupwizardlib.template;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.util.Log;
+import android.widget.AbsListView;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+
+import com.android.setupwizardlib.template.RequireScrollMixin.ScrollHandlingDelegate;
+
+/**
+ * {@link ScrollHandlingDelegate} which analyzes scroll events from {@link ListView} and
+ * notifies {@link RequireScrollMixin} about scrollability changes.
+ */
+public class ListViewScrollHandlingDelegate implements ScrollHandlingDelegate,
+ AbsListView.OnScrollListener {
+
+ private static final String TAG = "ListViewDelegate";
+
+ private static final int SCROLL_DURATION = 500;
+
+ @NonNull
+ private final RequireScrollMixin mRequireScrollMixin;
+
+ @Nullable
+ private final ListView mListView;
+
+ public ListViewScrollHandlingDelegate(
+ @NonNull RequireScrollMixin requireScrollMixin,
+ @Nullable ListView listView) {
+ mRequireScrollMixin = requireScrollMixin;
+ mListView = listView;
+ }
+
+ @Override
+ public void startListening() {
+ if (mListView != null) {
+ mListView.setOnScrollListener(this);
+
+ final ListAdapter adapter = mListView.getAdapter();
+ if (mListView.getLastVisiblePosition() < adapter.getCount()) {
+ mRequireScrollMixin.notifyScrollabilityChange(true);
+ }
+ } else {
+ Log.w(TAG, "Cannot require scroll. List view is null");
+ }
+ }
+
+ @Override
+ public void pageScrollDown() {
+ if (mListView != null) {
+ final int height = mListView.getHeight();
+ mListView.smoothScrollBy(height, SCROLL_DURATION);
+ }
+ }
+
+ @Override
+ public void onScrollStateChanged(AbsListView view, int scrollState) {
+ }
+
+ @Override
+ public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
+ int totalItemCount) {
+ if (firstVisibleItem + visibleItemCount >= totalItemCount) {
+ mRequireScrollMixin.notifyScrollabilityChange(false);
+ } else {
+ mRequireScrollMixin.notifyScrollabilityChange(true);
+ }
+ }
+}
diff --git a/library/main/src/com/android/setupwizardlib/template/RequireScrollMixin.java b/library/main/src/com/android/setupwizardlib/template/RequireScrollMixin.java
new file mode 100644
index 0000000..231c064
--- /dev/null
+++ b/library/main/src/com/android/setupwizardlib/template/RequireScrollMixin.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2017 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.setupwizardlib.template;
+
+import android.os.Handler;
+import android.os.Looper;
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.support.annotation.StringRes;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+import com.android.setupwizardlib.TemplateLayout;
+import com.android.setupwizardlib.view.NavigationBar;
+
+/**
+ * A mixin to require the a scrollable container (BottomScrollView, RecyclerView or ListView) to
+ * be scrolled to bottom, making sure that the user sees all content above and below the fold.
+ */
+public class RequireScrollMixin implements Mixin {
+
+ /* static section */
+
+ /**
+ * Listener for when the require-scroll state changes. Note that this only requires the user to
+ * scroll to the bottom once - if the user scrolled to the bottom and back-up, scrolling to
+ * bottom is not required again.
+ */
+ public interface OnRequireScrollStateChangedListener {
+
+ /**
+ * Called when require-scroll state changed.
+ *
+ * @param scrollNeeded True if the user should be required to scroll to bottom.
+ */
+ void onRequireScrollStateChanged(boolean scrollNeeded);
+ }
+
+ /**
+ * A delegate to detect scrollability changes and to scroll the page. This provides a layer
+ * of abstraction for BottomScrollView, RecyclerView and ListView. The delegate should call
+ * {@link #notifyScrollabilityChange(boolean)} when the view scrollability is changed.
+ */
+ interface ScrollHandlingDelegate {
+
+ /**
+ * Starts listening to scrollability changes at the target scrollable container.
+ */
+ void startListening();
+
+ /**
+ * Scroll the page content down by one page.
+ */
+ void pageScrollDown();
+ }
+
+ /* non-static section */
+
+ @NonNull
+ private final TemplateLayout mTemplateLayout;
+
+ private final Handler mHandler = new Handler(Looper.getMainLooper());
+
+ private boolean mRequiringScrollToBottom = false;
+
+ // Whether the user have seen the more button yet.
+ private boolean mEverScrolledToBottom = false;
+
+ private ScrollHandlingDelegate mDelegate;
+
+ @Nullable
+ private OnRequireScrollStateChangedListener mListener;
+
+ /**
+ * @param templateLayout The template containing this mixin
+ */
+ public RequireScrollMixin(@NonNull TemplateLayout templateLayout) {
+ mTemplateLayout = templateLayout;
+ }
+
+ /**
+ * Sets the delegate to handle scrolling. The type of delegate should depend on whether the
+ * scrolling view is a BottomScrollView, RecyclerView or ListView.
+ */
+ public void setScrollHandlingDelegate(@NonNull ScrollHandlingDelegate delegate) {
+ mDelegate = delegate;
+ }
+
+ /**
+ * Listen to require scroll state changes. When scroll is required,
+ * {@link OnRequireScrollStateChangedListener#onRequireScrollStateChanged(boolean)} is called
+ * with {@code true}, and vice versa.
+ */
+ public void setOnRequireScrollStateChangedListener(
+ @Nullable OnRequireScrollStateChangedListener listener) {
+ mListener = listener;
+ }
+
+ /**
+ * @return The scroll state listener previously set, or {@code null} if none is registered.
+ */
+ public OnRequireScrollStateChangedListener getOnRequireScrollStateChangedListener() {
+ return mListener;
+ }
+
+ /**
+ * Creates an {@link OnClickListener} which if scrolling is required, will scroll the page down,
+ * and if scrolling is not required, delegates to the wrapped {@code listener}. Note that you
+ * should call {@link #requireScroll()} as well in order to start requiring scrolling.
+ *
+ * @param listener The listener to be invoked when scrolling is not needed and the user taps on
+ * the button. If {@code null}, the click listener will be a no-op when scroll
+ * is not required.
+ * @return A new {@link OnClickListener} which will scroll the page down or delegate to the
+ * given listener depending on the current require-scroll state.
+ */
+ public OnClickListener createOnClickListener(@Nullable final OnClickListener listener) {
+ return new OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ if (mRequiringScrollToBottom) {
+ mDelegate.pageScrollDown();
+ } else if (listener != null) {
+ listener.onClick(view);
+ }
+ }
+ };
+ }
+
+ /**
+ * Coordinate with the given navigation bar to require scrolling on the page. The more button
+ * will be shown instead of the next button while scrolling is required.
+ */
+ public void requireScrollWithNavigationBar(@NonNull final NavigationBar navigationBar) {
+ setOnRequireScrollStateChangedListener(
+ new OnRequireScrollStateChangedListener() {
+ @Override
+ public void onRequireScrollStateChanged(boolean scrollNeeded) {
+ navigationBar.getMoreButton()
+ .setVisibility(scrollNeeded ? View.VISIBLE : View.GONE);
+ navigationBar.getNextButton()
+ .setVisibility(scrollNeeded ? View.GONE : View.VISIBLE);
+ }
+ });
+ navigationBar.getMoreButton().setOnClickListener(createOnClickListener(null));
+ requireScroll();
+ }
+
+ /**
+ * @see #requireScrollWithButton(Button, CharSequence, OnClickListener)
+ */
+ public void requireScrollWithButton(
+ @NonNull Button button,
+ @StringRes int moreText,
+ @Nullable OnClickListener onClickListener) {
+ requireScrollWithButton(button, button.getContext().getText(moreText), onClickListener);
+ }
+
+ /**
+ * Use the given {@code button} to require scrolling. When scrolling is required, the button
+ * label will change to {@code moreText}, and tapping the button will cause the page to scroll
+ * down.
+ *
+ * <p>Note: Calling {@link View#setOnClickListener} on the button after this method will remove
+ * its link to the require-scroll mechanism. If you need to do that, obtain the click listener
+ * from {@link #createOnClickListener(OnClickListener)}.
+ *
+ * <p>Note: The normal button label is taken from the button's text at the time of calling this
+ * method. Calling {@link android.widget.TextView#setText} after calling this method causes
+ * undefined behavior.
+ *
+ * @param button The button to use for require scroll. The button's "normal" label is taken from
+ * the text at the time of calling this method, and the click listener of it will
+ * be replaced.
+ * @param moreText The button label when scroll is required.
+ * @param onClickListener The listener for clicks when scrolling is not required.
+ */
+ public void requireScrollWithButton(
+ @NonNull final Button button,
+ final CharSequence moreText,
+ @Nullable OnClickListener onClickListener) {
+ final CharSequence nextText = button.getText();
+ button.setOnClickListener(createOnClickListener(onClickListener));
+ setOnRequireScrollStateChangedListener(new OnRequireScrollStateChangedListener() {
+ @Override
+ public void onRequireScrollStateChanged(boolean scrollNeeded) {
+ button.setText(scrollNeeded ? moreText : nextText);
+ }
+ });
+ requireScroll();
+ }
+
+ /**
+ * @return True if scrolling is required. Note that this mixin only requires the user to
+ * scroll to the bottom once - if the user scrolled to the bottom and back-up, scrolling to
+ * bottom is not required again.
+ */
+ public boolean isScrollingRequired() {
+ return mRequiringScrollToBottom;
+ }
+
+ /**
+ * Start requiring scrolling on the layout. After calling this method, this mixin will start
+ * listening to scroll events from the scrolling container, and call
+ * {@link OnRequireScrollStateChangedListener} when the scroll state changes.
+ */
+ public void requireScroll() {
+ mDelegate.startListening();
+ }
+
+ /**
+ * {@link ScrollHandlingDelegate} should call this method when the scrollability of the
+ * scrolling container changed, so this mixin can recompute whether scrolling should be
+ * required.
+ *
+ * @param canScrollDown True if the view can scroll down further.
+ */
+ void notifyScrollabilityChange(boolean canScrollDown) {
+ if (canScrollDown == mRequiringScrollToBottom) {
+ // Already at the desired require-scroll state
+ return;
+ }
+ if (canScrollDown) {
+ if (!mEverScrolledToBottom) {
+ postScrollStateChange(true);
+ mRequiringScrollToBottom = true;
+ }
+ } else {
+ postScrollStateChange(false);
+ mRequiringScrollToBottom = false;
+ mEverScrolledToBottom = true;
+ }
+ }
+
+ private void postScrollStateChange(final boolean scrollNeeded) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (mListener != null) {
+ mListener.onRequireScrollStateChanged(scrollNeeded);
+ }
+ }
+ });
+ }
+}
diff --git a/library/main/src/com/android/setupwizardlib/template/ScrollViewScrollHandlingDelegate.java b/library/main/src/com/android/setupwizardlib/template/ScrollViewScrollHandlingDelegate.java
new file mode 100644
index 0000000..d159465
--- /dev/null
+++ b/library/main/src/com/android/setupwizardlib/template/ScrollViewScrollHandlingDelegate.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2017 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.setupwizardlib.template;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+import android.util.Log;
+import android.widget.ScrollView;
+
+import com.android.setupwizardlib.template.RequireScrollMixin.ScrollHandlingDelegate;
+import com.android.setupwizardlib.view.BottomScrollView;
+import com.android.setupwizardlib.view.BottomScrollView.BottomScrollListener;
+
+/**
+ * {@link ScrollHandlingDelegate} which analyzes scroll events from {@link BottomScrollView} and
+ * notifies {@link RequireScrollMixin} about scrollability changes.
+ */
+public class ScrollViewScrollHandlingDelegate
+ implements ScrollHandlingDelegate, BottomScrollListener {
+
+ private static final String TAG = "ScrollViewDelegate";
+
+ @NonNull
+ private final RequireScrollMixin mRequireScrollMixin;
+
+ @Nullable
+ private final BottomScrollView mScrollView;
+
+ public ScrollViewScrollHandlingDelegate(
+ @NonNull RequireScrollMixin requireScrollMixin,
+ @Nullable ScrollView scrollView) {
+ mRequireScrollMixin = requireScrollMixin;
+ if (scrollView instanceof BottomScrollView) {
+ mScrollView = (BottomScrollView) scrollView;
+ } else {
+ Log.w(TAG, "Cannot set non-BottomScrollView. Found=" + scrollView);
+ mScrollView = null;
+ }
+ }
+
+ @Override
+ public void onScrolledToBottom() {
+ mRequireScrollMixin.notifyScrollabilityChange(false);
+ }
+
+ @Override
+ public void onRequiresScroll() {
+ mRequireScrollMixin.notifyScrollabilityChange(true);
+ }
+
+ @Override
+ public void startListening() {
+ if (mScrollView != null) {
+ mScrollView.setBottomScrollListener(this);
+ } else {
+ Log.w(TAG, "Cannot require scroll. Scroll view is null.");
+ }
+ }
+
+ @Override
+ public void pageScrollDown() {
+ if (mScrollView != null) {
+ mScrollView.pageScroll(ScrollView.FOCUS_DOWN);
+ }
+ }
+}
diff --git a/library/main/src/com/android/setupwizardlib/util/AbstractRequireScrollHelper.java b/library/main/src/com/android/setupwizardlib/util/AbstractRequireScrollHelper.java
deleted file mode 100644
index 2697371..0000000
--- a/library/main/src/com/android/setupwizardlib/util/AbstractRequireScrollHelper.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2016 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.setupwizardlib.util;
-
-import android.view.View;
-
-import com.android.setupwizardlib.view.NavigationBar;
-
-/**
- * Add this helper to require the scroll view to be scrolled to the bottom, making sure that the
- * user sees all content on the screen. This will change the navigation bar to show the more button
- * instead of the next button when there is more content to be seen. When the more button is
- * clicked, the scroll view will be scrolled one page down.
- */
-public abstract class AbstractRequireScrollHelper implements View.OnClickListener {
-
- private final NavigationBar mNavigationBar;
-
- private boolean mScrollNeeded;
- // Whether the user have seen the more button yet.
- private boolean mScrollNotified = false;
-
- protected AbstractRequireScrollHelper(NavigationBar navigationBar) {
- mNavigationBar = navigationBar;
- }
-
- protected void requireScroll() {
- mNavigationBar.getMoreButton().setOnClickListener(this);
- }
-
- protected void notifyScrolledToBottom() {
- if (mScrollNeeded) {
- mNavigationBar.post(new Runnable() {
- @Override
- public void run() {
- mNavigationBar.getNextButton().setVisibility(View.VISIBLE);
- mNavigationBar.getMoreButton().setVisibility(View.GONE);
- }
- });
- mScrollNeeded = false;
- mScrollNotified = true;
- }
- }
-
- protected void notifyRequiresScroll() {
- if (!mScrollNeeded && !mScrollNotified) {
- mNavigationBar.post(new Runnable() {
- @Override
- public void run() {
- mNavigationBar.getNextButton().setVisibility(View.GONE);
- mNavigationBar.getMoreButton().setVisibility(View.VISIBLE);
- }
- });
- mScrollNeeded = true;
- }
- }
-
- @Override
- public void onClick(View view) {
- pageScrollDown();
- }
-
- protected abstract void pageScrollDown();
-}
diff --git a/library/main/src/com/android/setupwizardlib/util/ListViewRequireScrollHelper.java b/library/main/src/com/android/setupwizardlib/util/ListViewRequireScrollHelper.java
deleted file mode 100644
index 7877569..0000000
--- a/library/main/src/com/android/setupwizardlib/util/ListViewRequireScrollHelper.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2016 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.setupwizardlib.util;
-
-import android.os.Build;
-import android.widget.AbsListView;
-import android.widget.ListAdapter;
-import android.widget.ListView;
-
-import com.android.setupwizardlib.view.NavigationBar;
-
-/**
- * Add this helper to require the list view to be scrolled to the bottom, making sure that the
- * user sees all content on the screen. This will change the navigation bar to show the more button
- * instead of the next button when there is more content to be seen. When the more button is
- * clicked, the list view will be scrolled one page down.
- */
-public class ListViewRequireScrollHelper extends AbstractRequireScrollHelper
- implements AbsListView.OnScrollListener {
-
- public static void requireScroll(NavigationBar navigationBar, ListView listView) {
- new ListViewRequireScrollHelper(navigationBar, listView).requireScroll();
- }
-
- private final ListView mListView;
-
- private ListViewRequireScrollHelper(NavigationBar navigationBar, ListView listView) {
- super(navigationBar);
- mListView = listView;
- }
-
- @Override
- protected void requireScroll() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
- // APIs to scroll a list only exists on Froyo or above.
- super.requireScroll();
- mListView.setOnScrollListener(this);
-
- final ListAdapter adapter = mListView.getAdapter();
- if (mListView.getLastVisiblePosition() < adapter.getCount()) {
- notifyRequiresScroll();
- }
- }
- }
-
- @Override
- protected void pageScrollDown() {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) {
- final int height = mListView.getHeight();
- mListView.smoothScrollBy(height, 500);
- }
- }
-
- @Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
- }
-
- @Override
- public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,
- int totalItemCount) {
- if (firstVisibleItem + visibleItemCount >= totalItemCount) {
- notifyScrolledToBottom();
- } else {
- notifyRequiresScroll();
- }
- }
-}
diff --git a/library/main/src/com/android/setupwizardlib/util/RequireScrollHelper.java b/library/main/src/com/android/setupwizardlib/util/RequireScrollHelper.java
deleted file mode 100644
index cce336f..0000000
--- a/library/main/src/com/android/setupwizardlib/util/RequireScrollHelper.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2015 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.setupwizardlib.util;
-
-import android.widget.ScrollView;
-
-import com.android.setupwizardlib.view.BottomScrollView;
-import com.android.setupwizardlib.view.NavigationBar;
-
-/**
- * Add this helper to require the scroll view to be scrolled to the bottom, making sure that the
- * user sees all content on the screen. This will change the navigation bar to show the more button
- * instead of the next button when there is more content to be seen. When the more button is
- * clicked, the scroll view will be scrolled one page down.
- */
-public class RequireScrollHelper extends AbstractRequireScrollHelper
- implements BottomScrollView.BottomScrollListener {
-
- public static void requireScroll(NavigationBar navigationBar, BottomScrollView scrollView) {
- new RequireScrollHelper(navigationBar, scrollView).requireScroll();
- }
-
- private final BottomScrollView mScrollView;
-
- private RequireScrollHelper(NavigationBar navigationBar, BottomScrollView scrollView) {
- super(navigationBar);
- mScrollView = scrollView;
- }
-
- @Override
- protected void requireScroll() {
- super.requireScroll();
- mScrollView.setBottomScrollListener(this);
- }
-
- @Override
- protected void pageScrollDown() {
- mScrollView.pageScroll(ScrollView.FOCUS_DOWN);
- }
-
- @Override
- public void onScrolledToBottom() {
- notifyScrolledToBottom();
- }
-
- @Override
- public void onRequiresScroll() {
- notifyRequiresScroll();
- }
-}
diff --git a/library/main/src/com/android/setupwizardlib/view/NavigationBar.java b/library/main/src/com/android/setupwizardlib/view/NavigationBar.java
index 9bb123f..2a1dd28 100644
--- a/library/main/src/com/android/setupwizardlib/view/NavigationBar.java
+++ b/library/main/src/com/android/setupwizardlib/view/NavigationBar.java
@@ -35,7 +35,7 @@ import com.android.setupwizardlib.R;
* next button. By default, the more button is hidden, and typically the next button will be hidden
* if the more button is shown.
*
- * @see com.android.setupwizardlib.util.RequireScrollHelper
+ * @see com.android.setupwizardlib.template.RequireScrollMixin
*/
public class NavigationBar extends LinearLayout implements View.OnClickListener {