diff options
Diffstat (limited to 'library/main/src')
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 { |