/* * Copyright 2020 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.car.app.model; import static androidx.annotation.RestrictTo.Scope.LIBRARY; import android.text.SpannableString; import android.text.Spanned; import androidx.annotation.Keep; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RestrictTo; import androidx.car.app.utils.CollectionUtils; import androidx.car.app.utils.StringUtils; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Objects; /** * A model that represents text to display in the car screen. * *
The Car App Library only supports a specific set of spans of type {@link CarSpan}. Further, * individual APIs in the library that take text as input may only support a certain subset of * {@link CarSpan}s. Spans that are not supported will be simply ignored by the host. * *
By default and unless explicitly documented in the individual APIs that take a text * parameter as input, spans for that API are not supported and will be ignored. * *
For example, the {@link Row.Builder#addText(CharSequence)} API documents that * {@link ForegroundCarColorSpan} instances can be used to color the text of the row. This means any * other types of spans except {@link ForegroundCarColorSpan} will be ignored. * *
{@link CarText} instances represent the text that was passed by the app through a * {@link CharSequence}, with the non-{@link CarSpan} spans removed. * *
The {@link CarText#toString} method can be used to get a string representation of the string,
* whereas the {@link CarText#toCharSequence()} method returns the reconstructed
* {@link CharSequence}, with the non{@link CarSpan} spans removed.
*
*/
public final class CarText {
@Keep
private final String mText;
@Keep
private final List Only {@link CarSpan} type spans are allowed in a {@link CarText}, other spans will be
* removed from the provided {@link CharSequence}.
*/
@NonNull
public static CarText create(@NonNull CharSequence text) {
return new CarText(text);
}
/** Returns whether the text string is empty. */
public boolean isEmpty() {
return mText.isEmpty();
}
@NonNull
@Override
public String toString() {
return mText;
}
/**
* Returns the {@link CharSequence} corresponding to this text.
*
* Spans that are not of type {@link CarSpan} that were passed when creating the
* {@link CarText} instance will not be present in the returned {@link CharSequence}.
*
* @see CarText#create(CharSequence)
*/
@NonNull
public CharSequence toCharSequence() {
SpannableString spannableString = new SpannableString(mText == null ? "" : mText);
for (SpanWrapper spanWrapper : CollectionUtils.emptyIfNull(mSpans)) {
spannableString.setSpan(
spanWrapper.getCarSpan(),
spanWrapper.getStart(),
spanWrapper.getEnd(),
spanWrapper.getFlags());
}
return spannableString;
}
/**
* Returns a shortened string from the input {@code text}.
*
* @hide
*/
@RestrictTo(LIBRARY)
@Nullable
public static String toShortString(@Nullable CarText text) {
return text == null ? null : StringUtils.shortenString(text.toString());
}
private CarText() {
mText = "";
mSpans = Collections.emptyList();
}
private CarText(CharSequence text) {
mText = text.toString();
List