1 /*
2  * Copyright 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 androidx.recyclerview.selection;
18 
19 import static androidx.core.util.Preconditions.checkArgument;
20 
21 import androidx.annotation.IntDef;
22 import androidx.recyclerview.widget.RecyclerView;
23 
24 import org.jspecify.annotations.NonNull;
25 import org.jspecify.annotations.Nullable;
26 
27 import java.lang.annotation.Retention;
28 import java.lang.annotation.RetentionPolicy;
29 
30 /**
31  * Provides selection library access to stable selection keys identifying items
32  * presented by a {@link RecyclerView RecyclerView} instance.
33  *
34  * @param <K> Selection key type. @see {@link StorageStrategy} for supported types.
35  */
36 public abstract class ItemKeyProvider<K> {
37 
38     /**
39      * Provides access to all data, regardless of whether it is bound to a view or not.
40      * Key providers with this access type enjoy support for enhanced features like:
41      * SHIFT+click range selection, and band selection.
42      */
43     public static final int SCOPE_MAPPED = 0;
44 
45     /**
46      * Provides access to cached data based for items that were recently bound in the view.
47      * Employing this provider will result in a reduced feature-set, as some
48      * features like SHIFT+click range selection and band selection are dependent
49      * on mapped access.
50      */
51     public static final int SCOPE_CACHED = 1;
52 
53     @IntDef({
54             SCOPE_MAPPED,
55             SCOPE_CACHED
56     })
57     @Retention(RetentionPolicy.SOURCE)
58     public @interface Scope {}
59 
60     private final @Scope int mScope;
61 
62     /**
63      * Creates a new provider with the given scope.
64      *
65      * @param scope Scope can't be changed at runtime.
66      */
ItemKeyProvider(@cope int scope)67     protected ItemKeyProvider(@Scope int scope) {
68         checkArgument(scope == SCOPE_MAPPED || scope == SCOPE_CACHED);
69 
70         mScope = scope;
71     }
72 
hasAccess(@cope int scope)73     final boolean hasAccess(@Scope int scope) {
74         return scope == mScope;
75     }
76 
77     /**
78      * @return The selection key at the given adapter position, or null.
79      */
getKey(int position)80     public abstract @Nullable K getKey(int position);
81 
82     /**
83      * @return the position corresponding to the selection key, or RecyclerView.NO_POSITION
84      * if the key is unrecognized.
85      */
getPosition(@onNull K key)86     public abstract int getPosition(@NonNull K key);
87 }
88