java.lang.Object
↳androidx.navigation.NavType<T>
Subclasses:
NavType.ParcelableType<D>, NavType.ParcelableArrayType<D>, NavType.SerializableType<D>, NavType.EnumType<D>, NavType.SerializableArrayType<D>
Overview
NavType denotes the type that can be used in a NavArgument.
There are built-in NavTypes for primitive types, such as int, long, boolean, float, and
strings, parcelable, and serializable classes (including Enums), as well as arrays of
each supported type.
You should only use one of the static NavType instances and subclasses
defined in this class.
Summary
Fields |
---|
public static final NavType<UnknownReference> | BoolArrayType NavType for storing boolean arrays,
corresponding with the "boolean[]" type in a Navigation XML file. |
public static final NavType<java.lang.Boolean> | BoolType NavType for storing boolean values,
corresponding with the "boolean" type in a Navigation XML file. |
public static final NavType<UnknownReference> | FloatArrayType NavType for storing float arrays,
corresponding with the "float[]" type in a Navigation XML file. |
public static final NavType<java.lang.Float> | FloatType NavType for storing float values,
corresponding with the "float" type in a Navigation XML file. |
public static final NavType<UnknownReference> | IntArrayType NavType for storing integer arrays,
corresponding with the "integer[]" type in a Navigation XML file. |
public static final NavType<java.lang.Integer> | IntType NavType for storing integer values,
corresponding with the "integer" type in a Navigation XML file. |
public static final NavType<UnknownReference> | LongArrayType NavType for storing long arrays,
corresponding with the "long[]" type in a Navigation XML file. |
public static final NavType<java.lang.Long> | LongType NavType for storing long values,
corresponding with the "long" type in a Navigation XML file. |
public static final NavType<java.lang.Integer> | ReferenceType NavType for storing integer values representing resource ids,
corresponding with the "reference" type in a Navigation XML file. |
public static final NavType<java.lang.String> | StringArrayType NavType for storing String arrays,
corresponding with the "string[]" type in a Navigation XML file. |
public static final NavType<java.lang.String> | StringType NavType for storing String values,
corresponding with the "string" type in a Navigation XML file. |
Methods |
---|
public static NavType<java.lang.Object> | fromArgType(java.lang.String type, java.lang.String packageName)
Parse an argType string into a NavType. |
public abstract java.lang.Object | get(Bundle bundle, java.lang.String key)
Get a value of this type from the bundle |
public abstract java.lang.String | getName()
Returns the name of this type. |
public boolean | isNullableAllowed()
Check if an argument with this type can hold a null value. |
public abstract java.lang.Object | parseValue(java.lang.String value)
Parse a value of this type from a String. |
public abstract void | put(Bundle bundle, java.lang.String key, java.lang.Object value)
Put a value of this type in he bundle |
public java.lang.String | toString()
|
from java.lang.Object | clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Fields
public static final
NavType<java.lang.Integer>
IntTypeNavType for storing integer values,
corresponding with the "integer" type in a Navigation XML file.
Null values are not supported.
public static final
NavType<java.lang.Integer>
ReferenceTypeNavType for storing integer values representing resource ids,
corresponding with the "reference" type in a Navigation XML file.
Null values are not supported.
public static final
NavType<UnknownReference>
IntArrayTypeNavType for storing integer arrays,
corresponding with the "integer[]" type in a Navigation XML file.
Null values are supported.
Default values in Navigation XML files are not supported.
public static final
NavType<java.lang.Long>
LongTypeNavType for storing long values,
corresponding with the "long" type in a Navigation XML file.
Null values are not supported.
Default values for this type in Navigation XML files must always end with an 'L' suffix, e.g.
`app:defaultValue="123L"`.
public static final
NavType<UnknownReference>
LongArrayTypeNavType for storing long arrays,
corresponding with the "long[]" type in a Navigation XML file.
Null values are supported.
Default values in Navigation XML files are not supported.
public static final
NavType<java.lang.Float>
FloatTypeNavType for storing float values,
corresponding with the "float" type in a Navigation XML file.
Null values are not supported.
public static final
NavType<UnknownReference>
FloatArrayTypeNavType for storing float arrays,
corresponding with the "float[]" type in a Navigation XML file.
Null values are supported.
Default values in Navigation XML files are not supported.
public static final
NavType<java.lang.Boolean>
BoolTypeNavType for storing boolean values,
corresponding with the "boolean" type in a Navigation XML file.
Null values are not supported.
public static final
NavType<UnknownReference>
BoolArrayTypeNavType for storing boolean arrays,
corresponding with the "boolean[]" type in a Navigation XML file.
Null values are supported.
Default values in Navigation XML files are not supported.
public static final
NavType<java.lang.String>
StringTypeNavType for storing String values,
corresponding with the "string" type in a Navigation XML file.
Null values are supported.
public static final
NavType<java.lang.String>
StringArrayTypeNavType for storing String arrays,
corresponding with the "string[]" type in a Navigation XML file.
Null values are supported.
Default values in Navigation XML files are not supported.
Methods
public boolean
isNullableAllowed()
Check if an argument with this type can hold a null value.
Returns:
Returns true if this type allows null values, false otherwise.
public abstract void
put(Bundle bundle, java.lang.String key, java.lang.Object value)
Put a value of this type in he bundle
Parameters:
bundle: bundle to put value in
key: bundle key
value: value of this type
public abstract java.lang.Object
get(Bundle bundle, java.lang.String key)
Get a value of this type from the bundle
Parameters:
bundle: bundle to get value from
key: bundle key
Returns:
value of this type
public abstract java.lang.Object
parseValue(java.lang.String value)
Parse a value of this type from a String.
Parameters:
value: string representation of a value of this type
Returns:
parsed value of the type represented by this NavType
public abstract java.lang.String
getName()
Returns the name of this type.
This is the same value that is used in Navigation XML argType
attribute.
Returns:
name of this type
public java.lang.String
toString()
public static
NavType<java.lang.Object>
fromArgType(java.lang.String type, java.lang.String packageName)
Parse an argType string into a NavType.
Parameters:
type: argType string, usually parsed from the Navigation XML file
packageName: package name of the R file,
used for parsing relative class names starting with a dot.
Returns:
a NavType representing the type indicated by the argType string.
Defaults to StringType for null.
Source
/*
* 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.navigation;
import android.os.Bundle;
import android.os.Parcelable;
import androidx.annotation.AnyRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.io.Serializable;
import java.text.ParseException;
/**
* NavType denotes the type that can be used in a {@link NavArgument}.
* <p>
* There are built-in NavTypes for primitive types, such as int, long, boolean, float, and
* strings, parcelable, and serializable classes (including Enums), as well as arrays of
* each supported type.
* <p>
* You should only use one of the static NavType instances and subclasses
* defined in this class.
*
* @param <T> the type of the data that is supported by this NavType
*/
public abstract class NavType<T> {
private final boolean mNullableAllowed;
NavType(boolean nullableAllowed) {
this.mNullableAllowed = nullableAllowed;
}
/**
* Check if an argument with this type can hold a null value.
* @return Returns true if this type allows null values, false otherwise.
*/
public boolean isNullableAllowed() {
return mNullableAllowed;
}
/**
* Put a value of this type in he {@code bundle}
*
* @param bundle bundle to put value in
* @param key bundle key
* @param value value of this type
*/
public abstract void put(@NonNull Bundle bundle, @NonNull String key, @Nullable T value);
/**
* Get a value of this type from the {@code bundle}
*
* @param bundle bundle to get value from
* @param key bundle key
* @return value of this type
*/
@Nullable
public abstract T get(@NonNull Bundle bundle, @NonNull String key);
/**
* Parse a value of this type from a String.
*
* @param value string representation of a value of this type
* @return parsed value of the type represented by this NavType
* @throws IllegalArgumentException if value cannot be parsed into this type
*/
@NonNull
public abstract T parseValue(@NonNull String value);
/**
* Parse a value of this type from a String and put it in a {@code bundle}
*
* @param bundle bundle to put value in
* @param key bundle key under which to put the value
* @param value parsed value
* @return parsed value of the type represented by this NavType
* @throws ParseException if value cannot be parsed into this type
*/
@NonNull
T parseAndPut(@NonNull Bundle bundle, @NonNull String key, @NonNull String value) {
T parsedValue = parseValue(value);
put(bundle, key, parsedValue);
return parsedValue;
}
/**
* Returns the name of this type.
* <p>
* This is the same value that is used in Navigation XML <code>argType</code> attribute.
*
* @return name of this type
*/
@NonNull
public abstract String getName();
@Override
@NonNull
public String toString() {
return getName();
}
/**
* Parse an argType string into a NavType.
*
* @param type argType string, usually parsed from the Navigation XML file
* @param packageName package name of the R file,
* used for parsing relative class names starting with a dot.
* @return a NavType representing the type indicated by the argType string.
* Defaults to StringType for null.
*/
@SuppressWarnings("unchecked")
@NonNull
public static NavType<?> fromArgType(@Nullable String type, @Nullable String packageName) {
if (IntType.getName().equals(type)) {
return IntType;
} else if (IntArrayType.getName().equals(type)) {
return IntArrayType;
} else if (LongType.getName().equals(type)) {
return LongType;
} else if (LongArrayType.getName().equals(type)) {
return LongArrayType;
} else if (BoolType.getName().equals(type)) {
return BoolType;
} else if (BoolArrayType.getName().equals(type)) {
return BoolArrayType;
} else if (StringType.getName().equals(type)) {
return StringType;
} else if (StringArrayType.getName().equals(type)) {
return StringArrayType;
} else if (FloatType.getName().equals(type)) {
return FloatType;
} else if (FloatArrayType.getName().equals(type)) {
return FloatArrayType;
} else if (ReferenceType.getName().equals(type)) {
return ReferenceType;
} else if (type != null && !type.isEmpty()) {
try {
String className;
if (type.startsWith(".") && packageName != null) {
className = packageName + type;
} else {
className = type;
}
if (type.endsWith("[]")) {
className = className.substring(0, className.length() - 2);
Class<?> clazz = Class.forName(className);
if (Parcelable.class.isAssignableFrom(clazz)) {
return new ParcelableArrayType(clazz);
} else if (Serializable.class.isAssignableFrom(clazz)) {
return new SerializableArrayType(clazz);
}
} else {
Class<?> clazz = Class.forName(className);
if (Parcelable.class.isAssignableFrom(clazz)) {
return new ParcelableType(clazz);
} else if (Enum.class.isAssignableFrom(clazz)) {
return new EnumType(clazz);
} else if (Serializable.class.isAssignableFrom(clazz)) {
return new SerializableType(clazz);
}
}
throw new IllegalArgumentException(className + " is not Serializable or "
+ "Parcelable.");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
return StringType;
}
@NonNull
static NavType inferFromValue(@NonNull String value) {
//because we allow Long literals without the L suffix at runtime,
//the order of IntType and LongType parsing has to be reversed compared to Safe Args
try {
IntType.parseValue(value);
return IntType;
} catch (IllegalArgumentException e) {
//ignored, proceed to check next type
}
try {
LongType.parseValue(value);
return LongType;
} catch (IllegalArgumentException e) {
//ignored, proceed to check next type
}
try {
FloatType.parseValue(value);
return FloatType;
} catch (IllegalArgumentException e) {
//ignored, proceed to check next type
}
try {
BoolType.parseValue(value);
return BoolType;
} catch (IllegalArgumentException e) {
//ignored, proceed to check next type
}
return StringType;
}
@SuppressWarnings("unchecked")
@NonNull
static NavType inferFromValueType(@Nullable Object value) {
if (value instanceof Integer) {
return IntType;
} else if (value instanceof int[]) {
return IntArrayType;
} else if (value instanceof Long) {
return LongType;
} else if (value instanceof long[]) {
return LongArrayType;
} else if (value instanceof Float) {
return FloatType;
} else if (value instanceof float[]) {
return FloatArrayType;
} else if (value instanceof Boolean) {
return BoolType;
} else if (value instanceof boolean[]) {
return BoolArrayType;
} else if (value instanceof String || value == null) {
return StringType;
} else if (value instanceof String[]) {
return StringArrayType;
} else if (value.getClass().isArray()
&& Parcelable.class.isAssignableFrom(value.getClass().getComponentType())) {
return new ParcelableArrayType(value.getClass().getComponentType());
} else if (value.getClass().isArray()
&& Serializable.class.isAssignableFrom(value.getClass().getComponentType())) {
return new SerializableArrayType(value.getClass().getComponentType());
} else if (value instanceof Parcelable) {
return new ParcelableType(value.getClass());
} else if (value instanceof Enum) {
return new EnumType(value.getClass());
} else if (value instanceof Serializable) {
return new SerializableType(value.getClass());
} else {
throw new IllegalArgumentException("Object of type " + value.getClass().getName()
+ " is not supported for navigation arguments.");
}
}
/**
* NavType for storing integer values,
* corresponding with the "integer" type in a Navigation XML file.
* <p>
* Null values are not supported.
*/
@NonNull
public static final NavType<Integer> IntType = new NavType<Integer>(false) {
@Override
public void put(@NonNull Bundle bundle, @NonNull String key, @NonNull Integer value) {
bundle.putInt(key, value);
}
@Override
public Integer get(@NonNull Bundle bundle, @NonNull String key) {
return (Integer) bundle.get(key);
}
@NonNull
@Override
public Integer parseValue(@NonNull String value) {
if (value.startsWith("0x")) {
return Integer.parseInt(value.substring(2), 16);
} else {
return Integer.parseInt(value);
}
}
@NonNull
@Override
public String getName() {
return "integer";
}
};
/**
* NavType for storing integer values representing resource ids,
* corresponding with the "reference" type in a Navigation XML file.
* <p>
* Null values are not supported.
*/
@NonNull
public static final NavType<Integer> ReferenceType = new NavType<Integer>(false) {
@Override
public void put(@NonNull Bundle bundle, @NonNull String key,
@NonNull @AnyRes Integer value) {
bundle.putInt(key, value);
}
@AnyRes
@Override
public Integer get(@NonNull Bundle bundle, @NonNull String key) {
return (Integer) bundle.get(key);
}
@NonNull
@Override
public Integer parseValue(@NonNull String value) {
throw new UnsupportedOperationException(
"References don't support parsing string values.");
}
@NonNull
@Override
public String getName() {
return "reference";
}
};
/**
* NavType for storing integer arrays,
* corresponding with the "integer[]" type in a Navigation XML file.
* <p>
* Null values are supported.
* Default values in Navigation XML files are not supported.
*/
@NonNull
public static final NavType<int[]> IntArrayType = new NavType<int[]>(true) {
@Override
public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable int[] value) {
bundle.putIntArray(key, value);
}
@Override
public int[] get(@NonNull Bundle bundle, @NonNull String key) {
return (int[]) bundle.get(key);
}
@NonNull
@Override
public int[] parseValue(@NonNull String value) {
throw new UnsupportedOperationException("Arrays don't support default values.");
}
@NonNull
@Override
public String getName() {
return "integer[]";
}
};
/**
* NavType for storing long values,
* corresponding with the "long" type in a Navigation XML file.
* <p>
* Null values are not supported.
* Default values for this type in Navigation XML files must always end with an 'L' suffix, e.g.
* `app:defaultValue="123L"`.
*/
@NonNull
public static final NavType<Long> LongType = new NavType<Long>(false) {
@Override
public void put(@NonNull Bundle bundle, @NonNull String key, @NonNull Long value) {
bundle.putLong(key, value);
}
@Override
public Long get(@NonNull Bundle bundle, @NonNull String key) {
return (Long) bundle.get(key);
}
@NonNull
@Override
public Long parseValue(@NonNull String value) {
//At runtime the L suffix is optional, contrary to the Safe Args plugin.
//This is in order to be able to parse long numbers passed as deep link URL parameters
if (value.endsWith("L")) {
value = value.substring(0, value.length() - 1);
}
if (value.startsWith("0x")) {
return Long.parseLong(value.substring(2), 16);
} else {
return Long.parseLong(value);
}
}
@NonNull
@Override
public String getName() {
return "long";
}
};
/**
* NavType for storing long arrays,
* corresponding with the "long[]" type in a Navigation XML file.
* <p>
* Null values are supported.
* Default values in Navigation XML files are not supported.
*/
@NonNull
public static final NavType<long[]> LongArrayType = new NavType<long[]>(true) {
@Override
public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable long[] value) {
bundle.putLongArray(key, value);
}
@Override
public long[] get(@NonNull Bundle bundle, @NonNull String key) {
return (long[]) bundle.get(key);
}
@NonNull
@Override
public long[] parseValue(@NonNull String value) {
throw new UnsupportedOperationException("Arrays don't support default values.");
}
@NonNull
@Override
public String getName() {
return "long[]";
}
};
/**
* NavType for storing float values,
* corresponding with the "float" type in a Navigation XML file.
* <p>
* Null values are not supported.
*/
@NonNull
public static final NavType<Float> FloatType = new NavType<Float>(false) {
@Override
public void put(@NonNull Bundle bundle, @NonNull String key, @NonNull Float value) {
bundle.putFloat(key, value);
}
@Override
public Float get(@NonNull Bundle bundle, @NonNull String key) {
return (Float) bundle.get(key);
}
@NonNull
@Override
public Float parseValue(@NonNull String value) {
return Float.parseFloat(value);
}
@NonNull
@Override
public String getName() {
return "float";
}
};
/**
* NavType for storing float arrays,
* corresponding with the "float[]" type in a Navigation XML file.
* <p>
* Null values are supported.
* Default values in Navigation XML files are not supported.
*/
@NonNull
public static final NavType<float[]> FloatArrayType = new NavType<float[]>(true) {
@Override
public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable float[] value) {
bundle.putFloatArray(key, value);
}
@Override
public float[] get(@NonNull Bundle bundle, @NonNull String key) {
return (float[]) bundle.get(key);
}
@NonNull
@Override
public float[] parseValue(@NonNull String value) {
throw new UnsupportedOperationException("Arrays don't support default values.");
}
@NonNull
@Override
public String getName() {
return "float[]";
}
};
/**
* NavType for storing boolean values,
* corresponding with the "boolean" type in a Navigation XML file.
* <p>
* Null values are not supported.
*/
@NonNull
public static final NavType<Boolean> BoolType = new NavType<Boolean>(false) {
@Override
public void put(@NonNull Bundle bundle, @NonNull String key, @NonNull Boolean value) {
bundle.putBoolean(key, value);
}
@Override
public Boolean get(@NonNull Bundle bundle, @NonNull String key) {
return (Boolean) bundle.get(key);
}
@NonNull
@Override
public Boolean parseValue(@NonNull String value) {
if ("true".equals(value)) {
return true;
} else if ("false".equals(value)) {
return false;
} else {
throw new IllegalArgumentException(
"A boolean NavType only accepts \"true\" or \"false\" values.");
}
}
@NonNull
@Override
public String getName() {
return "boolean";
}
};
/**
* NavType for storing boolean arrays,
* corresponding with the "boolean[]" type in a Navigation XML file.
* <p>
* Null values are supported.
* Default values in Navigation XML files are not supported.
*/
@NonNull
public static final NavType<boolean[]> BoolArrayType = new NavType<boolean[]>(true) {
@Override
public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable boolean[] value) {
bundle.putBooleanArray(key, value);
}
@Override
public boolean[] get(@NonNull Bundle bundle, @NonNull String key) {
return (boolean[]) bundle.get(key);
}
@NonNull
@Override
public boolean[] parseValue(@NonNull String value) {
throw new UnsupportedOperationException("Arrays don't support default values.");
}
@NonNull
@Override
public String getName() {
return "boolean[]";
}
};
/**
* NavType for storing String values,
* corresponding with the "string" type in a Navigation XML file.
* <p>
* Null values are supported.
*/
@NonNull
public static final NavType<String> StringType = new NavType<String>(true) {
@Override
public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable String value) {
bundle.putString(key, value);
}
@Override
public String get(@NonNull Bundle bundle, @NonNull String key) {
return (String) bundle.get(key);
}
@NonNull
@Override
public String parseValue(@NonNull String value) {
return value;
}
@NonNull
@Override
public String getName() {
return "string";
}
};
/**
* NavType for storing String arrays,
* corresponding with the "string[]" type in a Navigation XML file.
* <p>
* Null values are supported.
* Default values in Navigation XML files are not supported.
*/
@NonNull
public static final NavType<String[]> StringArrayType = new NavType<String[]>(true) {
@Override
public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable String[] value) {
bundle.putStringArray(key, value);
}
@Override
public String[] get(@NonNull Bundle bundle, @NonNull String key) {
return (String[]) bundle.get(key);
}
@NonNull
@Override
public String[] parseValue(@NonNull String value) {
throw new UnsupportedOperationException("Arrays don't support default values.");
}
@NonNull
@Override
public String getName() {
return "string[]";
}
};
/**
* ParcelableType is used for passing Parcelables in {@link NavArgument}s.
* <p>
* Null values are supported.
* Default values in Navigation XML files are not supported.
*
* @param <D> the Parcelable class that is supported by this NavType
*/
public static final class ParcelableType<D> extends NavType<D> {
@NonNull
private final Class<D> mType;
/**
* Constructs a NavType that supports a given Parcelable type.
* @param type class that is a subtype of Parcelable
*/
public ParcelableType(@NonNull Class<D> type) {
super(true);
if (!Parcelable.class.isAssignableFrom(type)
&& !Serializable.class.isAssignableFrom(type)) {
throw new IllegalArgumentException(
type + " does not implement Parcelable or Serializable.");
}
this.mType = type;
}
@Override
public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable D value) {
mType.cast(value);
if (value == null || value instanceof Parcelable) {
bundle.putParcelable(key, (Parcelable) value);
} else if (value instanceof Serializable) {
bundle.putSerializable(key, (Serializable) value);
}
}
@SuppressWarnings("unchecked")
@Override
@Nullable
public D get(@NonNull Bundle bundle, @NonNull String key) {
return (D) bundle.get(key);
}
@NonNull
@Override
public D parseValue(@NonNull String value) {
throw new UnsupportedOperationException("Parcelables don't support default values.");
}
@Override
@NonNull
public String getName() {
return mType.getName();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ParcelableType<?> that = (ParcelableType<?>) o;
return mType.equals(that.mType);
}
@Override
public int hashCode() {
return mType.hashCode();
}
}
/**
* ParcelableArrayType is used for {@link NavArgument}s which hold arrays of Parcelables.
* <p>
* Null values are supported.
* Default values in Navigation XML files are not supported.
*
* @param <D> the type of Parcelable component class of the array
*/
public static final class ParcelableArrayType<D extends Parcelable> extends NavType<D[]> {
@NonNull
private final Class<D[]> mArrayType;
/**
* Constructs a NavType that supports arrays of a given Parcelable type.
* @param type class that is a subtype of Parcelable
*/
@SuppressWarnings("unchecked")
public ParcelableArrayType(@NonNull Class<D> type) {
super(true);
if (!Parcelable.class.isAssignableFrom(type)) {
throw new IllegalArgumentException(
type + " does not implement Parcelable.");
}
Class<D[]> arrayType;
try {
arrayType = (Class<D[]>) Class.forName("[L" + type.getName() + ";");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e); //should never happen
}
this.mArrayType = arrayType;
}
@Override
public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable D[] value) {
mArrayType.cast(value);
bundle.putParcelableArray(key, value);
}
@SuppressWarnings("unchecked")
@Override
@Nullable
public D[] get(@NonNull Bundle bundle, @NonNull String key) {
return (D[]) bundle.get(key);
}
@NonNull
@Override
public D[] parseValue(@NonNull String value) {
throw new UnsupportedOperationException("Arrays don't support default values.");
}
@Override
@NonNull
public String getName() {
return mArrayType.getName();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ParcelableArrayType<?> that = (ParcelableArrayType<?>) o;
return mArrayType.equals(that.mArrayType);
}
@Override
public int hashCode() {
return mArrayType.hashCode();
}
}
/**
* SerializableType is used for Serializable {@link NavArgument}s.
* For handling Enums you must use {@link EnumType} instead.
* <p>
* Null values are supported.
* Default values in Navigation XML files are not supported.
*
* @param <D> the Serializable class that is supported by this NavType
* @see EnumType
*/
public static class SerializableType<D extends Serializable> extends NavType<D> {
@NonNull
private final Class<D> mType;
/**
* Constructs a NavType that supports a given Serializable type.
* @param type class that is a subtype of Serializable
*/
public SerializableType(@NonNull Class<D> type) {
super(true);
if (!Serializable.class.isAssignableFrom(type)) {
throw new IllegalArgumentException(
type + " does not implement Serializable.");
}
if (type.isEnum()) {
throw new IllegalArgumentException(
type + " is an Enum. You should use EnumType instead.");
}
this.mType = type;
}
SerializableType(boolean nullableAllowed, @NonNull Class<D> type) {
super(nullableAllowed);
if (!Serializable.class.isAssignableFrom(type)) {
throw new IllegalArgumentException(
type + " does not implement Serializable.");
}
this.mType = type;
}
@Override
public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable D value) {
mType.cast(value);
bundle.putSerializable(key, value);
}
@SuppressWarnings("unchecked")
@Override
@Nullable
public D get(@NonNull Bundle bundle, @NonNull String key) {
return (D) bundle.get(key);
}
@NonNull
@Override
public D parseValue(@NonNull String value) {
throw new UnsupportedOperationException("Serializables don't support default values.");
}
@Override
@NonNull
public String getName() {
return mType.getName();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof SerializableType)) return false;
SerializableType<?> that = (SerializableType<?>) o;
return mType.equals(that.mType);
}
@Override
public int hashCode() {
return mType.hashCode();
}
}
/**
* EnumType is used for {@link NavArgument}s holding enum values.
* <p>
* Null values are not supported.
* To specify a default value in a Navigation XML file, simply use the enum constant
* without the class name, e.g. `app:defaultValue="MONDAY"`.
*
* @param <D> the Enum class that is supported by this NavType
*/
public static final class EnumType<D extends Enum> extends SerializableType<D> {
@NonNull
private final Class<D> mType;
/**
* Constructs a NavType that supports a given Enum type.
* @param type class that is an Enum
*/
public EnumType(@NonNull Class<D> type) {
super(false, type);
if (!type.isEnum()) {
throw new IllegalArgumentException(
type + " is not an Enum type.");
}
mType = type;
}
@SuppressWarnings("unchecked")
@NonNull
@Override
public D parseValue(@NonNull String value) {
for (Object constant : mType.getEnumConstants()) {
if (((Enum) constant).name().equals(value)) {
return (D) constant;
}
}
throw new IllegalArgumentException("Enum value " + value + " not found for type "
+ mType.getName() + ".");
}
@Override
@NonNull
public String getName() {
return mType.getName();
}
}
/**
* SerializableArrayType is used for {@link NavArgument}s that hold arrays of Serializables.
* This type also supports arrays of Enums.
* <p>
* Null values are supported.
* Default values in Navigation XML files are not supported.
*
* @param <D> the Serializable component class of the array
*/
public static final class SerializableArrayType<D extends Serializable> extends NavType<D[]> {
@NonNull
private final Class<D[]> mArrayType;
/**
* Constructs a NavType that supports arrays of a given Serializable type.
* @param type class that is a subtype of Serializable
*/
@SuppressWarnings("unchecked")
public SerializableArrayType(@NonNull Class<D> type) {
super(true);
if (!Serializable.class.isAssignableFrom(type)) {
throw new IllegalArgumentException(
type + " does not implement Serializable.");
}
Class<D[]> arrayType;
try {
arrayType = (Class<D[]>) Class.forName("[L" + type.getName() + ";");
} catch (ClassNotFoundException e) {
throw new RuntimeException(e); //should never happen
}
this.mArrayType = arrayType;
}
@Override
public void put(@NonNull Bundle bundle, @NonNull String key, @Nullable D[] value) {
mArrayType.cast(value);
bundle.putSerializable(key, value);
}
@SuppressWarnings("unchecked")
@Override
@Nullable
public D[] get(@NonNull Bundle bundle, @NonNull String key) {
return (D[]) bundle.get(key);
}
@NonNull
@Override
public D[] parseValue(@NonNull String value) {
throw new UnsupportedOperationException("Arrays don't support default values.");
}
@Override
@NonNull
public String getName() {
return mArrayType.getName();
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
SerializableArrayType<?> that = (SerializableArrayType<?>) o;
return mArrayType.equals(that.mArrayType);
}
@Override
public int hashCode() {
return mArrayType.hashCode();
}
}
}