1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.setupwizardlib.template;
18 
19 import android.support.annotation.NonNull;
20 import android.support.annotation.Nullable;
21 import android.support.v7.widget.RecyclerView;
22 import android.util.Log;
23 
24 import com.android.setupwizardlib.template.RequireScrollMixin.ScrollHandlingDelegate;
25 
26 /**
27  * {@link ScrollHandlingDelegate} which analyzes scroll events from {@link RecyclerView} and
28  * notifies {@link RequireScrollMixin} about scrollability changes.
29  */
30 public class RecyclerViewScrollHandlingDelegate implements ScrollHandlingDelegate {
31 
32     private static final String TAG = "RVRequireScrollMixin";
33 
34     @Nullable
35     private final RecyclerView mRecyclerView;
36 
37     @NonNull
38     private final RequireScrollMixin mRequireScrollMixin;
39 
RecyclerViewScrollHandlingDelegate( @onNull RequireScrollMixin requireScrollMixin, @Nullable RecyclerView recyclerView)40     public RecyclerViewScrollHandlingDelegate(
41             @NonNull RequireScrollMixin requireScrollMixin,
42             @Nullable RecyclerView recyclerView) {
43         mRequireScrollMixin = requireScrollMixin;
44         mRecyclerView = recyclerView;
45     }
46 
canScrollDown()47     private boolean canScrollDown() {
48         if (mRecyclerView != null) {
49             // Compatibility implementation of View#canScrollVertically
50             final int offset = mRecyclerView.computeVerticalScrollOffset();
51             final int range = mRecyclerView.computeVerticalScrollRange()
52                     - mRecyclerView.computeVerticalScrollExtent();
53             return range != 0 && offset < range - 1;
54         }
55         return false;
56     }
57 
58     @Override
startListening()59     public void startListening() {
60         if (mRecyclerView != null) {
61             mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
62                 @Override
63                 public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
64                     mRequireScrollMixin.notifyScrollabilityChange(canScrollDown());
65                 }
66             });
67 
68             if (canScrollDown()) {
69                 mRequireScrollMixin.notifyScrollabilityChange(true);
70             }
71         } else {
72             Log.w(TAG, "Cannot require scroll. Recycler view is null.");
73         }
74     }
75 
76     @Override
pageScrollDown()77     public void pageScrollDown() {
78         if (mRecyclerView != null) {
79             final int height = mRecyclerView.getHeight();
80             mRecyclerView.smoothScrollBy(0, height);
81         }
82     }
83 }
84