Разработайте приложение Android для поддержки английского и арабского "выравнивания компоновки",
Я разрабатываю Android-приложение для поддержки как En/Ar. Но я столкнулся с проблемой, что, если пользователь изменится с En на Ar, выравнивание пользовательского интерфейса должно перейти от "слева направо" на "справа налево".
Пример: (TextView) (EditText), это в En
Но в Ar это должно быть: (EditText) (TextView).
Есть ли способ сделать это без создания двух разных макетов или двух разных версий?
Ответы
Ответ 1
Почему это невозможно сделать с двумя макетами (вы никогда не говорили, почему это нежелательно)? Как описано в документации разработчиков Android
Большая часть локализации приложения предоставляет альтернативу текст для разных языков. В некоторых случаях вы также альтернативная графика, звуки, макеты и другие локали ресурсы.
Приложение может указывать много каталогов res//, каждый с различными квалификаторами. Чтобы создать альтернативный ресурс для другой язык, вы используете классификатор, который указывает язык или языковая область.
Ссылка: http://developer.android.com/guide/topics/resources/localization.html
Итак, в вашем случае создайте res/layout-ar
, затем скопируйте существующий макет в эту папку, а затем просто поменяйте их. Простой, следует передовой практике и легко сделать. Это также облегчает дальнейшие изменения локализации без необходимости писать больше кода.
Если вам нужно написать код, вам нужно будет найти язык по умолчанию устройства, а затем поменять его на основе этого. Вы можете получить язык:
Locale.getDefault().getDisplayLanguage();
Подробнее см. этот вопрос: Получить текущий язык на устройстве
В заключительном личном примечании: я думаю, что первое намного лучше разделяет проблемы, так как код обеспечивает логику, а макеты XML фактически управляют макетом (при этом Android автоматически выбирает нужные ресурсы без необходимости писать больше код).
Ответ 2
Я попытался извлечь из этого ужас, создав набор пользовательских компонентов LabeledView
(для компонентов Form, таких как CheckBox
, EditText
и Spinners
). Эти представления (например, LabledEditText
) раздувают специфичный для региона макет и реализуют минимальный минимум вызовов, чтобы действовать как фасад (EditText
в этом случае).
res/layout/component_labeled_view.xml - [TextView][EditText]
res/layout-ar/component_labeled_view.xml - [EditText][TextView]
Сам класс View
содержит:
public LabeledEditText(Context context, AttributeSet attrs) {
super(context, attrs);
LayoutInflater inflator = LayoutInflater.from(context);
mContainer = inflator.inflate(R.layout.component_labeled_edittext, null);
mValueView = (EditText) mContainer.findViewById(R.id.editText);
mLabelTextView = (TextView) mContainer.findViewById(R.id.textView);
align(attrs);
}
public Editable getText() {
return ((EditText)mValueView).getText();
}
public void setText(String text) {
((EditText)mValueView).setText(text);
}
public void addTextChangedListener(TextWatcher watcher) {
((EditText)mValueView).addTextChangedListener(watcher);
}
Это должно по крайней мере сократить любое дублирование, так как теперь вы можете ссылаться на представление LabeledEditText
, а не на TextView
и EditText
.
В моей реализации, которую я не полностью показал, я сделал еще один шаг и создал абстрактный класс LabeledView
, который использует некоторые настраиваемые атрибуты, позволяющие мне настраивать как метку, так и значение в определенных ситуациях (см. align(attrs);
строка кода). В зависимости от того, насколько велико ваше приложение, вы можете попробовать что-то подобное?
Ответ 3
В Android 4.2 появилась встроенная поддержка макета "справа налево".
В AndroidManifest установлен андроид: поддерживает Rtl = "true" на уровне приложения, а в свойствах макета вместо начального/конечного свойств используются свойства left/right.
Вот видео с подробным объяснением: https://youtu.be/plW1qSGDSzs
Ответ 4
Почему бы просто не сделать TextView над EditText?