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 package com.android.documentsui.dirlist; 17 18 import static androidx.core.util.Preconditions.checkState; 19 import static com.android.documentsui.base.SharedMinimal.DEBUG; 20 import static com.android.documentsui.base.SharedMinimal.VERBOSE; 21 22 import android.content.Context; 23 import android.os.Build; 24 import androidx.annotation.Nullable; 25 import androidx.recyclerview.widget.RecyclerView; 26 import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener; 27 import android.util.Log; 28 import android.view.MotionEvent; 29 import android.view.ScaleGestureDetector; 30 31 import com.android.documentsui.base.Features; 32 33 import java.util.function.Consumer; 34 35 /** 36 * Class providing support for gluing gesture scaling of the ui into RecyclerView + DocsUI. 37 */ 38 final class ScaleHelper { 39 40 private static final String TAG = "ScaleHelper"; 41 42 private final Context mContext; 43 private final Features mFeatures; 44 private final Consumer<Float> mScaleCallback; 45 46 private @Nullable ScaleGestureDetector mScaleDetector; 47 ScaleHelper(Context context, Features features, Consumer<Float> scaleCallback)48 public ScaleHelper(Context context, Features features, Consumer<Float> scaleCallback) { 49 mContext = context; 50 mFeatures = features; 51 mScaleCallback = scaleCallback; 52 } 53 onInterceptTouchEvent(RecyclerView rv, MotionEvent e)54 private boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { 55 // Checking feature is deferred to runtime so the feature can be enabled 56 // after this class has been setup. 57 if (mFeatures.isGestureScaleEnabled() && mScaleDetector != null) { 58 mScaleDetector.onTouchEvent(e); 59 } 60 61 return false; 62 } 63 attach(RecyclerView view)64 void attach(RecyclerView view) { 65 checkState(DEBUG); 66 checkState(mScaleDetector == null); 67 68 mScaleDetector = new ScaleGestureDetector( 69 mContext, 70 new ScaleGestureDetector.SimpleOnScaleGestureListener() { 71 @Override 72 public boolean onScale(ScaleGestureDetector detector) { 73 if (VERBOSE) Log.v(TAG, 74 "Received scale event: " + detector.getScaleFactor()); 75 mScaleCallback.accept(detector.getScaleFactor()); 76 return true; 77 } 78 }); 79 80 view.addOnItemTouchListener( 81 new OnItemTouchListener() { 82 @Override 83 public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { 84 return ScaleHelper.this.onInterceptTouchEvent(rv, e); 85 } 86 87 @Override 88 public void onTouchEvent(RecyclerView rv, MotionEvent e) {} 89 90 @Override 91 public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) {} 92 }); 93 } 94 } 95