Merge "Make res.Configuration support locale lists."
This commit is contained in:
committed by
Android (Google) Code Review
commit
cdc5673633
@@ -9663,12 +9663,14 @@ package android.content.res {
|
||||
method public int diff(android.content.res.Configuration);
|
||||
method public boolean equals(android.content.res.Configuration);
|
||||
method public int getLayoutDirection();
|
||||
method public android.util.LocaleList getLocales();
|
||||
method public boolean isLayoutSizeAtLeast(int);
|
||||
method public boolean isScreenRound();
|
||||
method public static boolean needNewResources(int, int);
|
||||
method public void readFromParcel(android.os.Parcel);
|
||||
method public void setLayoutDirection(java.util.Locale);
|
||||
method public void setLocale(java.util.Locale);
|
||||
method public void setLocales(android.util.LocaleList);
|
||||
method public void setTo(android.content.res.Configuration);
|
||||
method public void setToDefaults();
|
||||
method public int updateFrom(android.content.res.Configuration);
|
||||
@@ -9742,7 +9744,7 @@ package android.content.res {
|
||||
field public int hardKeyboardHidden;
|
||||
field public int keyboard;
|
||||
field public int keyboardHidden;
|
||||
field public java.util.Locale locale;
|
||||
field public deprecated java.util.Locale locale;
|
||||
field public int mcc;
|
||||
field public int mnc;
|
||||
field public int navigation;
|
||||
@@ -34201,11 +34203,15 @@ package android.util {
|
||||
|
||||
public final class LocaleList {
|
||||
ctor public LocaleList();
|
||||
ctor public LocaleList(java.util.Locale);
|
||||
ctor public LocaleList(java.util.Locale[]);
|
||||
method public static android.util.LocaleList forLanguageTags(java.lang.String);
|
||||
method public java.util.Locale get(int);
|
||||
method public static android.util.LocaleList getEmptyLocaleList();
|
||||
method public java.util.Locale getPrimary();
|
||||
method public boolean isEmpty();
|
||||
method public int size();
|
||||
method public java.lang.String toLanguageTags();
|
||||
}
|
||||
|
||||
public final class Log {
|
||||
|
||||
@@ -10000,12 +10000,14 @@ package android.content.res {
|
||||
method public int diff(android.content.res.Configuration);
|
||||
method public boolean equals(android.content.res.Configuration);
|
||||
method public int getLayoutDirection();
|
||||
method public android.util.LocaleList getLocales();
|
||||
method public boolean isLayoutSizeAtLeast(int);
|
||||
method public boolean isScreenRound();
|
||||
method public static boolean needNewResources(int, int);
|
||||
method public void readFromParcel(android.os.Parcel);
|
||||
method public void setLayoutDirection(java.util.Locale);
|
||||
method public void setLocale(java.util.Locale);
|
||||
method public void setLocales(android.util.LocaleList);
|
||||
method public void setTo(android.content.res.Configuration);
|
||||
method public void setToDefaults();
|
||||
method public int updateFrom(android.content.res.Configuration);
|
||||
@@ -10079,7 +10081,7 @@ package android.content.res {
|
||||
field public int hardKeyboardHidden;
|
||||
field public int keyboard;
|
||||
field public int keyboardHidden;
|
||||
field public java.util.Locale locale;
|
||||
field public deprecated java.util.Locale locale;
|
||||
field public int mcc;
|
||||
field public int mnc;
|
||||
field public int navigation;
|
||||
@@ -36495,11 +36497,15 @@ package android.util {
|
||||
|
||||
public final class LocaleList {
|
||||
ctor public LocaleList();
|
||||
ctor public LocaleList(java.util.Locale);
|
||||
ctor public LocaleList(java.util.Locale[]);
|
||||
method public static android.util.LocaleList forLanguageTags(java.lang.String);
|
||||
method public java.util.Locale get(int);
|
||||
method public static android.util.LocaleList getEmptyLocaleList();
|
||||
method public java.util.Locale getPrimary();
|
||||
method public boolean isEmpty();
|
||||
method public int size();
|
||||
method public java.lang.String toLanguageTags();
|
||||
}
|
||||
|
||||
public final class Log {
|
||||
|
||||
@@ -22,11 +22,13 @@ import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
import org.xmlpull.v1.XmlSerializer;
|
||||
|
||||
import android.annotation.Nullable;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.os.Build;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.LocaleList;
|
||||
import android.view.View;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -36,7 +38,7 @@ import java.util.Locale;
|
||||
/**
|
||||
* This class describes all device configuration information that can
|
||||
* impact the resources the application retrieves. This includes both
|
||||
* user-specified configuration options (locale and scaling) as well
|
||||
* user-specified configuration options (locale list and scaling) as well
|
||||
* as device configurations (such as input modes, screen size and screen orientation).
|
||||
* <p>You can acquire this object from {@link Resources}, using {@link
|
||||
* Resources#getConfiguration}. Thus, from an activity, you can get it by chaining the request
|
||||
@@ -78,8 +80,13 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
* Current user preference for the locale, corresponding to
|
||||
* <a href="{@docRoot}guide/topics/resources/providing-resources.html#LocaleQualifier">locale</a>
|
||||
* resource qualifier.
|
||||
*
|
||||
* @deprecated Do not set or read this directly. Use {@link #getLocales()} and
|
||||
* {@link #setLocales(LocaleList)}.
|
||||
*/
|
||||
public Locale locale;
|
||||
@Deprecated public Locale locale;
|
||||
|
||||
private LocaleList mLocaleList;
|
||||
|
||||
/**
|
||||
* Locale should persist on setting. This is hidden because it is really
|
||||
@@ -648,6 +655,15 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
setTo(o);
|
||||
}
|
||||
|
||||
/* This brings mLocaleList in sync with locale in case a user of the older API who doesn't know
|
||||
* about setLocales() has changed locale directly. */
|
||||
private void fixUpLocaleList() {
|
||||
if ((locale == null && !mLocaleList.isEmpty()) ||
|
||||
(locale != null && !locale.equals(mLocaleList.getPrimary()))) {
|
||||
mLocaleList = new LocaleList(locale);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTo(Configuration o) {
|
||||
fontScale = o.fontScale;
|
||||
mcc = o.mcc;
|
||||
@@ -655,6 +671,8 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
if (o.locale != null) {
|
||||
locale = (Locale) o.locale.clone();
|
||||
}
|
||||
o.fixUpLocaleList();
|
||||
mLocaleList = o.mLocaleList;
|
||||
userSetLocale = o.userSetLocale;
|
||||
touchscreen = o.touchscreen;
|
||||
keyboard = o.keyboard;
|
||||
@@ -692,11 +710,12 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
} else {
|
||||
sb.append("?mnc");
|
||||
}
|
||||
if (locale != null) {
|
||||
fixUpLocaleList();
|
||||
if (!mLocaleList.isEmpty()) {
|
||||
sb.append(" ");
|
||||
sb.append(locale);
|
||||
sb.append(mLocaleList);
|
||||
} else {
|
||||
sb.append(" ?locale");
|
||||
sb.append(" ?localeList");
|
||||
}
|
||||
int layoutDir = (screenLayout&SCREENLAYOUT_LAYOUTDIR_MASK);
|
||||
switch (layoutDir) {
|
||||
@@ -819,6 +838,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
public void setToDefaults() {
|
||||
fontScale = 1;
|
||||
mcc = mnc = 0;
|
||||
mLocaleList = LocaleList.getEmptyLocaleList();
|
||||
locale = null;
|
||||
userSetLocale = false;
|
||||
touchscreen = TOUCHSCREEN_UNDEFINED;
|
||||
@@ -864,16 +884,20 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
changed |= ActivityInfo.CONFIG_MNC;
|
||||
mnc = delta.mnc;
|
||||
}
|
||||
if (delta.locale != null
|
||||
&& (locale == null || !locale.equals(delta.locale))) {
|
||||
fixUpLocaleList();
|
||||
delta.fixUpLocaleList();
|
||||
if (!delta.mLocaleList.isEmpty() && !mLocaleList.equals(delta.mLocaleList)) {
|
||||
changed |= ActivityInfo.CONFIG_LOCALE;
|
||||
locale = delta.locale != null
|
||||
? (Locale) delta.locale.clone() : null;
|
||||
// If locale has changed, then layout direction is also changed ...
|
||||
changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
|
||||
// ... and we need to update the layout direction (represented by the first
|
||||
// 2 most significant bits in screenLayout).
|
||||
setLayoutDirection(locale);
|
||||
mLocaleList = delta.mLocaleList;
|
||||
// delta.locale can't be null, since delta.mLocaleList is not empty.
|
||||
if (!delta.locale.equals(locale)) {
|
||||
locale = (Locale) delta.locale.clone();
|
||||
// If locale has changed, then layout direction is also changed ...
|
||||
changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
|
||||
// ... and we need to update the layout direction (represented by the first
|
||||
// 2 most significant bits in screenLayout).
|
||||
setLayoutDirection(locale);
|
||||
}
|
||||
}
|
||||
final int deltaScreenLayoutDir = delta.screenLayout & SCREENLAYOUT_LAYOUTDIR_MASK;
|
||||
if (deltaScreenLayoutDir != SCREENLAYOUT_LAYOUTDIR_UNDEFINED &&
|
||||
@@ -1023,8 +1047,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
if (delta.mnc != 0 && mnc != delta.mnc) {
|
||||
changed |= ActivityInfo.CONFIG_MNC;
|
||||
}
|
||||
if (delta.locale != null
|
||||
&& (locale == null || !locale.equals(delta.locale))) {
|
||||
fixUpLocaleList();
|
||||
delta.fixUpLocaleList();
|
||||
if (!mLocaleList.equals(delta.mLocaleList)) {
|
||||
changed |= ActivityInfo.CONFIG_LOCALE;
|
||||
changed |= ActivityInfo.CONFIG_LAYOUT_DIRECTION;
|
||||
}
|
||||
@@ -1146,14 +1171,15 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
dest.writeFloat(fontScale);
|
||||
dest.writeInt(mcc);
|
||||
dest.writeInt(mnc);
|
||||
if (locale == null) {
|
||||
dest.writeInt(0);
|
||||
} else {
|
||||
dest.writeInt(1);
|
||||
dest.writeString(locale.getLanguage());
|
||||
dest.writeString(locale.getCountry());
|
||||
dest.writeString(locale.getVariant());
|
||||
|
||||
fixUpLocaleList();
|
||||
final int localeListSize = mLocaleList.size();
|
||||
dest.writeInt(localeListSize);
|
||||
for (int i = 0; i < localeListSize; ++i) {
|
||||
final Locale l = mLocaleList.get(i);
|
||||
dest.writeString(l.toLanguageTag());
|
||||
}
|
||||
|
||||
if(userSetLocale) {
|
||||
dest.writeInt(1);
|
||||
} else {
|
||||
@@ -1182,10 +1208,15 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
fontScale = source.readFloat();
|
||||
mcc = source.readInt();
|
||||
mnc = source.readInt();
|
||||
if (source.readInt() != 0) {
|
||||
locale = new Locale(source.readString(), source.readString(),
|
||||
source.readString());
|
||||
|
||||
final int localeListSize = source.readInt();
|
||||
final Locale[] localeArray = new Locale[localeListSize];
|
||||
for (int i = 0; i < localeListSize; ++i) {
|
||||
localeArray[i] = Locale.forLanguageTag(source.readString());
|
||||
}
|
||||
mLocaleList = new LocaleList(localeArray);
|
||||
locale = mLocaleList.getPrimary();
|
||||
|
||||
userSetLocale = (source.readInt()==1);
|
||||
touchscreen = source.readInt();
|
||||
keyboard = source.readInt();
|
||||
@@ -1234,18 +1265,33 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
if (n != 0) return n;
|
||||
n = this.mnc - that.mnc;
|
||||
if (n != 0) return n;
|
||||
if (this.locale == null) {
|
||||
if (that.locale != null) return 1;
|
||||
} else if (that.locale == null) {
|
||||
|
||||
fixUpLocaleList();
|
||||
that.fixUpLocaleList();
|
||||
// for backward compatibility, we consider an empty locale list to be greater
|
||||
// than any non-empty locale list.
|
||||
if (this.mLocaleList.isEmpty()) {
|
||||
if (!that.mLocaleList.isEmpty()) return 1;
|
||||
} else if (that.mLocaleList.isEmpty()) {
|
||||
return -1;
|
||||
} else {
|
||||
n = this.locale.getLanguage().compareTo(that.locale.getLanguage());
|
||||
if (n != 0) return n;
|
||||
n = this.locale.getCountry().compareTo(that.locale.getCountry());
|
||||
if (n != 0) return n;
|
||||
n = this.locale.getVariant().compareTo(that.locale.getVariant());
|
||||
final int minSize = Math.min(this.mLocaleList.size(), that.mLocaleList.size());
|
||||
for (int i = 0; i < minSize; ++i) {
|
||||
final Locale thisLocale = this.mLocaleList.get(i);
|
||||
final Locale thatLocale = that.mLocaleList.get(i);
|
||||
n = thisLocale.getLanguage().compareTo(thatLocale.getLanguage());
|
||||
if (n != 0) return n;
|
||||
n = thisLocale.getCountry().compareTo(thatLocale.getCountry());
|
||||
if (n != 0) return n;
|
||||
n = thisLocale.getVariant().compareTo(thatLocale.getVariant());
|
||||
if (n != 0) return n;
|
||||
n = thisLocale.toLanguageTag().compareTo(thatLocale.toLanguageTag());
|
||||
if (n != 0) return n;
|
||||
}
|
||||
n = this.mLocaleList.size() - that.mLocaleList.size();
|
||||
if (n != 0) return n;
|
||||
}
|
||||
|
||||
n = this.touchscreen - that.touchscreen;
|
||||
if (n != 0) return n;
|
||||
n = this.keyboard - that.keyboard;
|
||||
@@ -1288,13 +1334,13 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
result = 31 * result + Float.floatToIntBits(fontScale);
|
||||
result = 31 * result + mcc;
|
||||
result = 31 * result + mnc;
|
||||
result = 31 * result + (locale != null ? locale.hashCode() : 0);
|
||||
result = 31 * result + mLocaleList.hashCode();
|
||||
result = 31 * result + touchscreen;
|
||||
result = 31 * result + keyboard;
|
||||
result = 31 * result + keyboardHidden;
|
||||
@@ -1312,14 +1358,47 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the locale. This is the preferred way for setting up the locale (instead of using the
|
||||
* direct accessor). This will also set the layout direction according to the locale.
|
||||
* Get the locale list. This is the preferred way for getting the locales (instead of using
|
||||
* the direct accessor to {@link #locale}, which would only provide the primary locale).
|
||||
*
|
||||
* @return The locale list.
|
||||
*/
|
||||
public LocaleList getLocales() {
|
||||
fixUpLocaleList();
|
||||
return mLocaleList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the locale list. This is the preferred way for setting up the locales (instead of using
|
||||
* the direct accessor or {@link #setLocale(Locale)}). This will also set the layout direction
|
||||
* according to the first locale in the list.
|
||||
*
|
||||
* Note that the layout direction will always come from the first locale in the locale list,
|
||||
* even if the locale is not supported by the resources (the resources may only support
|
||||
* another locale further down the list which has a different direction).
|
||||
*
|
||||
* @param locales The locale list. If null, an empty LocaleList will be assigned.
|
||||
*/
|
||||
public void setLocales(@Nullable LocaleList locales) {
|
||||
mLocaleList = locales == null ? LocaleList.getEmptyLocaleList() : locales;
|
||||
locale = mLocaleList.getPrimary();
|
||||
setLayoutDirection(locale);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the locale list to a list of just one locale. This will also set the layout direction
|
||||
* according to the locale.
|
||||
*
|
||||
* Note that after this is run, calling <code>.equals()</code> on the input locale and the
|
||||
* {@link #locale} attribute would return <code>true</code> if they are not null, but there is
|
||||
* no guarantee that they would be the same object.
|
||||
*
|
||||
* See also the note about layout direction in {@link #setLocales(LocaleList)}.
|
||||
*
|
||||
* @param loc The locale. Can be null.
|
||||
*/
|
||||
public void setLocale(Locale loc) {
|
||||
locale = loc;
|
||||
setLayoutDirection(locale);
|
||||
public void setLocale(@Nullable Locale loc) {
|
||||
setLocales(new LocaleList(loc));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1335,19 +1414,19 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the layout direction from the Locale.
|
||||
* Set the layout direction from a Locale.
|
||||
*
|
||||
* @param locale The Locale. If null will set the layout direction to
|
||||
* @param loc The Locale. If null will set the layout direction to
|
||||
* {@link View#LAYOUT_DIRECTION_LTR}. If not null will set it to the layout direction
|
||||
* corresponding to the Locale.
|
||||
*
|
||||
* @see View#LAYOUT_DIRECTION_LTR
|
||||
* @see View#LAYOUT_DIRECTION_RTL
|
||||
*/
|
||||
public void setLayoutDirection(Locale locale) {
|
||||
public void setLayoutDirection(Locale loc) {
|
||||
// There is a "1" difference between the configuration values for
|
||||
// layout direction and View constants for layout direction, just add "1".
|
||||
final int layoutDirection = 1 + TextUtils.getLayoutDirectionFromLocale(locale);
|
||||
final int layoutDirection = 1 + TextUtils.getLayoutDirectionFromLocale(loc);
|
||||
screenLayout = (screenLayout&~SCREENLAYOUT_LAYOUTDIR_MASK)|
|
||||
(layoutDirection << SCREENLAYOUT_LAYOUTDIR_SHIFT);
|
||||
}
|
||||
@@ -1370,21 +1449,21 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public static String localeToResourceQualifier(Locale locale) {
|
||||
public static String localeToResourceQualifier(Locale loc) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean l = (locale.getLanguage().length() != 0);
|
||||
boolean c = (locale.getCountry().length() != 0);
|
||||
boolean s = (locale.getScript().length() != 0);
|
||||
boolean v = (locale.getVariant().length() != 0);
|
||||
|
||||
boolean l = (loc.getLanguage().length() != 0);
|
||||
boolean c = (loc.getCountry().length() != 0);
|
||||
boolean s = (loc.getScript().length() != 0);
|
||||
boolean v = (loc.getVariant().length() != 0);
|
||||
// TODO: take script and extensions into account
|
||||
if (l) {
|
||||
sb.append(locale.getLanguage());
|
||||
sb.append(loc.getLanguage());
|
||||
if (c) {
|
||||
sb.append("-r").append(locale.getCountry());
|
||||
sb.append("-r").append(loc.getCountry());
|
||||
if (s) {
|
||||
sb.append("-s").append(locale.getScript());
|
||||
sb.append("-s").append(loc.getScript());
|
||||
if (v) {
|
||||
sb.append("-v").append(locale.getVariant());
|
||||
sb.append("-v").append(loc.getVariant());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1409,6 +1488,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: send the whole locale list
|
||||
if (config.locale != null && !config.locale.getLanguage().isEmpty()) {
|
||||
parts.add(localeToResourceQualifier(config.locale));
|
||||
}
|
||||
@@ -1646,8 +1726,10 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
delta.mnc = change.mnc;
|
||||
}
|
||||
|
||||
if ((base.locale == null && change.locale != null) ||
|
||||
(base.locale != null && !base.locale.equals(change.locale))) {
|
||||
base.fixUpLocaleList();
|
||||
change.fixUpLocaleList();
|
||||
if (!base.mLocaleList.equals(change.mLocaleList)) {
|
||||
delta.mLocaleList = change.mLocaleList;
|
||||
delta.locale = change.locale;
|
||||
}
|
||||
|
||||
@@ -1724,7 +1806,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
private static final String XML_ATTR_FONT_SCALE = "fs";
|
||||
private static final String XML_ATTR_MCC = "mcc";
|
||||
private static final String XML_ATTR_MNC = "mnc";
|
||||
private static final String XML_ATTR_LOCALE = "locale";
|
||||
private static final String XML_ATTR_LOCALES = "locales";
|
||||
private static final String XML_ATTR_TOUCHSCREEN = "touch";
|
||||
private static final String XML_ATTR_KEYBOARD = "key";
|
||||
private static final String XML_ATTR_KEYBOARD_HIDDEN = "keyHid";
|
||||
@@ -1754,10 +1836,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
configOut.mcc = XmlUtils.readIntAttribute(parser, XML_ATTR_MCC, 0);
|
||||
configOut.mnc = XmlUtils.readIntAttribute(parser, XML_ATTR_MNC, 0);
|
||||
|
||||
final String localeStr = XmlUtils.readStringAttribute(parser, XML_ATTR_LOCALE);
|
||||
if (localeStr != null) {
|
||||
configOut.locale = Locale.forLanguageTag(localeStr);
|
||||
}
|
||||
final String localesStr = XmlUtils.readStringAttribute(parser, XML_ATTR_LOCALES);
|
||||
configOut.mLocaleList = LocaleList.forLanguageTags(localesStr);
|
||||
configOut.locale = configOut.mLocaleList.getPrimary();
|
||||
|
||||
configOut.touchscreen = XmlUtils.readIntAttribute(parser, XML_ATTR_TOUCHSCREEN,
|
||||
TOUCHSCREEN_UNDEFINED);
|
||||
@@ -1807,8 +1888,9 @@ public final class Configuration implements Parcelable, Comparable<Configuration
|
||||
if (config.mnc != 0) {
|
||||
XmlUtils.writeIntAttribute(xml, XML_ATTR_MNC, config.mnc);
|
||||
}
|
||||
if (config.locale != null) {
|
||||
XmlUtils.writeStringAttribute(xml, XML_ATTR_LOCALE, config.locale.toLanguageTag());
|
||||
config.fixUpLocaleList();
|
||||
if (!config.mLocaleList.isEmpty()) {
|
||||
XmlUtils.writeStringAttribute(xml, XML_ATTR_LOCALES, config.mLocaleList.toLanguageTags());
|
||||
}
|
||||
if (config.touchscreen != TOUCHSCREEN_UNDEFINED) {
|
||||
XmlUtils.writeIntAttribute(xml, XML_ATTR_TOUCHSCREEN, config.touchscreen);
|
||||
|
||||
@@ -23,8 +23,8 @@ import java.util.Locale;
|
||||
|
||||
// TODO: We don't except too many LocaleLists to exist at the same time, and
|
||||
// we need access to the data at native level, so we should pass the data
|
||||
// down to the native level, create a mapt of every list seen there, take a
|
||||
// pointer back, and just keep that pointed in the Java-level object, so
|
||||
// down to the native level, create a map of every list seen there, take a
|
||||
// pointer back, and just keep that pointer in the Java-level object, so
|
||||
// things could be copied very quickly.
|
||||
|
||||
/**
|
||||
@@ -34,6 +34,7 @@ import java.util.Locale;
|
||||
public final class LocaleList {
|
||||
private final Locale[] mList;
|
||||
private static final Locale[] sEmptyList = new Locale[0];
|
||||
private static final LocaleList sEmptyLocaleList = new LocaleList();
|
||||
|
||||
public Locale get(int location) {
|
||||
return location < mList.length ? mList[location] : null;
|
||||
@@ -51,10 +52,77 @@ public final class LocaleList {
|
||||
return mList.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
if (other == this)
|
||||
return true;
|
||||
if (!(other instanceof LocaleList))
|
||||
return false;
|
||||
final Locale[] otherList = ((LocaleList) other).mList;
|
||||
if (mList.length != otherList.length)
|
||||
return false;
|
||||
for (int i = 0; i < mList.length; ++i) {
|
||||
if (!mList[i].equals(otherList[i]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 1;
|
||||
for (int i = 0; i < mList.length; ++i) {
|
||||
result = 31 * result + mList[i].hashCode();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[");
|
||||
for (int i = 0; i < mList.length; ++i) {
|
||||
sb.append(mList[i]);
|
||||
if (i < mList.length - 1) {
|
||||
sb.append(',');
|
||||
}
|
||||
}
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String toLanguageTags() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < mList.length; ++i) {
|
||||
sb.append(mList[i].toLanguageTag());
|
||||
if (i < mList.length - 1) {
|
||||
sb.append(',');
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* It is almost always better to call {@link #getEmptyLocaleList()} instead which returns
|
||||
* a pre-constructed empty locale list.
|
||||
*/
|
||||
public LocaleList() {
|
||||
mList = sEmptyList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException if any of the input locales is <code>null</code>.
|
||||
* @throws IllegalArgumentException if any of the input locales repeat.
|
||||
*/
|
||||
public LocaleList(@Nullable Locale locale) {
|
||||
if (locale == null) {
|
||||
mList = sEmptyList;
|
||||
} else {
|
||||
mList = new Locale[1];
|
||||
mList[0] = (Locale) locale.clone();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws NullPointerException if any of the input locales is <code>null</code>.
|
||||
* @throws IllegalArgumentException if any of the input locales repeat.
|
||||
@@ -79,4 +147,21 @@ public final class LocaleList {
|
||||
mList = localeList;
|
||||
}
|
||||
}
|
||||
|
||||
public static LocaleList getEmptyLocaleList() {
|
||||
return sEmptyLocaleList;
|
||||
}
|
||||
|
||||
public static LocaleList forLanguageTags(@Nullable String list) {
|
||||
if (list == null || list.equals("")) {
|
||||
return getEmptyLocaleList();
|
||||
} else {
|
||||
final String[] tags = list.split(",");
|
||||
final Locale[] localeArray = new Locale[tags.length];
|
||||
for (int i = 0; i < localeArray.length; ++i) {
|
||||
localeArray[i] = Locale.forLanguageTag(tags[i]);
|
||||
}
|
||||
return new LocaleList(localeArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user