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 androidx.annotation.NonNull;
20 import androidx.annotation.Nullable;
21 import androidx.recyclerview.widget.RecyclerView;
22 import android.util.Log;
23 import com.android.setupwizardlib.template.RequireScrollMixin.ScrollHandlingDelegate;
24 
25 /**
26  * {@link ScrollHandlingDelegate} which analyzes scroll events from {@link RecyclerView} and
27  * notifies {@link RequireScrollMixin} about scrollability changes.
28  */
29 public class RecyclerViewScrollHandlingDelegate implements ScrollHandlingDelegate {
30 
31   private static final String TAG = "RVRequireScrollMixin";
32 
33   @Nullable private final RecyclerView recyclerView;
34 
35   @NonNull private final RequireScrollMixin requireScrollMixin;
36 
RecyclerViewScrollHandlingDelegate( @onNull RequireScrollMixin requireScrollMixin, @Nullable RecyclerView recyclerView)37   public RecyclerViewScrollHandlingDelegate(
38       @NonNull RequireScrollMixin requireScrollMixin, @Nullable RecyclerView recyclerView) {
39     this.requireScrollMixin = requireScrollMixin;
40     this.recyclerView = recyclerView;
41   }
42 
canScrollDown()43   private boolean canScrollDown() {
44     if (recyclerView != null) {
45       // Compatibility implementation of View#canScrollVertically
46       final int offset = recyclerView.computeVerticalScrollOffset();
47       final int range =
48           recyclerView.computeVerticalScrollRange() - recyclerView.computeVerticalScrollExtent();
49       return range != 0 && offset < range - 1;
50     }
51     return false;
52   }
53 
54   @Override
startListening()55   public void startListening() {
56     if (this.recyclerView != null) {
57       this.recyclerView.addOnScrollListener(
58           new RecyclerView.OnScrollListener() {
59             @Override
60             public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
61               requireScrollMixin.notifyScrollabilityChange(canScrollDown());
62             }
63           });
64 
65       if (canScrollDown()) {
66         requireScrollMixin.notifyScrollabilityChange(true);
67       }
68     } else {
69       Log.w(TAG, "Cannot require scroll. Recycler view is null.");
70     }
71   }
72 
73   @Override
pageScrollDown()74   public void pageScrollDown() {
75     if (recyclerView != null) {
76       final int height = recyclerView.getHeight();
77       recyclerView.smoothScrollBy(0, height);
78     }
79   }
80 }
81