mirror of https://github.com/M66B/FairEmail.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
231 lines
7.2 KiB
231 lines
7.2 KiB
/*
|
|
* Copyright 2018 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 androidx.recyclerview.selection;
|
|
|
|
import static androidx.core.util.Preconditions.checkArgument;
|
|
|
|
import android.os.Bundle;
|
|
import android.os.Parcelable;
|
|
|
|
import androidx.annotation.NonNull;
|
|
import androidx.annotation.Nullable;
|
|
import androidx.annotation.VisibleForTesting;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
/**
|
|
* Strategy for storing keys in saved state. Extend this class when using custom
|
|
* key types that aren't supported by default. Prefer use of builtin storage strategies:
|
|
* {@link #createStringStorage()}, {@link #createLongStorage()},
|
|
* {@link #createParcelableStorage(Class)}.
|
|
*
|
|
* <p>
|
|
* See
|
|
* {@link androidx.recyclerview.selection.SelectionTracker.Builder SelectionTracker.Builder}
|
|
* for more detailed advice on which key type to use for your selection keys.
|
|
*
|
|
* @param <K> Selection key type. Built in support is provided for String, Long, and Parcelable
|
|
* types. Use the respective factory method to create a StorageStrategy instance
|
|
* appropriate to the desired type.
|
|
* {@link #createStringStorage()},
|
|
* {@link #createParcelableStorage(Class)},
|
|
* {@link #createLongStorage()}
|
|
*/
|
|
public abstract class StorageStrategy<K> {
|
|
|
|
@VisibleForTesting
|
|
static final String SELECTION_ENTRIES = "androidx.recyclerview.selection.entries";
|
|
|
|
@VisibleForTesting
|
|
static final String SELECTION_KEY_TYPE = "androidx.recyclerview.selection.type";
|
|
|
|
private final Class<K> mType;
|
|
|
|
/**
|
|
* Creates a new instance.
|
|
*
|
|
* @param type the key type class that is being used.
|
|
*/
|
|
public StorageStrategy(@NonNull Class<K> type) {
|
|
checkArgument(type != null);
|
|
mType = type;
|
|
}
|
|
|
|
/**
|
|
* Create a {@link Selection} from supplied {@link Bundle}.
|
|
*
|
|
* @param state Bundle instance that may contain parceled Selection instance.
|
|
* @return
|
|
*/
|
|
public abstract @Nullable Selection<K> asSelection(@NonNull Bundle state);
|
|
|
|
/**
|
|
* Creates a {@link Bundle} from supplied {@link Selection}.
|
|
*
|
|
* @param selection The selection to asBundle.
|
|
* @return
|
|
*/
|
|
public abstract @NonNull Bundle asBundle(@NonNull Selection<K> selection);
|
|
|
|
String getKeyTypeName() {
|
|
return mType.getCanonicalName();
|
|
}
|
|
|
|
/**
|
|
* @return StorageStrategy suitable for use with {@link Parcelable} keys
|
|
* (like {@link android.net.Uri}).
|
|
*/
|
|
public static <K extends Parcelable> StorageStrategy<K> createParcelableStorage(Class<K> type) {
|
|
return new ParcelableStorageStrategy(type);
|
|
}
|
|
|
|
/**
|
|
* @return StorageStrategy suitable for use with {@link String} keys.
|
|
*/
|
|
public static StorageStrategy<String> createStringStorage() {
|
|
return new StringStorageStrategy();
|
|
}
|
|
|
|
/**
|
|
* @return StorageStrategy suitable for use with {@link Long} keys.
|
|
*/
|
|
public static StorageStrategy<Long> createLongStorage() {
|
|
return new LongStorageStrategy();
|
|
}
|
|
|
|
private static class StringStorageStrategy extends StorageStrategy<String> {
|
|
|
|
StringStorageStrategy() {
|
|
super(String.class);
|
|
}
|
|
|
|
@Override
|
|
public @Nullable Selection<String> asSelection(@NonNull Bundle state) {
|
|
|
|
String keyType = state.getString(SELECTION_KEY_TYPE, null);
|
|
if (keyType == null || !keyType.equals(getKeyTypeName())) {
|
|
return null;
|
|
}
|
|
|
|
@Nullable ArrayList<String> stored = state.getStringArrayList(SELECTION_ENTRIES);
|
|
if (stored == null) {
|
|
return null;
|
|
}
|
|
|
|
Selection<String> selection = new Selection<>();
|
|
selection.mSelection.addAll(stored);
|
|
return selection;
|
|
}
|
|
|
|
@Override
|
|
public @NonNull Bundle asBundle(@NonNull Selection<String> selection) {
|
|
|
|
Bundle bundle = new Bundle();
|
|
|
|
bundle.putString(SELECTION_KEY_TYPE, getKeyTypeName());
|
|
|
|
ArrayList<String> value = new ArrayList<>(selection.size());
|
|
value.addAll(selection.mSelection);
|
|
bundle.putStringArrayList(SELECTION_ENTRIES, value);
|
|
|
|
return bundle;
|
|
}
|
|
}
|
|
|
|
private static class LongStorageStrategy extends StorageStrategy<Long> {
|
|
|
|
LongStorageStrategy() {
|
|
super(Long.class);
|
|
}
|
|
|
|
@Override
|
|
public @Nullable Selection<Long> asSelection(@NonNull Bundle state) {
|
|
String keyType = state.getString(SELECTION_KEY_TYPE, null);
|
|
if (keyType == null || !keyType.equals(getKeyTypeName())) {
|
|
return null;
|
|
}
|
|
|
|
@Nullable long[] stored = state.getLongArray(SELECTION_ENTRIES);
|
|
if (stored == null) {
|
|
return null;
|
|
}
|
|
|
|
Selection<Long> selection = new Selection<>();
|
|
for (long key : stored) {
|
|
selection.mSelection.add(key);
|
|
}
|
|
return selection;
|
|
}
|
|
|
|
@Override
|
|
public @NonNull Bundle asBundle(@NonNull Selection<Long> selection) {
|
|
|
|
Bundle bundle = new Bundle();
|
|
bundle.putString(SELECTION_KEY_TYPE, getKeyTypeName());
|
|
|
|
long[] value = new long[selection.size()];
|
|
int i = 0;
|
|
for (Long key : selection) {
|
|
value[i++] = key;
|
|
}
|
|
bundle.putLongArray(SELECTION_ENTRIES, value);
|
|
|
|
return bundle;
|
|
}
|
|
}
|
|
|
|
private static class ParcelableStorageStrategy<K extends Parcelable>
|
|
extends StorageStrategy<K> {
|
|
|
|
ParcelableStorageStrategy(Class<K> type) {
|
|
super(type);
|
|
checkArgument(Parcelable.class.isAssignableFrom(type));
|
|
}
|
|
|
|
@Override
|
|
public @Nullable Selection<K> asSelection(@NonNull Bundle state) {
|
|
|
|
String keyType = state.getString(SELECTION_KEY_TYPE, null);
|
|
if (keyType == null || !keyType.equals(getKeyTypeName())) {
|
|
return null;
|
|
}
|
|
|
|
@Nullable ArrayList<K> stored = state.getParcelableArrayList(SELECTION_ENTRIES);
|
|
if (stored == null) {
|
|
return null;
|
|
}
|
|
|
|
Selection<K> selection = new Selection<>();
|
|
selection.mSelection.addAll(stored);
|
|
return selection;
|
|
}
|
|
|
|
@Override
|
|
public @NonNull Bundle asBundle(@NonNull Selection<K> selection) {
|
|
|
|
Bundle bundle = new Bundle();
|
|
bundle.putString(SELECTION_KEY_TYPE, getKeyTypeName());
|
|
|
|
ArrayList<K> value = new ArrayList<>(selection.size());
|
|
value.addAll(selection.mSelection);
|
|
bundle.putParcelableArrayList(SELECTION_ENTRIES, value);
|
|
|
|
return bundle;
|
|
}
|
|
}
|
|
}
|