Build an Android App with JavaScript for Generating QR Codes
We are back with yet another Android app demo. This time, we take a different approach to building an Android app with JavaScript.
Being the de-facto programming language for the web, JavaScript has enjoyed tremendous growth over the years, especially in frontend browser-based applications. Thanks to the advances in runtime environments and the tooling, it is now possible to take JavaScript off the browser and use it in other ways. In this blog post, we show you how to build an Android app using JavaScript and related web technologies, without using any native Java or Kotlin based environments. We also show you how to integrate an API with such Android applications by leveraging the power of the RapidAPI‘s API marketplace.
Can we use JavaScript for Android?
The Android ecosystem supports the concept of hybrid apps, which is a wrapper over the native platform. It mimics the UI, UX, and all kinds of hardware and network interactions, just like how you would use a native Android app.
Many frameworks offer a hybrid wrapper for Android. The Ionic framework is the most popular among the developer community. It leverages the Cordova WebView plugin, which is a browser like skin over the native Android UI.
Using the Ionic framework for Building Android Apps with Javascript
The ionic framework works with Angular, React as well as vanilla JavaScript or Vue, to bind the application. Ionic 5 is the latest version of the framework. The support for React, JavaScript, and Vue was added in version 4. However, JavaScript and Vue support is still not stable enough to build production-grade apps. Therefore, as of this writing, it is recommended to use Angular with Ionic 5.
Using the TypeScript language, a superset of JavaScript, you can build an Ionic application on top of Angular, which runs as a hybrid Android app using the WebView plugin.
The Ionic framework acts as the glue between the Android platform, Angular, and Cordova. The resulting hybrid app feels just as good as a native app. A regular user would never be able to make out the difference.
The only downside is these apps is that they are not performant like native apps. Moreover, these apps cannot command fine-grained control over the underlying hardware in case of a need for hardware boosted performance.
Building the UI Layer for Ionic Hybrid App
The Ionic framework offers a set of UI components that you can use to build the app UI.
Like you use HTML tags to build the browser UI, Ionic offers high-level custom tags to build the app’s UI elements.
Here is how you can piece together an app screen to display a piece of small information on a card.

Using the <ion-card> tag, you can build this screen as follows.
In this way, Ionic provides a complete library of UI specific custom elements to build UI screens for apps.
Making API Calls from Ionic Hybrid App
If you are using Angular as the base framework, then making an API call is easy.
Angular provides an HTTP client library for TypeScript that leverages the HTTPClient class.
This class provides all the HTTP methods, including the most common ones, post() and get() to invoke API requests from an URL. Here is how you can define a module to make a quick API call using HTTPClient and a few helper classes.
<ion-header> and <ion-content> defines the top level wrappers for housing the UI elements.
The UI is structured in a typical HTML fashion using <div> elements containing both Ionic specific custom elements, as well as standard HTML elements. This includes <ion-card> , <ion-item> , <ion-label> , <ion-button> , along with <form> and <img> tags.
Now open the file home.page.scss and replace the default content with this.
This is the standard CSS stuff that you define to style the UI components. The most notable thing here is .loading class. It defines the loading animation to be displayed while waiting for the API response.
Now open the file home.page.ts and replace the default content as follows.
This code is in TypeScript. It defines the business logic for the UI. The only interaction point for this app is the button press to invoke the QRcikit API and display the generated QR code.
The getQRCode( ) function handles this. You can follow the comments in the code to understand the flow.
This also uses the HTTP service for API invocation. You will tackle this function in the next step.
Step 4: Add the code for HTTP service
Open the file http.service.ts under /qrcode/src/app path and replace the existing content with this code.
Further, add the HttpClientModule for imports under the @NgModule block.
With this step, coding is complete.
Step 6: Generate Android artifacts
To generate an Android app from this Ionic project, you will need to add Android specific artifacts.
First, you must ensure that the build environment for Android is correctly set up.
Now open the config.xml file under qrcode path and change the value of the <name> tag to QRCodeGen. The content of this tag will be the name of the app that installs on Android phone.
After that, switch to the terminal where you created the Ionic project. Make sure that you are under the “qrcode” path and issue the following commands.
1. Add the Android platform to Ionic project.
| ionic cordova platform add android |
2. Build the Android app
| ionic cordova build android |
Note: These commands will take some time to execute, anywhere between 5 to 10 minutes. If you face any errors due to the unavailability of dependencies, please follow the error messages to install the dependencies and run the command again.
At the end of the build step, you will see the new Android .apk file under the qrcode/platforms/android/app/build/outputs/apk/debug path.
Step 7: Test the Android app
To test the app, you can use the Android emulator that comes by default with the Android Studio.
Launch the Android studio. On being prompted by the welcome screen, choose the option for opening an existing project, and navigate to the “qrcode” project folder. This will open the Android Studio IDE and show the “qrcode” folder structure.
Note: The Android Studio is used to launch the emulator only. We are not going to use it to build the app.
Now launch the AVD manager from the top toolbar, and you will see the list of available virtual devices.

Double click on the virtual device to launch it. It will take a few minutes to start and display the Android screen.

Now drag and drop the .apk file on the emulator window. This action will install the app on the emulator device. It will create an app icon with the name QRCodeGen, as per the name you defined in the config.xml file.
Once installed, navigate to the app, launch it, and you are ready to test it.
You have just created an Android app with JavaScript without using any of the native Android development tools.
What’s Next?
If you are a web developer, you will be most familiar with HTML CSS and JavaScript instead of Java or Kotlin. Hence, this approach is the best way to build an Android app without upskilling yourself.
You should now have a good idea about how to build an Android app with Ionic. It is a reliable framework, and with a reliable API from the RapidAPI marketplace, you can do wonders with hybrid Android apps.
So what do you want to build?
Share your thoughts and queries in the comments below. We will be back soon with yet another exciting demo around Android.
How to build Android apps with JavaScript?
The preferred development environment for Android app is Kotlin or Java, hence there is no direct way of building an Android app using JavaScript. However, with the help of a framework, it is possible to add a wrapper over the native Android interface. The Ionic framework is one of the oldest and the most popular framework that leverages several web frameworks to provide that wrapper. Apart from supporting vanilla JavaScript, which is still in beta, you can use Ionic with Angular and React to built a hybrid wrapper over Android.
How to generate a QR code?
QR codes can be used to encode useful information ranging from website URLs, contact information as well as other information. The ideal way to generate a QR code is through an API. You can search the RapidAPI catalog to choose one among the many QR code generation APIs.
Is there any API to generate QR code?
Yes. You can generate any QR code representing an URL, of arbitrary data using a QR code generation API. The generated QR code is available through an image that is returned as part of the API response. You can search the RapidAPI catalog to choose from many QR code generation APIs which provide custom options for decorating the QR code images as well as multiple formats to return the generated QR code image.
Building a Mobile App using HTML, CSS, and JavaScript
![]()
So you have seen the title, and you are wondering how you can pull off building an actual mobile application by just using the knowledge of basic web technologies without the need to learn Android or IOS development? This is made possible by converting your regular web applications to work as a standard mobile application that can be installed on multiple platforms. By doing this, we will achieve a type of application referred to as Progressive Web Apps (PWAs).
In this article, we will learn how to leverage the power of HTML, CSS, and Javascript to build a simple mobile app. We will not be using frameworks like Ionic or React Native. This is because this tutorial focuses on showing how a basic web app can be made to feel and behave like a native mobile application that can be installed and run on mobile devices using the most straightforward method with the least abstraction.
To proceed, let us have a brief introduction to PWAs.
What are Progressive Web Apps?
Progressive Web Apps (PWAs) are web apps that use service workers, manifests, and other web-platform features combined with progressive enhancement to give users an experience on par with native apps.
In simple terms, they are basically websites styled like apps that can be run either inside a website browser or installed directly on a mobile device and accessed like a native app.
There are three key components of a PWA;
- Service Worker: The service worker transforms the website into an app by allowing it to download and cache files on a device.
- Web Manifest: This JSON file provides the basic meta-information about the app, such as the app icon, background color, etc.
- Secure HTTPS: HTTPS is mandatory and makes PWAs more secure than regular web apps.
PWAs have pros and cons. Among the former:
- Cheap and Fast Development: PWAs are less expensive, quicker, and easier to create than native apps. Native app development from the ground up necessitates particular technologies for both platforms. HTML, CSS, and JavaScript are all that are required for a PWA.
- Cross-Platform Availability: One of the promising advantages of PWAs is that they can be installed and run on multiple devices across various operating systems.
- Offline Functionality: Having bad or no internet at all won’t stop users from using your app as it can cache data for offline viewing using service workers.
- Performance: Compared to native mobile apps, PWAs are much lighter, don’t take as much memory space, and have a faster load time.
On the negative side:
- High Battery Usage: Because PWAs are built-in high-level web code, phones have to work harder to read the code; they use more battery than native apps.
- Mobile hardware access: PWAs cannot access various hardware features like the device’s Bluetooth, proximity sensors, etc.
- Distribution Since PWAs are not distributed through the app store, you may miss out on users who mainly browse the app store.
You should consider using/building Progressive Web Apps if you meet the following criteria:
- You don’t have the budget to build a full-fledged app.
- You need to push to your target audience faster.
- Having cross-platform compatibility is essential to your business.
We’ll be building a “Todo List” mobile app using HTML, CSS, and Javascript. We will first build out a web app while using IndexedDB for our database, workbox to make it work offline, and web manifest to make it installable across devices. The final result will be as follows:
Создаем приложение на JavaScript с помощью React Native
В этом уроке мы будем изучать React Native – фреймворк от компании Facebook для создания нативных приложений под iOS и Android. У него много общего с другим очень популярным фреймворком от Facebook – React Javascript, который предназначен для построения декларативных пользовательских интерфейсов.
Примечание: это обновленный вариант урока, написанного Колином Эбергардом из iOS Team, содержащий ряд правок для версии React Native 0.22.
Но на данный момент и так существует достаточно фреймворков, использующих JavaScript для создания iOS-приложений, таких как PhoneGap или Titanium. Что же делает React Native особенным?
1. В отличие от PhoneGap, в React Native логика приложения пишется и работает на JavaScript, в то время как его интерфейс остается полностью нативным. Таким образом не требуется никаких компромиссов, характерных для HTML5 UI.
2. В отличие от Titanium, React вводит новый оригинальный и крайне эффективный подход к созданию пользовательских интерфейсов. Если говорить кратко, UI приложения выражается как функция текущего состояния приложения.
Ключевая особенность React Native в том, что его разработчики намерены привнести модель программирования React в сферу разработки мобильных приложений. Важное уточнение: речь идет не о таком кроссплатформенном инструменте, с которым можно писать софт один раз и использовать его везде, а о таком, который можно изучить один раз и писать на нем везде. Данный урок предназначен для iOS-платформы, но, изучив весь изложенный материал, вы сможете без труда создавать также Android-приложения.
Если у вас есть опыт написания приложений на Objective-C или Swift, вы наверняка не обрадуетесь идее перехода на JavaScript. Но вместе с тем, второй пункт явно должен был заинтересовать Swift-разработчиков.
Несомненно, работая со Swift, вам приходилось изучать много новых и более эффективных способов шифрования алгоритмов, а также методик, способствующих преобразованию и неизменяемости. Тем не менее, способ построения UI здесь очень похож на тот, что используется при работе с Objective-C: он тоже основывается на UIKit и является императивным.
React за счет таких необычных понятий как Virtual DOM и согласование переносит функциональное программирование на слой пользовательского интерфейса.
В данном уроке по React Native мы будем создавать приложение по поиску недвижимости в Великобритании:

Если вы никогда прежде не работали с JavaScript, не волнуйтесь. Мы подробно разберем каждый шаг разработки. React использует для стилизации синтаксис наподобие CSS, который легко прочитать и понять, но в случае чего вы всегда можете обратиться к Mozilla Developer Network.
Интересно? Идем дальше.
Приступаем к работе
Для создания JavaScript-кода React Native использует Node.js, среду выполнения JavaScript. Если вы еще не установили себе Node.js, пора это сделать.
Сначала установим Homebrew, следуя инструкциям на сайте, а затем – Node.js, выполнив в окне терминала следующее:
Затем с помощью homebrew установим watchman – сервис для отслеживания изменения и поиска файлов от Facebook:
React Native использует его, чтобы отслеживать изменения кода и делать соответствующие правки. Это что-то вроде Xcode, но выполняющего сборку каждый раз после сохранения файла.
Далее установим React Native Command Line Interface (CLI), используя npm:
Он использует Node Package Manager, чтобы вызвать и глобально установить CLI-инструмент; npm поставляется вместе с Node.js, его функция аналогична CocoaPods или Carthage.
Для тех, кто хочет глубже разобраться с React Native, его исходный код находится в открытом доступе на GitHub.
Перейдите к папке, в которой вы хотите сохранить проект, и воспользуйтесь CLI-инструментом для его создания:
Эта строка создает начальный проект, в котором содержится всё необходимое для разработки и запуска приложения на React Native.
Если вы видите уведомление об устаревшей версии Node.js, убедитесь, что та, которую установил brew, является актуальной. Для этого выполните в терминале команду brew link —overwrite node.
Взглянув на созданные папки и файлы, вы обнаружите папку node_modules, в которой находится фреймворк React Native. Файл index.ios.js – это макет приложения, созданный CLI-инструментом. Обратите также внимание на папку ios – в ней содержится проект Xcode и небольшой код для интеграции с Bootstrap. Наконец, там есть и компоненты для Android, но мы не будем рассматривать их здесь.
Откройте файл проекта, сделайте его сборку и запустите. Симулятор отобразит следующее сообщение:

Примечание: На момент написания урока начальный проект, созданный CLI-инструментом React Native, выводил три предупреждения во время сборки. Потому не волнуйтесь, впервые увидев какие-либо уведомления от Xcode. Разработчики React Native знают об этой небольшой проблеме, и мы работаем вместе с ними над ее устранением в следующем релизе React Native.
Вероятно, вы также заметили всплывающее окно терминала с таким сообщением:
Это упаковщик React Native, работающий под управлением Node.js. Вскоре вы узнаете, для чего он нужен.
Не закрывайте окно терминала, пусть оно работает на фоне. Если вы случайно закрыли его, просто остановите и перезапустите проект с помощью Xcode.
Примечание: прежде чем мы заберемся в дебри кода, нужно определиться с выбором текстового редактора. Вам предстоит писать много JavaScript-кода, а Xcode явно не подходит для этого. Я использую Sublime Text, это недорогой и очень удобный инструмент. Но Atom, Brackets или любой другой легковесный редактор тоже отлично подойдет.
Hello React Native
Прежде чем начать работу над приложением по поиску недвижимости, мы создадим приложение Hello World. По ходу дела я буду вводить новые компоненты и понятия.
Откройте файл index.ios.js в текстовом редакторе и удалите всё его содержимое, так как мы будем создавать приложение с нуля. Добавьте в начале файла следующее:
Эта директива объявляет строгий режим, который добавляет улучшенную обработку ошибок и налагает ограничения на некоторые элементы JavaScript. Проще говоря, он улучшает работу JavaScript.
Примечание: более подробную информацию о строгом режиме можно найти в статье Джона Резига под названием ECMAScript 5 Strict Mode, JSON, and More.
Затем добавьте эту строку:
Она загружает модуль react-native и присваивает его переменной React. React Native использует такую же технологию загрузки модуля, как и Node.js с функцией require, которая примерно эквивалентна подключению и импорту библиотек в Swift.
Примечание: более подробную информацию о модулях JavaScript можно найти в статье Эдди Османи о модульном JavaScript.
Далее добавьте следующее:
Этот код задает единый стиль, который мы вскоре применим к тексту Hello World. Если у вас уже есть какой-либо опыт веб-разработки, вероятно, вы узнали эти свойства. Внешний вид класса StyleSheet, используемого для стилизации интерфейса, напоминает синтаксис широко применяемого в вебе языка Cascading Style Sheets (CSS).
Итак, займемся непосредственно приложением. Добавьте следующий код прямо под переменной со стилями:
Да, это класс JavaScript.
Классы были добавлены в ECMAScript 6 (ES6). Поскольку JavaScript постоянно развивается, разработчики вынуждены ограничивать себя в используемых средствах ради сохранения совместимости со старыми системами или браузерами. И хотя iOS 9 не полностью поддерживает ES6, React Native использует инструмент под названием Babel, который автоматически переводит современный JavaScript в совместимый с устаревшими версиями JavaScript там, где это необходимо.
Примечание: если вы веб-разработчик, вы также можете использовать Babel в браузере. Так что теперь действительно не осталось оправданий для работы со старыми версиями JavaScript – даже для поддержки устаревших версий браузеров.
PropertyFinderApp расширяет React.Component, основной структурный элемент интерфейса React. Компоненты содержат неизменяемые свойства и изменяемые переменные состояния; они предоставляют метод для рендеринга. Приложение, над которым мы сейчас работаем, очень простое и нуждается только в методе рендеринга.
Компоненты React Native – это не классы UIKit, а их легковесные эквиваленты. Фреймворк обеспечивает преобразование дерева компонентов React в требуемый нативный интерфейс.
Наконец, добавим в конец файла эту строку:
AppRegistry определяет точку входа в приложение и предоставляет корневой компонент.
Сохраните изменения в index.ios.js и вернитесь к Xcode. Убедитесь, что схема PropertyFinder выбрана с одним из симуляторов iPhone, а затем соберите и запустите ваш проект. Через несколько секунд на экране отобразится ваше приложение Hello World!:

Это JavaScript-приложение, работающее на симуляторе, который отображает нативный UI – и это без помощи браузера.
Всё еще не верите? Убедитесь сами: выберите в Xcode Debug\View Debugging\Capture View Hierarchy и вы увидите нативную иерархию представлений. Вы также заметите повсюду сущности UIWebView. Тест приложения отображается в RCTText. Но что это такое? Вернитесь в Xcode, выберите File\Open Quickly… и введите RCTView.h. Обратите внимание, что RCTView наследует непосредственно от UIView. Выходит, всё работает отлично.

Хотите знать, как это работает? Откройте в Xcode AppDelegate.m и определите расположение application:didFinishLaunchingWithOptions:. Этот метод создает RCTRootView, который загружает JavaScript-приложение и рендерит результирующее представление.
Когда приложение запускается, RCTRootView загружает приложение из этого URL:
Вспомните окно терминала, которое было открыто, когда вы запускали это приложение. Оно запускает упаковщик и сервер, который обрабатывает запрос выше.
Откройте этот URL в Safari, и вы увидите JavaScript-код вашего приложения. Вы также должны обнаружить там код Hello World!, встроенный во фреймворк React Native.
Когда ваше приложение запускается, этот код загружается и выполняется фреймворком JavaScriptCore. В нашем случае он загружает компонент PropertyFinderApp и затем выстраивает нативное UIKit представление. Дальше в уроке мы поговорим об этом подробнее.
Hello World JSX
Созданное приложение использует React.createElement для построения простого интерфейса, преобразовываемого в нативный эквивалент с помощью React. И хотя текущий JavaScript-код читается легко, в случае более сложного UI со вложенными элементами он может превратиться в кашу.
Убедитесь, что приложение еще работает, затем вернитесь к редактированию файла index.ios.js и измените оператор return следующим образом:
Это JSX, расширение синтаксиса JavaScript, которое добавляет в JavaScript-код синтаксис наподобие HTML. Те, у кого уже есть опыт веб-разработки, заметят сходство с последним. Мы будем использовать JSX на протяжении всего урока.
Сохраните изменения в index.ios.js и вернитесь в симулятор. Нажмите Cmd+R, чтобы обновить сообщение на экране:

Перезапустить приложение на React Native так же просто, как обновить страницу браузера. Обратите внимание, что в таком случае отобразятся только те изменения, которые касались JavaScript-файлов. Во всех других случаях потребуется повторная сборка приложения в Xcode.
Поскольку в этом уроке мы будем работать с тем же набором JavaScript-компонентов, вы можете оставить приложение работать и обновлять его после сохранения изменений в index.ios.js.
Примечание: если вам интересно, во что преобразовывается JSX, взгляните на ‘bundle’ в браузере.
Полагаю, мы вполне наигрались с Hello World!, теперь пришло время создать настоящее приложение.
Добавляем навигацию
Приложение Property Finder использует стандартную стековую навигацию, предоставленную навигационным контроллером UIKit. Добавим это поведение.
В файле index.ios.js переименуйте класс PropertyFinderApp в HelloWorld:
Оставим пока текст Hello World!, но он больше не будет корневым компонентом приложения.
Затем добавим ниже компонента HelloWorld следующий класс:
Он создает навигационный контроллер, применяет стиль и устанавливает первоначальный маршрут к компоненту HelloWorld. В веб-разработке маршрутизация – это способ определения навигационной структуры приложения, где страницы – или маршруты – привязываются к соответствующим URL.
Далее подкорректируйте стили, добавив туда параметры контейнера, как показано ниже:
О том, что такое flex: 1, вы узнаете немного позже.
Сохраните изменения, вернитесь в симулятор и нажмите Cmd+R, чтобы увидеть обновленный интерфейс:

Корневое представление навигационного контроллера соответствует тексту Hello World. Теперь у нас есть базовая навигационная структура текущего приложения. Пора добавить настоящий UI.
Создаем страницу поиска
Добавьте в проект новый файл под названием SearchPage.js и поместите его в одну папку с файлом index.ios.js. Добавьте в новый файл этот код:
Мы уже рассматривали строгий режим и импорт в react-native, но следующий оператор присвоения – это нечто другое.
Это деструктурирующее присваивание, позволяющее извлекать множество свойств объекта и присваивать их переменным с одним оператором. Как результат, в оставшемся коде можно отбросить префикс React. К примеру, можно обращаться напрямую к StyleSheet, а не к React.StyleSheet. Деструктурирование также очень удобно использовать для управления массивами. Более подробную информацию о нем можно найти в этой статье.
Не закрывая файл SearchPage.js, добавьте внизу этот стиль:
Это тоже стандартные CSS-свойства. Возможно, данный способ задания стилей покажется вам менее удобным, чем использование Interface Builder, но этот подход определенно лучше, чем задавать свойства представления по одному в методах viewDidLoad().
Вставьте сам компонент непосредственно под стилями:
render отлично демонстрирует JSX и его структуру. Наряду со стилем вы можете очень просто визуализировать интерфейс, созданный этим компонентом: контейнер с двумя текстовыми подписями.
Напоследок добавим следующую строку в конец файла:
Она экспортирует класс SearchPage, что позволяет использовать его в других файлах.
Следующий шаг – обновить маршрутизацию приложения, чтобы установить другой первоначальный маршрут.
Откройте index.ios.js и добавьте эту строку сразу после require в начале файла:
В функции render класса PropertyFinderApp обновите initialRoute, чтобы привязать только что созданную страницу, как показано ниже:
Теперь, если хотите, можно удалить класс HelloWorld и его стили. Они вам больше не понадобятся.
Сохраните изменения, вернитесь в симулятор и нажмите Cmd+R, чтобы увидеть обновленный интерфейс:

Здесь используется новый компонент SearchPage.
Стилизуем с помощью Flexbox
В этом уроке мы уже имели дело с некоторыми базовыми свойствами CSS, задающими параметры цвета, а также внутренних и внешних отступов. Тем не менее, вероятно, вы еще не слышали о flexbox. Эта технология лишь недавно была добавлена в спецификацию CSS, она очень полезна при построении макетов пользовательских интерфейсов.
React Native использует библиотеку css-layout, которая является JavaScript-реализацией flexbox-стандарта, скомпилированного на C (для iOS) и на Java (для Android).
Очень хорошо, что React Native создавался как отдельный проект, нацеленный на несколько языков программирования, так как это позволяет разрабатывать приложения с использованием новейших подходов, вроде применения flexbox-макетов к SVG.
По умолчанию контейнер в вашем приложении имеет направление потока данных в виде столбца, что соответствует параметру column – а значит, всё содержимое контейнера будет выстраиваться вертикально:

Это так называемая главная ось, или main axis, она может иметь как горизонтальное, так и вертикальное направление.
Вертикальное положение каждого дочернего элемента контейнера высчитывается с учетом его внешних и внутренних отступов, а также высоты. Контейнер также задает свойству alignItems значение center, что определяет положение дочерних элементов на главной оси. В данном случае мы получим текст с выравниванием по центру.
Теперь добавим поле ввода и кнопки. Откройте файл SearchPage.js и введите следующий код сразу после закрывающего тега второго элемента Text:
Мы добавили два представления высшего уровня: в одном из них находится текстовое поле ввода и кнопка, а в другом – еще одна кнопка. Сейчас вы узнаете, как можно стилизовать эти элементы
Вернитесь к параметрам стилей, поставьте запятую после блока container и добавьте ниже новые стили:
Следите за форматированием: каждое свойство стиля или селектор следует отделять запятой.
Эти стили предназначены для только что добавленных поля ввода и кнопок.
Сохраните изменения, вернитесь в симулятор и нажмите Cmd+R, чтобы увидеть обновленный интерфейс:

Текстовое поле и кнопка ‘Go’ находятся на одной строке, так как вы поместили их в контейнер со стилем flowRight, элементы которого выстраиваются в строку за счет свойства flexDirection: ‘row’. Вместо того чтобы жестко задавать ширину каждого из этих элементов, мы выставили им относительную ширину с помощью значений свойства flex. Таким образом, в селекторе текстового поля searchInput мы имеем flex: 4, а в селекторе кнопки button — flex: 1, вследствие чего их соотношение составляет 4:1.
Возможно, вы также заметили, что элементы, которые мы называем кнопками, по сути таковыми не являются. На самом деле, кнопки в UIKit – это всего лишь интерактивные текстовые надписи. Кнопки вашего приложения используют компонент React Native под названием TouchableHighlight, который по нажатию становится прозрачным и показывает нижележащий цвет.
Наконец, добавим на страницу поиска изображение. Вы можете скачать его в нескольких разрешениях одним архивом. После скачивания распакуйте архив.
Далее создадим в корневом проекте директорию под названием ’Resources’ и поместим в нее все три изображения.
Предметные каталоги: Как вам известно, специалисты из Apple рекомендуют по возможности помещать изображения в предметные каталоги. Тем не менее, для React Native это наоборот нежелательно. Хранение цифровых объектов приложения рядом с его компонентами дает несколько преимуществ. Во-первых, это позволяет сохранить независимость компонентов. Во-вторых, при добавлении новых изображений не требуется повторная загрузка приложения. И в-третьих, при разработке приложения для iOS и Android это дает возможность хранить изображения для двух платформ в одном месте.
Вернитесь к файлу SearchPage.js и добавьте эту строку под закрывающим тегом компонента TouchableHighlight, отвечающего за кнопку location:
Теперь добавьте соответствующий стиль изображения в блоке со стилями, не забыв поставить запятую после предыдущего селектора:
Сохраните изменения. Вернитесь в симулятор и нажмите Cmd+R, чтобы увидеть новый интерфейс:

Примечание: Если изображение с домом не отображается, а вместо него показано уведомление о том, что картинка не найдена, попробуйте перезапустить упаковщик с помощью команды npm start в терминале.
Наше приложение уже смотрится симпатично, но всё же чего-то не хватает. Нужно добавить состояние приложения и выполнить кое-какие действия.
Добавляем состояние компонента
Каждый компонент в React имеет собственный объект состояния, который используется как хранилище типа «ключ–значение». Прежде чем компонент отобразится, нужно задать начальное состояние.
В файле SearchPage.js добавьте следующий код в класс SearchPage, прямо перед render():
Теперь у вашего компонента есть переменная state, а начальным значением searchString является london.
Время воспользоваться этим состоянием компонента. Изменим элемент TextInput в render, как показано ниже:
Мы выставили значение свойства TextInput – то есть показываемого пользователю текста – на текущее значение переменной состояния searchString. Итак, мы позаботились о начальном состоянии. Но что будет, когда пользователь отредактирует этот текст?
Прежде всего, создадим метод, выступающий в роли обработчика событий. Перейдите к классу SearchPage и добавьте данный метод сразу после constructor:
Он берет значение из свойства text в событии родного браузера и использует его для обновления состояния компонента. Он также добавляет код для сбора данных, которые нам вскоре пригодятся.
Чтобы данный метод вызывался каждый раз при изменении текста, вернемся к полю TextInput метода render и добавим свойство onChange. В итоге тег примет следующий вид:
Когда пользователь меняет текст, вызывается функция, добавленная к свойству onChange (в данном случае это onSearchTextChanged).
Примечание: Возможно, вам непонятно, для чего нужно выражение bind(this). JavaScript интерпретирует ключевое слово this немного иначе, чем большинство других языков. В Swift данному слову соответствует self. Использование bind в данном контексте гарантирует, что this внутри метода onSearchTextChanged является отсылкой к экземпляру компонента. Дополнительную информацию о ключевом слове this можно получить на MDN.
Прежде чем мы снова обновим приложение, добавим оператор log в начале render(), сразу перед return:
Вам предстоит узнать нечто очень любопытное об этих операторах.
Сохраните изменения, вернитесь в симулятор и нажмите Cmd+R. Вы увидите, что теперь начальным значением поля ввода является ‘london’, а при редактировании текста в консоль Xcode записываются какие-то выражения:

Если вы внимательно посмотрите на скриншот выше, то можете заподозрить, что порядок записи выражений немного нарушен:
1. Это первоначальный вызов render(), необходимый чтобы настроить представление.
2. При изменении текста вызывается onSearchTextChanged().
3. Затем обновляется состояние компонента, чтобы отобразить только что введенный текст, который повторно запускает render.
4. onSearchTextChanged() завершает всё, записывая новую строку поиска.
Когда приложение обновляет состояние любого компонента React, это запускает повторный рендеринг всего пользовательского интерфейса, который, в свою очередь, вызывает render всех компонентов. Это превосходная идея, так как в этом случае логика рендеринга полностью отделяется от изменений состояния, которые затрагивают UI.
В большинстве UI-фреймворков разработчику нужно либо вручную обновлять интерфейс в зависимости от изменений состояния, либо делать это посредством каких-либо вспомогательных фреймворков, которые создают неявную связь между состоянием приложения и его представлением в UI. Что касается второго варианта, по этому поводу можно ознакомиться со статьей о применении шаблона MVVM совместно с фреймворком ReactiveCocoa.
С React вам больше не придется волноваться о том, какие части UI могут быть затронуты изменением состояния, так как весь интерфейс выражается в виде функции состояния приложения.
На данном этапе вы, скорее всего, заметили один изъян данного подхода. Совершенно верно, дело в производительности.
Конечно, нельзя просто так отбрасывать весь интерфейс и перестраивать его каждый раз, когда что-то меняется. Вот где React по-настоящему проявляет себя. Каждый раз, когда интерфейс рендерится, он берет дерево видимых объектов, которое возвращают методы render, и согласовывает его с текущим представлением UIKit. В результате этого согласования получается список обновлений, которые React должен применить к текущему представлению. Таким образом, повторному рендерингу подвергнутся только те объекты, которые на самом деле были изменены.
Разве не здорово видеть, как в нашем iOS-приложении применяются новейшие подходы, за счет которых ReactJS является таким уникальным: virtual-DOM (объектная модель документа, визуальное дерево веб-документа) и согласование?
Позже у вас будет возможность разобраться с этим подробнее, а пока нужно еще поработать над приложением. Для начала удалим код сбора данных, который мы добавили ранее, так как он только засоряет общий код.
Настраиваем поиск
Чтобы реализовать поиск, нужно обработать нажатие кнопки ‘Go’, создать необходимый API-запрос и предоставить пользователю визуальное подтверждение того, что запрос обрабатывается.
Откройте файл SearchPage.js, найдите constructor и обновите внутри него начальное состояние:
Новое свойство isLoading будет следить за тем, обрабатывается ли запрос.
Добавьте такую логику в начале render:
Это тернарный оператор if, который либо добавляет индикатор выполнения действия, либо отображает пустой экран – в зависимости от состояния компонента isLoading. Поскольку весь компонент рендерится каждый раз заново, вы можете спокойно смешивать логику JSX и JavaScript.
Чтобы добавить на страницу индикатор загрузки, перейдите к JSX, отвечающему за интерфейс поиска в return, и вставьте под Image эту строку:
Затем добавьте данные методы в класс SearchPage:
Метод _executeQuery() впоследствии будет выполнять запрос, но пока он просто заносит сообщение в консоль и необходимым образом настраивает компонент isLoading, чтобы в интерфейсе отобразилось новое состояние.
Примечание: Классы в JavaScript не имеют модификаторов доступа, потому ключевого слова ‘private’ для них тоже не существует. В силу этого многие разработчики часто дают методам префикс в виде нижнего подчеркивания, чтобы указать, что они являются private.
Метод onSearchPressed() настраивает и отправляет запрос. Он должен срабатывать по нажатию кнопки ‘Go’. Чтобы реализовать это, вернитесь к render и добавьте следующее свойство внутри открывающего тега компонента TouchableHighlight, отвечающего за текст ‘Go’:
Наконец, добавьте эту служебную функцию над объявлением класса SearchPage:
Эта функция не зависит от SearchPage, потому она реализуется скорее как свободная функция, а не как метод. Сначала она создает строку запроса, основываясь на параметрах данных. Исходя из них, она преобразовывает данные в требуемый формат строки: пары name=value, разделенные амперсандами. Синтаксис => соответствует стрелочной функции, еще одному недавнему дополнению в JavaScript. Стрелочные функции предоставляют более лаконичный синтаксис для создания анонимных функций.
Сохраните изменения, вернитесь к симулятору, перезагрузите страницу с помощью комбинации Cmd+R и нажмите кнопку ‘Go’. На экране отобразится индикатор загрузки. Обратите внимание на консоль Xcode:

На экране показан индикатор активности, а в логе появляется URL для требуемого запроса. Откройте этот URL в браузере, чтобы увидеть результат: большой JSON-объект. Но не волнуйтесь, вам не нужно будет вникать в него. Сейчас мы добавим код и проведем его парсинг.
Примечание: Данное приложение использует для поиска недвижимости Nestoria API. JSON-ответ, который приходит из API, весьма незамысловат. Так или иначе, вы всегда можете просмотреть документацию на предмет предполагаемого формата URL-запросов и ответов.
Следующий шаг – выполнить запрос из приложения.
Выполняем API-запрос
Не закрывая файл SearchPage.js, обновите начальное положение в конструкторе класса, чтобы добавить переменную message:
Найдите render и добавьте внутри него следующую строку:
Она отвечает за отображение внизу экрана сообщений для пользователя.
Найдите класс SearchPage и добавьте в конец метода _executeQuery() данный код:
Он использует функцию fetch, которая является частью Web API и предоставляет значительно улучшенный API по сравнению с XMLHttpRequest. Асинхронный ответ возвращается в виде объекта promise, и в случае успеха выполняется парсинг JSON-объекта, который затем передается в метод _handleResponse (мы добавим его немного позже).
Наконец, добавим эту функцию в SearchPage:
Она очищает isLoading и при успешном запросе добавляет в лог количество найденных объектов недвижимости.
Примечание: В Nestoria API есть ряд весьма полезных кодов ответа сервера. К примеру, коды 202 и 200 возвращают список локаций, подобранных по принципу наилучшего выбора. Почему бы не воспользоваться этой опцией и не предоставить пользователям несколько дополнительных предложений?
Сохраните изменения, вернитесь в симулятор и нажмите Cmd+R. Попробуйте ввести поисковый запрос ‘london’. Вы должны увидеть в логе сообщение о том, что было найдено 20 объектов недвижимости (стандартное для результата количество). А теперь попробуйте ввести неверный запрос, например ‘narnia’. Вы увидите следующее сообщение:

Время поработать над выводом результата поиска на экран.
Выводим результат поиска
Создайте новый файл под названием SearchResults.js и добавьте в него следующее:
Всё верно, это выражение require, включающее модуль react-native и деструктурирующее присваивание.
Затем добавьте сам компонент:
Код выше использует специальный компонент – ListView, который отображает данные внутри контейнера прокрутки в несколько рядов, почти как в UITableView. Данные попадают в ListView через ListView.DataSource и функцию, передающую UI для каждого ряда.
Создавая источник данных, вы предоставляете функцию, которая проверяет на идентичность пару рядов. ListView затем использует результат во время процесса согласования, чтобы выявить изменения в данных списка. В нашем примере Nestoria API возвращает объекты недвижимости со свойством guid, что хорошо подходит для наших целей.
Добавьте в конец файла экспорт модуля:
А эту строку нужно вставить в начале файла SearchPage.js, ниже вызова require для React:
Это позволит нам использовать класс SearchResults изнутри класса SearchPage:
Измените метод _handleResponse, заменив выражение console.log на следующее:
Этот код переходит к компоненту SearchResults и передает объекты недвижимости из API-запроса. Использование push-метода обеспечивает загрузку результатов поиска в стек переходов, вследствие чего у вас появится кнопка ‘Back’, чтобы вернуться в корневой каталог.
Сохраните изменения, вернитесь в симулятор, нажмите Cmd+R и попробуйте выполнить поиск. Вы увидите список объектов недвижимости:

Наконец-то мы получили настоящий список. Правда, выглядит он пока скучновато. Давайте немного преобразим его.
Применяем стилизацию
Постепенно код React Native начинает приобретать знакомый вам вид, поэтому мы немного ускорим темп работы.
Добавим данное определение стиля сразу после деструктурирующего присваивания в файле SearchResults.js:
Здесь содержатся все стили для отображения каждого ряда данных.
Заменим renderRow() следующим кодом:
Этот код обрабатывает данные цен, полученных в формате ‘300,000 GBP’ и убирает оттуда GBP. Затем он отображает строку интерфейса, используя подход, с которым вы, скорее всего, уже хорошо знакомы. Изображение (Image) загружается из возвращенного URL (rowData.img_url), который React Native берет из основного потока, и добавляется в ряд.
Также обратите внимание на использование стрелочной функции в свойстве onPress компонента TouchableHighlight. С ее помощью захватывается guid для ряда.
Последний шаг – добавить этот метод в класс, чтобы управлять нажатием на экран:
Этот метод определяет, какой объект недвижимости был выбран пользователем. Правда, сейчас он не работает, но мы это скоро исправим. А пока любуйтесь результатом.
Сохраните изменения, вернитесь в симулятор и нажмите Cmd+R, чтобы увидеть обновленный список:

Выглядит отлично… если закрыть глаза на цены.
Наконец, пришло время добавить последнюю страницу.
Добавляем страницу просмотра информации о недвижимости
Создайте в проекте новый файл под названием PropertyView.js и введите туда этот код:
Уверен, вы уже способны набрать его даже с закрытыми глазами.
Теперь добавим стили:
И сам компонент:
Часто случается так, что API возвращает данные низкого качества и с пропущенными полями. Потому первая часть render() проводит обработку данных для частичного улучшения их качества.
Остальная его часть весьма очевидна: это функция неизменяемого состояния данного компонента.
Теперь добавим экспорт в конец файла:
Вернитесь к SearchResults.js и добавьте выражение require в начало файла, сразу после строки React require:
Затем обновите rowPressed(), чтобы перемещаться по PropertyView:
Порядок действий вам знаком: сохраняем, возвращаемся в симулятор и нажимаем Cmd+R. Теперь можно выполнить поиск, выбрать любой объект и перейти к просмотру информации о нем:

Эх, вот что я называю доступным жильем!
Приложение почти готово, осталось только добавить опцию поиска по геолокации.
Реализуем поиск по местоположению
Откройте в Xcode файл Info.plist и добавьте напротив NSLocationWhenInUseUsageDescription следующее значение:
Вот как будет выглядеть ваш plist-файл после добавления нового значения:

Это информация, которую приложение будет отображать пользователям при попытке запросить их местоположение.
Откройте SearchPage.js, перейдите к компоненту TouchableHighlight, отвечающему за отображение кнопки ‘Location’, и добавьте это значение:
По нажатию кнопки вызывается метод onLocationPressed (мы сейчас его добавим).
Вставьте внутрь класса SearchPage следующий код:
Данные о текущем местоположении берутся с помощью navigator.geolocation. Это интерфейс Web API, потому он должен быть понятен каждому, кто имел дело с браузерными сервисами определения геолокации. React Native предоставляет собственную реализацию данного API, используя нативные средства iOS.
В случае успешного определения текущего местоположения будет вызвана первая стрелочная функция. Она отправит запрос в Nestoria. Если же что-то пойдет не так, отобразится стандартное сообщение.
Так как мы редактировали plist, потребуется перезапустить приложение, чтобы увидеть изменения. На этот раз, увы, без Cmd+R. Остановите приложение в Xcode и выполните его повторную сборку. Затем запустите проект.
Прежде чем использовать поиск по геолокации, стоит убедиться, что база данных Nestoria содержит информацию о вашем регионе. Выберите в меню симулятора Debug\Location\Custom Location … и введите широту с долготой: к примеру, 55.02 и -1.42 соответственно. Это координаты одного живописного городка на побережье северной части Англии, откуда я родом.
Теперь нажмите кнопку Location, разрешите приложению определять местоположение и смотрите результат.

Примечание от Рэя: Поиск по местоположению сработал не у всех. Как правило, возникала ошибка доступа, несмотря на то, что определение местоположения было разрешено. Мы пока не до конца разобрались с этой ситуацией. Возможно, это проблема самого React Native. Если кому-либо удалось исправить эту ошибку, пожалуйста, напишите нам.
Конечно, это не Лондон, но цены гораздо приятнее.
Поздравляю с созданием вашего первого приложения на React Native. Вы можете скачать себе весь проект, если хотите просмотреть мой код.
Если вы веб-разработчик, теперь вам должно быть понятнее, как можно без труда создать полностью нативный интерфейс и навигацию приложения, используя JavaScript и React. Если вы разработчик нативных приложений, надеюсь, вы оценили по достоинству такие преимущества React Native, как быстрое взаимодействие с приложением, современный JavaScript и понятные правила стилизации в духе CSS.
Возможно, ваше следующее приложение будет написано на этом фреймворке? А может быть, вы всё равно продолжите работать со Swift или Objective-C? Так или иначе, надеюсь, вам удалось найти в этой статье что-нибудь новое и полезное для будущих проектов.
Если же у вас есть вопросы или комментарии по поводу данного урока, присоединяйтесь к обсуждению.
How to Create Android & iOS Mobile App using HTML, CSS & JavaScript
Apache Cordova is an open-source mobile development framework. It allows you to use standard web technologies such as HTML5, CSS3, and JavaScript for cross-platform development, avoiding each mobile platform native development language. Applications execute within wrappers targeted to each platform, and rely on standards-compliant API bindings to access each device’s sensors, data, and network status.”
If you want to learn how to develop Android & iOS Mobile apps using HTML, CSS, JS & Apache Cordova then enroll in my course here with 90% discount.
In this blog post, I’ll show you how to Create your first Cordova Project for Android, iOS, Browser, and Desktop using HTML, CSS, and JavaScript.
By Cross-Platform, we mean that the application codebase can be written once using HTML5, CSS3 & JavaScript and it can be run across multiple target mobile platforms such as Android, iOS, Windows, Firefox, Ubuntu mobile.
The web development community has been continually innovating and with the recent development of frameworks such as Angular, IONIC, jQuery and React, the traditional web applications have now almost become indistinguishable from their native platform-specific peers in terms of functionality.
Apache Cordova can be extended with native plug-ins, allowing developers to add more functionalities that can be called from JavaScript, making it communicate directly between the native layer and the HTML5 page. These plugins allow access to the device’s accelerometer, camera, compass, file system, microphone, and more.
However, the use of Web-based technologies leads some Apache Cordova applications to run slower than native applications with similar functionality.
And the most important thing is: Cordova is free and open source. Here’s how to get started with Apache Cordova.
Use Apache Cordova if you are:
- a mobile developer and want to extend an application across more than one platform, without having to re-implement it with each platform’s language and toolset.
- a web developer and want to deploy a web app that’s packaged for distribution in various app store portals.
- a mobile developer interested in mixing native application components with a WebView (special browser window) that can access device-level APIs, or if you want to develop a plugin interface between native and WebView components.
If you would like to watch and learn from video then you must watch on YouTube and also subscribe to the “Instill Learning” YouTube channel for a future tutorial.
Prerequisite
Before creating a new Cordova App, there are few prerequisites and you have to install this software:
*Node.js (npm comes with Node.js) [ https://nodejs.org/en/ ]
*Cordova [after installing node.js, you can install cordova through command line or terminal by using following command “npm install -g cordova“] [ https://cordova.apache.org/#getstarted ]
Step 1: Create a new Cordova App
cordova create DeviceInfo info.androidabcd.deviceinfo DeviceInfoSample
After creating the new app, move to Cordova project folder
Step 2: Add the Android platform
cordova platform add android@latest
Step 3: Add plugin to get device information
cordova plugin add cordova-plugin-device
By using this plugin you get the following device information:
- device.cordova
- device.model
- device.platform
- device.uuid
- device.version
- device.manufacturer
- device.isVirtual
- device.serial
Step 4: Open code in Visual Studio Code Editor
If you haven’t install visual studio code then download and install from here: https://code.visualstudio.com/
You can open the Cordova project from the command line or terminal by typing ” code . ” [code space dot], or you can directly drag & drop the project into visual studio code.

Step 5: Edit index.html in www folder
Step 6: Edit index.js in www folder
Step 7: Edit index.css in www folder
Step 8: Prepare the Cordova project
After editing the source code in www folder, you must prepare the code, so that it can distribute to all platforms you have added. to prepare the source code type following command in the command line or terminal:
Step 9: Build Cordova Project
Once you build your Cordova project, you will notice that it will generate APK File and that you can install it manually in any Android device. Or if you want to install the app using the command line then see the next step.