Проблема смены раскладки в Android studio
Вопрос задан
Изменён 7 лет 4 месяца назад
Просмотрен 3k раз
Здравствуйте!
Постоянно такой косяк случается: набираю код, частенько меняю раскладку, и в какой-то момент она не хочет меняться обратно. Только при работе в Android studio.
Работаю под Windows`ом. Презапускаю среду, и все хорошо работает. Кто-нибудь сталкивался с подобным?
- android-studio
- android
0
На последних, на текущую дату, версиях Android Studio/IntelliJ IDEA мне не удалось воспроизвести данную проблему из чего можно подумать, что ее пофиксили.
Для ценителей раритетов или по другим причинам не имеющих возможности обновиться, существует очень простое решение:
В настройках переключения раскладок клавиатуры операционной системы повесить дополнительные комбинации на принудительное включение требуемых раскладок и пользоваться этими комбинациями, вместо Alt+Shift.
Для Windows8
Панель управления -> Язык -> Дополнительные параметры -> Переключение методов ввода -> Изменить сочетание клавиш языковой панели
Появится окно: Языки и службы текстового ввода.
Выбираете пункт: Включить Английский и нажимаете Сменить сочетание клавиш
Указываете удобное вам сочетание на ВКЛЮЧЕНИЕ английской раскладки.
То же самое делаете для русской раскладки.
В процессе работы пользуетесь обретенными комбинациями для ВКЛЮЧЕНИЯ нужной раскладки, а не переключения между ними.
Зарегистрируйтесь или войдите
Регистрация через GoogleРегистрация через Facebook
Регистрация через почту
Отправить без регистрации
Почта
Необходима, но никому не показывается
Отправить без регистрации
Почта
Необходима, но никому не показывается
Нажимая на кнопку «Отправить ответ», вы соглашаетесь с нашими пользовательским соглашением, политикой конфиденциальности и политикой о куки
Мысли на тему Как я перестал бояться и начал переводить android-приложения | все о настольных играх
Думаю, начало истории вы знаете – в феврале 2013 CGE анонсировали цифровую версию Galaxy Trucker, а в декабре 2014 она появилась в Google Play и единственным ее недостатком было отсутствие русского языка.
Никаких анонсов по поводу добавления языков не было, но когда я взглянул на содержание apk-файла поближе, то понял, что задел под другие языки есть – отдельная папка с названием localization_strings говорила об этом прямо и недвусмысленно.
Следует отметить, что перевод приложения – это далеко не то же самое, что перевод правил или даже пнп. Как с технической стороны, так и с точки зрения… скажем так, распространения. Если на «нелицензионный» перевод правил автор, скорее всего, закроет глаза (а то и поблагодарит), то выложенное для всеобщего скачивания переведенное приложения – откровенное пиратство. И если в случае ПК-версии можно извернуться каким-нибудь «русификатором» (тоже, строго говоря, сомнительным с точки зрения авторских прав), то с андроид-приложением этот вариант не пройдет.
В общем, исходя из этих соображений (а также в связи с тем, что я никогда не работал с андроид-приложениями), я решил пойти «официальным» путем и написал разработчикам, что, мол, так и так, hello from Russia, увлекаюсь настолками, попутно перевожу всякое, в том числе и к играм CGE, в частности, перевел правила ко всей линейке Galaxy Trucker, а тут у вас приложение вышло, хотите, помогу с переводом?
Через какое-то время пришел ответ «да, круто, мы думали переводить и на русский тоже, спасибо, если что – свяжемся». Получив пару таких писем выждав какое-то время, я понял, что не стоит ждать милостей от издателя, разобраться с приложением самостоятельно – вот наша задача.
Проблема первая – сборка-разборка
Первой задачей было не столько разборка (apk в общем случае открывается любым архиватором), сколько сборка приложения обратно в apk так, чтобы это все работало. Гугление дает довольно много инструкций по этому поводу, но почему-то в моем случае самые простые и популярные методы (Apktool, APK MultiTool, APK Studio, Eclipse, Android Studio и пр.) не сработали. Уж не знаю почему. А вот Virtuous Ten Studio справился (хотя я бы предпочел консольный apktool).
Про всякие подробности типа подписи приложения, генерации ключей и прочее рассказывать не буду – в сети все подробно расписано. Отмечу только, что мой скепсис касательно всяких программ для автоматического и полуавтоматического перевода apk-приложений оправдался… Хотя я понимаю, что случай не показательный, для перевода чего-нибудь попроще и постандартней они могут вполне подойти.
Проблема вторая – шрифты
Причем в данном случае это не только обычная «где бы взять такой же, но с кириллицей», а сам формат шрифта. В Galaxy Trucker используются bitmap-шрифты, то есть даже имея какой-нить ttf аналог с русскими буквами, его нельзя просто так взять и добавить в приложение. Проблема осложнялась тем, что bitmap-шрифты, как оказалось, бывают нескольких видов, а утилиты для работы с ними (в основном, самописные) заточены под конкретную программу, то есть на выходе получается что угодно кроме того, что понимает приложение. Плюс отсутствие внятных мануалов и полное отсутствие у меня опыта работы со шрифтами как таковыми. Но, тем не менее, потратив около трех дней на эксперименты и перелопатив тонны гугла (доходило даже до каких-то жутких софтин с корейских форумов) мне все же удалось заставить игру писать на русском.
Проблема третья – видеоролик
Я никогда раньше не работал с видео и не занимался озвучиванием. Но не оставлять же ролик на английском) Поэтому я решил, что лучшим выходом в этой ситуации будут субтитры. Правда, субтитры я тоже раньше не делал, но мне это показалось проще, чем писать отдельную дорожку, как-то вычищать оригинальную от английского голоса, сводить их и пр. Благо, что мануалов по сабам в сети тоже предостаточно. В общем, всего за сутки у меня получился ролик с хардсабами (вшитыми субтитрами), который не сильно превосходил размерами оригинальный и корректно проигрывался в приложении.
Итого – приложение распаковывается/запаковывается, русский шрифт есть, ролик на русском играется. «Дело за малым – просто перевести текст», – подумал я. Но я ошибся)
Во-первых, текста оказалось много. Очень много. По примерным подсчетам – почти в два раза больше, чем в допе к Space Alert (про перевод которого я писал в прошлый раз). Или почти столько же, сколько суммарно содержат правила базы и всех допов настольного Galaxy Tracker.
Во-вторых, рода и склонения. Если текст правил можно назвать статичным, то здесь построение фраз часто зависит от переменных типа «имя игрока», «пол игрока» или «количество чего-нибудь». В английском-то с этим проще, фразы вида [name]’s ship loses [n] crew members или It is [name]’s turn пишутся одинаково для любого имени и любого n. А в русском если 1, то астронавт, 2 или 4 – астронавта, а 5 или 8 – уже астронавтов. И если это Петя’s ход можно довольно безболезненно заменить на ходит Петя, то сделать Петин корабль/корабль Пети из имени Петя (причем так, чтобы одновременно с этим из Яна получался корабль Яны, из Олег – Олега, а из Лео – Лео), значительно сложнее. Ну и всякие потерял/потеряла, который/которая и прочие великие и могучие особенности.
В-третьих, согласование фраз. Обычно текст идет «сплошным потоком» и ты видишь всю картину целиком (хотя бы в рамках одного диалога/абзаца). Здесь же текст состоит из отдельных частей, которые могут сочетаться в различных комбинациях – кампания же нелинейная, а текст – отдельные фразы диалога. И заранее (в процессе перевода) можно лишь предполагать, как эти диалоги будут строиться, а проверить все комбинации «живьем» можно только многократно проходя кампанию и каждый раз выбирая другие варианты ответов и пытаясь создать новые игровые ситуации.
Ну и в-четвертых, перевод это не только текст, но и картинки. Правда, тут сложностей почти не возникло – мой давний друг Дмитрий Мольдон любезно согласился перевести все игровые картинки на русский язык. Спасибо ему еще раз)
Короче говоря, оказалось, что это далеко не «просто перевести текст». Особенно с учетом того, что основной его объем занимает «художка», диалоги, разговорные выражения. А ведь хочется сделать не просто перевод, а именно локализацию/адаптацию, а это значит – тщательный поиск идиом-аналогов, работа над стилистикой и лексикой (грубо говоря, чтобы речь гламурной дальнобойщицы на дизайнерском космолете отличалась от речи мелкого жулика, разводящего тебя на выпивку в местном баре). И, разумеется, хотелось как можно точнее передать замечательный юмор Влаада Хватила (для чего часто приходилось ориентировался на обе версии – английскую и чешскую).
Начавшись в самом конце декабря, работа над переводом заняла все новогодние праздники (благо они были длинные, а мои домашние с пониманием отнеслись к этому моему увлечению), потом еще неделю, а потом и остаток января. И в первых числах февраля я снова написал разработчикам, но теперь это было уже не просто абстрактное «предлагаю помощь», а вполне конкретное «имею перевод, готов путешествовать», ну, то есть что-то типа «я тут приложение перевел, но у меня возникли сложности тут, тут и тут, а пока переводил, нашел несколько багов – тут, тут и тут (вот скриншоты)».
Через пару дней пришел ответ «Хм, погодите, сейчас я свяжу вас с коллегой». А потом коллега ответил (ура!) и понеслась: багрепорты, вопросы и ответы, дополнительные разъяснения («да, действительно, в настолке летящий сзади метеорит можно сбить только пушкой в том же столбце, а в цифровой – в том же или соседнем, но это не баг, а фича»), множественные тестирования и согласования форматов. Выяснилось, что как раз в это время CGE начало готовить некую централизованную схему, призванную упростить работу с переводом на любые языки. Правда, в моем случае это было не совсем удобно – пришлось построчно вытаскивать перевод из готовых файлов, чтобы в итоге он также построчно загонялся в эти же файлы, но уже на их стороне.
Разумеется, помимо взаимодействия с CGE все это время шла работа над полировкой текста, менее удачные обороты заменялись более удачными, отлавливались опечатки, перефразировались выражения, вот это все.
Кстати, забавный курьез, вызванный, видимо, двойным языковым барьером (русский – английский – чешский – английский – русский): то, что у меня есть не просто переведенные тексты, а фактически рабочее приложение на русском языке, выяснилось чуть ли не через месяц после начала активного сотрудничества, причем, похоже, случайно, по очередной партии скриншотов (…but that they are already implemented to the app. How did you do that? :-O It is not so trivial. So not only you speak Russian, you like board games, but you are good programmer! At least it looks like it 🙂
А я по началу никак не мог понять, почему они постоянно предлагают мне помощь в интегрировании перевода в приложение =)
В итоге, несмотря на то, что перевод технически был готов еще в начале февраля (ну и на основную полировку текста ушло недели три-четыре), полноценные бета-версии «от разработчика» начали появляться только в апреле. На момент написания этой статьи русская (а точнее – мультиязычная, к начальным двум добавилось еще четыре языка) версия все еще находится в стадии активного тестирования, но основная часть работы уже позади. Остались только технические и перфекционистские нюансы, типа небольших сложностей с субтитрами – по понятным причинам пришлось отказаться от хардсабов, а субтитры в виде отдельных файлов просто так поверх видео не выводятся (то есть они выводятся, но не совсем так, как хотелось бы). Ну или, например, мои любимые кавычки-елочки и тире (а не просто дефисы-минусы) появились в шрифте только неделю назад, а это значит, что нужно заново пересмотреть весь текст и внести необходимые правки.
В общем, следите за новостями. Release Is Coming)
Подытожу
Перевод приложений – это не так страшно, как кажется. Да, это не всегда просто, но весьма интересно. А главное – ВОЗМОЖНО. Даже если вы раньше никогда этим не занимались.
Энтузиазм, тщательность, внимание к мелочам, терпение и снова энтузиазм. Ну и гугл, который и значение идиомы объяснит, и работать со спецутилитой научит, и контакты разработчиков подскажет.
Дерзайте, товарищи, возможно всё!
Язык программирования Котлин
Начать Почему Котлин
Разработано JetBrains и участники с открытым исходным кодом
Мультиплатформенный мобильный
Поделитесь логикой своих приложений для Android и iOS, сохранив собственный UX
На стороне сервера
Современный опыт разработки с использованием знакомой технологии JVM
Мультиплатформенные библиотеки
Создайте библиотеку, которая работает на нескольких платформах
Андроид
Рекомендуется Google для создания приложений для Android
Наука о данных
Попробуйте Kotlin
Простой
Асинхронный
Объектно-ориентированный
Функциональный
Идеально подходит для испытаний
5"> веселая главная () { val name = "stranger" // Объявите вашу первую переменную println("Привет, $name!") // ...и пользуйся! print("Текущее количество:") for (i in 0..10) { // Цикл в диапазоне от 0 до 10 распечатать("$я") } }импортировать kotlinx.coroutines.* suspend fun main() { // Функция, которую можно приостановить и возобновить позже val start = System.currentTimeMillis() coroutineScope { // Создаем область для запуска сопрограмм для (я в 1..10) { launch { // Запустить 10 одновременных задач delay(3000L - i * 300) // Приостановить их выполнение log(начало, "Обратный отсчет: $i") } } } // Выполнение продолжается после завершения всех сопрограмм в области видимости log(начало, "Взлет!") } журнал развлечений (начало: длинное, сообщение: строка) { println("$msg" + "(на ${Thread.currentThread().name}) " + "после ${(System.currentTimeMillis() - start)/1000F} с") }
абстрактный класс Person (имя val: String) { абстрактное веселое приветствие () } интерфейс FoodConsumer { весело есть () fun pay(amount: Int) = println("Вкусно! Вот $amount баксов!") } класс RestaurantCustomer (имя: строка, значение блюда: строка): человек (имя), FoodConsumer { fun order() = println("$dish, пожалуйста!") переопределить fun eat() = println("*Ест $блюдо*") переопределить fungreet() = println("Это я, $name.") } веселая главная () { val sam = RestaurantCustomer("Сэм", "Салат") sam.greet() // Реализация абстрактной функции sam.order() // Функция-член sam.eat() // Реализация функции интерфейса sam.pay(10) // Реализация по умолчанию в интерфейсе }5"> веселая главная () { // Кто отправил больше всего сообщений? val FreightSender = сообщения .groupBy(Сообщение::отправитель) .maxByOrNull { (_, сообщения) -> messages.size } ?.key // Получить их имена println(frequentSender) // [Ма] // Кто отправители? val отправители = сообщения .asSequence() // Делаем операции ленивыми (для длинной цепочки вызовов) .filter { it.body.isNotBlank() && !it.isRead } // Использовать лямбда-выражения... .map(Message::sender) // ...или ссылки на элементы .отчетливый() .сортировано() .toList() // Преобразование последовательности обратно в список для получения результата println(senders) // [Адам, Ма] } Сообщение класса данных( // Создаем класс данных val отправитель: строка, тело val: Строка, val isRead: Boolean = false, // Предоставляем значение по умолчанию для аргумента ) val messages = listOf( // Создаем список Сообщение("Ма", "Эй! Где ты?"), Message("Адам", "Сегодня все идет по плану?"), Сообщение("Ма", "Пожалуйста, ответьте.
// Тесты // Следующий пример работает только для JVM импортировать org.junit.Test импортировать kotlin.test.* класс SampleTest { @Тест fun `test sum`() { // Пишем имена тестов с пробелами в обратных кавычках значение а = 1 знач б = 41 assertEquals(42, sum(a, b), "Неверный результат для суммы($a, $b)") } @Тест весело `проверить вычисление`() { assertTrue("Ошибка вычисления") { setup() // Используем лямбду, возвращающую испытуемый вычислить() } } } // Источники забавная сумма (a: Int, b: Int) = a + b забавная установка () {} весело вычислить () = правда
Другие примеры ↗Начало работы ↗
Краткий
Выразительный
Асинхронный
Совместимый
Идеально подходит для тестов
// Приложения, созданные с помощью Kotlin, на 20% реже вылетают // (на основе внутренних данных Google) fun printMessagesUppercased(messages: List) { // Элементы списка могут быть пустыми // messages.add(Message("Java")) // Не разрешено, список доступен только для чтения messages.onEachIndexed {индекс, сообщение -> print("\nСообщение #$index: ") // print(msg.uppercase()) // Не разрешено, msg может быть нулевым msg?.let { // Печатаем, только если не null print(it.uppercase()) // Хорошо, это строка } } } веселая главная () { val messages = mutableListOf («привет», null, «мир») // messages = mutableListOf("!!!") // Не разрешено, нельзя переназначить значение messages.add("Kotlin") // Все в порядке, список можно изменять printMessagesUppercased (сообщения) }
импортировать kotlinx.coroutines.* импортировать kotlinx.coroutines.flow.* // начало выборки // Более 50% профессиональных разработчиков используют сопрограммы // сообщаем о повышении производительности // (на основе внутренних данных Google) весело main () = runBlocking { val start = System. currentTimeMillis() coroutineScope { // Создаем область для запуска сопрограмм val waitJob = launch { // Запуск сопрограммы ожидания ожидание(начало, 150) } countdownSignals(10, 300).collect {значение -> log(начало, "Обратный отсчет: $значение") } ожиданиеJob.cancel () } // Выполнение продолжается после завершения всех сопрограмм в области видимости log(начало, "Взлет!") } fun countdownSignals(n: Int, delayMillis: Long): Flow= поток { // Построитель потока for (i in (1..n).reversed()) { delay(delayMillis) // Задержка в выдаче сигналов emit(i) // Выдать элемент потока } } // Функция, которую можно приостановить и возобновить позже приостановить ожидание удовольствия (начало: долго, delayMillis: долго) { в то время как (currentCoroutineContext().isActive) { log(start, "Ожидание...") // Ожидание одновременно с чем-либо еще задержка (delayMillis) } } //конец выборки журнал развлечений (начало: длинное, сообщение: строка) { println("$msg после ${(System. currentTimeMillis() - start)/1000F}s") }
// Легко интегрируется в существующие приложения, // так как Kotlin совместим с Java и другими языками @SpringBootApplication демонстрационное приложение класса весело main(аргументы: Array) { runApplication (*args) } @RestController класс MessageResource { @GetMapping забавный индекс(): Список<Сообщение> = listOf( Сообщение("1", "Привет!"), Сообщение("2", "Добрый день!"), Сообщение("3", "Привет!"), ) } Сообщение класса данных (действительный идентификатор: строка?, допустимый текст: строка)
// Более 20% разработчиков начинают внедрять Kotlin с написания на нем тестов // (на основе опросов, проведенных JetBrains) // Следующий пример работает только для JVM импортировать org. junit.Test импортировать kotlin.test.* класс SampleTest { @Тест fun `test sum`() { // Пишем имена тестов с пробелами в обратных кавычках значение а = 1 знач б = 41 assertEquals(42, sum(a, b), "Неверный результат для суммы($a, $b)") } @Тест весело `проверить вычисление`() { assertTrue("Ошибка вычисления") { setup() // Используем лямбду, возвращающую испытуемый вычислить() } } } // Источники забавная сумма (a: Int, b: Int) = a + b забавная установка () {} весело вычислить () = правда
Начать ↗
Современный, лаконичный и безопасный язык программирования
Легко подобрать, так что вы можете сразу создавать мощные приложения.
Краткий
класс данных Сотрудник ( имя val: строка, val электронная почта: строка, val компания: Строка ) // + автоматически сгенерированные equals(), hashCode(), toString() и copy() object MyCompany { // Одноэлементный константное имя: String = "MyCompany" } fun main() { // Функция верхнего уровня val employee = Employee("Алиса", // Нет ключевого слова `новое` "alice@mycompany. com", MyCompany.name) println (сотрудник) }
Сейф
забавный ответ (условие: логическое значение): String? = // Обнуляемость является частью системы типов Kotlin if (условие) "Я в порядке" else null fun error(): Nothing = // Всегда генерировать исключение выбросить IllegalStateException("Здесь быть не должно") веселая главная () { val condition = true // Попробуйте заменить `true` на `false` и запустите образец! val message = ответ(условие) // Результат может быть нулевым // println(message.uppercase()) // Эта строка не компилируется println(message?.replace("отлично", "хорошо")) // Безопасный доступ к значению, допускающему значение NULL if (message != null) { // Если вы проверите правильность типа, println(message.uppercase()) // компилятор сделает это за вас. } val nonNull: String = // Если нулевой регистр выдает ошибку, answer(condition = true) ?: error() // Kotlin может сделать вывод, что результат не равен нулю println(ненулевой) }
Выразительный
весело main() { // начало выборки val map = mapOf (от 1 до «одного», от 2 до «двух») for ((k, v) in map) { // Обходим карту или список пар println("$k -> $v") } fungetKnowledge() = Pair("The Answer", 42) // Функции с одним выражением val (описание, ответ) = getKnowledge() // Деструктурировать в пару двух переменных println("$описание: $ответ") getText()?. let { // Применяем действие к выражению, допускающему значение NULL sendEmailTo("[email protected]", it) // если не null } создатьпустое окно() .apply { // Настраиваем свойства объекта ширина = 300 высота = 200 Видимый = Истина }.also { w -> // Выполняем дополнительную операцию над цепочкой вызовов показатьокно(ж) } val fixedIssue = issueById["13456"] ?.takeIf { it.status == Status.FIXED } // Использовать значение, только если условие истинно println (фиксированная проблема) //конец выборки } Окно класса данных (ширина переменной: Int, высота переменной: Int, переменная isVisible: логическое значение) весело createEmptyWindow() = Окно (0, 0, ложь) весело showWindow(окно: Окно) { println("Показано $окно") } весело getText(): Строка? = "Привет! Вы выиграли в лотерею! Оплатите приложенный счет, чтобы получить приз." весело sendEmailTo (кому: строка, сообщение: строка) { println("Отправка письма на адрес $to:\n$message") } Статус класса enum {OPEN, FIXED, IN_PROGRESS} Проблема класса данных (val status: Status) val issueById = mutableMapOf( "13456" для выдачи (Статус. ИСПРАВЛЕНО) )
Интероперабельный
// Использовать любую существующую библиотеку или фреймворк JVM // Вызов кода Kotlin из Java без проблем @SpringBootApplication демонстрационное приложение класса весело main(аргументы: Array
) { runApplication (*args) } @RestController класс MessageResource { @GetMapping забавный индекс(): Список<Сообщение> = listOf( Сообщение("1", "Привет!"), Сообщение("2", "Добрый день!"), Сообщение("3", "Привет!"), ) } Сообщение класса данных (действительный идентификатор: строка?, допустимый текст: строка) // Напишите код Kotlin, скомпилируйте его в JavaScript и запустите в браузере // Использовать существующие API и библиотеки JavaScript импортировать kotlinx.browser.window веселая главная () { Вал тело = окно.документ.тело body?.innerHTML += "Привет, Котлин" окно. setInterval({ тело?.innerHTML += "!" }, 1000) }
// Используйте оболочки Kotlin для создания приложений с помощью фреймворков JavaScript, таких как React импортировать реакцию.* импортировать реакцию.дом.* импортировать kotlinx.html.js.onClickFunction val counter = functionComponent
{ val (счетчик, setCount) = useState (0) кнопка { attrs.onClickFunction = {setCount (количество + 1)} +count.toString() } } Мультиплатформенный
// Общий // Объявить подписи, чтобы использовать их в общем коде // Предоставление специфичных для платформы реализаций в модулях платформы ожидать веселья randomUUID(): String ожидать класса PlatformSocket( URL-адрес: строка ) { весело openSocket (слушатель: PlatformSocketListener) весело closeSocket (код: Int, причина: строка) весело отправить сообщение (msg: строка) } интерфейс PlatformSocketListener { весело на Open () удовольствие от неудачи (t: Throwable) весело onMessage (msg: String) весело при закрытии (код: Int, причина: строка) }
импортировать java. util.* фактическое удовольствие randomUUID() = UUID.randomUUID().toString() фактический класс PlatformSocket фактический конструктор (url: String) { // Использовать okhttp3 в реализации }
// iOS импортировать платформу.Foundation.NSUUID фактическое удовольствие randomUUID(): String = NSUUID().UUIDString() фактический класс PlatformSocket фактический конструктор (url: String) { // Использовать в реализации platform.Foundation }
// JS // Использовать пакет `uuid` из npm в качестве зависимости фактическое развлечение randomUUID(): String = uuidv4() фактический класс PlatformSocket фактический конструктор (url: String) { // Реализация поверх WebSockets }
Продуктивный способ написания серверных приложений
Совместимость с экосистемой Java. Используйте свои любимые фреймворки и библиотеки JVM.
Узнать больше →Кроссплатформенный уровень для собственных приложений
Совместно используйте логику приложения между веб-, мобильными и настольными платформами, сохраняя при этом привычный для пользователей опыт.
Сэкономьте время и получите неограниченный доступ к функциям, характерным для этих платформ.
Узнать о мультиплатформе Kotlin → Узнать больше →Большое, дружелюбное и полезное
сообщество
У Kotlin отличная поддержка и множество участников в быстрорастущем глобальном сообществе. Воспользуйтесь преимуществами богатой экосистемы с широким спектром библиотек сообщества. Помощь всегда рядом — обратитесь к многочисленным ресурсам сообщества или напрямую обратитесь к команде Kotlin.
Присоединяйтесь к сообществу →Gradle представляет Kotlin как язык для написания скриптов сборки
Corda — это платформа распределенного реестра с открытым исходным кодом, поддерживаемая крупными банками и полностью построенная на Kotlin
.Evernote недавно интегрировала Kotlin в свой Android-клиент
Android-приложение Coursera частично написано на Kotlin
Spring использует языковые функции Kotlin, чтобы предлагать более лаконичные API
Весь новый код в Android-приложении Trello написан на языке Kotlin
Хотите попробовать?
Начало работы
Как переводить приложения в Android Studio
Перевод вашего приложения для Android не только улучшает общее взаимодействие с пользователем, но также может увеличить количество загрузок. Узнайте, как переводить приложения в Android Studio, официальной интегрированной среде разработки Android от Google.Давайте проведем вас через шаги, чтобы показать вам, как создать многоязычное приложение для Android с помощью Android Studio. Локализация вашего приложения для Android может увеличить продажи, увеличить коэффициент конверсии и улучшить общее впечатление от пользователя.
Android Studio — это официальная среда разработки Android, разработанная Google.
Если это ваш первый проект Android Studio: просто установите Android Studio, создайте новый проект из шаблона «Пустая активность» и перетащите некоторые виджеты пользовательского интерфейса на пустое пространство холста. Мы использовали этот небольшой пример представления (ниже), который мы будем использовать для этого поста.
По умолчанию виджеты пользовательского интерфейса сохраняют свои метки в жестко запрограммированных строках. Если вы наведете курсор на виджет пользовательского интерфейса, Android Studio покажет всплывающую подсказку, предлагающую переместить эту жестко запрограммированную строку в файл ресурсов с именем strings. xml.
Продолжайте, следуйте подсказке и переместите все переводимые строки в файл ресурсов strings.xml.
В навигаторе файлов проектов разверните только что созданный каталог значений, щелкните правой кнопкой мыши файл strings.xml, чтобы открыть Редактор переводов.
В редакторе переводов щелкните значок земного шара, чтобы добавить новый языковой файл, в нашем примере мы добавим «de» (немецкий) и «es» (испанский). Мы также хотим добавить локаль региона «de-at» для Австрии, которую нельзя создать с помощью редактора. В результате нам нужно создать каталог ‘values-de- r AT’ в папке ресурсов и создайте файл strings.xml.
Возможно, вам придется закрыть и снова открыть вкладку «Редактор перевода» после добавления нового языка, если он не отображается сразу.
Теперь вы можете начать перевод ваших строк. Если строка не переведена в локали, приложение автоматически вернется к наиболее похожему переводу. Например, если в австрийской локализации отсутствует перевод, будет использоваться немецкий перевод, а если его там тоже нет, будет использоваться язык по умолчанию — обычно это файл английского языка.
И вуаля: готово! Для выбора языка не требуется дополнительный код. Android выберет правильную локаль на основе языка устройства, если он доступен в опубликованном приложении.
Если вы хотите сделать еще один шаг вперед в локализации, ознакомьтесь с Phrase, нашим сервисом, который поможет вам управлять процессом перевода онлайн. Вы даже можете заказать профессиональные переводы одним нажатием кнопки.
Плагин Phrase для Android Studio легко интегрируется с Android Studio и редактором перевода. Установите плагин, после перезапуска он должен появиться на правой панели инструментов вашей IDE.
Затем вы можете позволить плагину создать конфигурацию вашей фразы.
Просто вставьте токен доступа, и плагин проведет вас через шаги. После успешной инициализации теперь вы можете извлекать и отправлять свои локали.
Если вам нужно настроить способ передачи или извлечения локалей из Phrase, вы можете отредактировать .phraseapp.yml
. Чтобы узнать больше о том, как редактировать конфигурацию, ознакомьтесь с нашей документацией.