Создание мобильного приложения Kotlin с помощью Salesforce SDK: редактирование и создание данных — часть 2
6 марта 2022 г.Во второй части нашей серии, состоящей из трех частей, мы продолжаем опираться на основы разработки под Android с помощью Salesforce Mobile SDK. [В первой части] (https://hackernoon.com/building-a-kotlin-mobile-app-with-the-salesforce-sdk) мы рассмотрели настройку проекта и создание макета, который извлекает данные из Salesforce, используя Kotlin в качестве наш язык программирования по выбору.
Прежде чем мы продолжим разработку полной стратегии мобильной синхронизации, мы сначала создадим наше мобильное приложение, позволяющее редактировать и создавать данные в нашей организации Salesforce.
Редактирование данных
Установив представление, давайте посмотрим, как мы можем редактировать данные. В идеале мы хотим сохранить тот же формат списка, но сделать его таким, чтобы, если пользователь коснется имени, он мог его отредактировать. Затем эти изменения должны быть отправлены обратно в Salesforce.
Для этого нам нужно сделать несколько вещей. Во-первых, нам нужно переопределить поведение списка по умолчанию, чтобы сделать элементы редактируемыми. Затем, после завершения редактирования записи, нам нужно сделать вызов API Salesforce для обновления данных.
Как и прежде, начнем с макета. Создайте файл в app/res/layout
с именем broker_item.xml
и вставьте в него следующие строки:
<линейный макет
xmlns:android="http://schemas.android.com/apk/res/android"
андроид: ориентация = "вертикальный"
Android: layout_width = "fill_parent"
андроид: layout_height="fill_parent">
<EditText android:id="@+id/broker_field"
Android: layout_width = "fill_parent"
android:layout_height="wrap_content"
Затем создайте файл в app/java/com.example.sfdc с именем BrokerListAdapter.kt и вставьте в него это:
пакет com.example.sfdc
импортировать android.content.Context;
импортировать android.text.Editable;
импортировать android.text.TextWatcher;
импортировать android.view.LayoutInflater;
импортировать android.view.View;
импортировать android.view.ViewGroup;
импортировать android.widget.ArrayAdapter;
импортировать android.widget.EditText;
импортировать com.salesforce.androidsdk.rest.BrokerItemBinding
импортировать com.salesforce.androidsdk.rest.ApiVersionStrings
импортировать com.salesforce.androidsdk.rest.RestClient
импортировать com.salesforce.androidsdk.rest.RestRequest
импортировать com.salesforce.androidsdk.rest.RestResponse
класс BrokerListAdapter : ArrayAdapter
внутренний переменный контекст: Контекст
Частный поздний вход var brokerItemBinding: BrokerItemBinding
частный клиент var: RestClient? = ноль
частный val nameToId: MutableMap
конструктор (контекст: контекст): супер (контекст, R.layout.broker_item, ArrayList
этот.контекст = контекст;
весело setClient (клиент: RestClient?) {
this.client = клиент
забавная карта (имя: строка, идентификатор: строка) {
this.nameToId.put(имя, идентификатор)
переопределить fun getView (position: Int, convertView: View?, parent: ViewGroup): View {
val inflater = контекст
.getSystemService(Context.LAYOUT_INFLATER_SERVICE) как LayoutInflater
BrokerItemBinding = BrokerItemBinding.inflate(inflate)
val rowView: View = inflater.inflate(R.layout.broker_item, parent, false)
значение BrokerField = BrokerItemBinding.brokerField
var item = getItem(позиция)
var brokerId = nameToId.get(item)
val поля: MutableMap
BrokerField.setText (элемент)
BrokerField.addTextChangedListener (объект: TextWatcher {
переопределить удовольствие перед TextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
переопределить fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
переопределить удовольствие afterTextChanged(s: Editable) {
элемент = BrokerField.text.toString()
fields.put("Имя", элемент!!)
val restRequest = RestRequest.getRequestForUpdate(ApiVersionStrings.getVersionNumber(контекст), "Broker__c", brokerId,
поля как Map
клиент?.sendAsync (restRequest, объект: RestClient.AsyncRequestCallback {
переопределить удовольствие при успехе (запрос: RestRequest, результат: RestResponse) {}
переопределить удовольствие при ошибке (исключение: исключение) {}
вернуть rowView
В экосистеме Android адаптер определяет функциональность элемента пользовательского интерфейса. Здесь мы создали новый адаптер, который переопределяет определенное поведение ArrayAdapter. Мы добавили функцию под названием setClient
, которая повторно использует тот же самый клиент Salesforce API, который нам нужен для заполнения списка в MainActivity
. Функция «карта» связывает имя брокера с его пользовательским идентификатором объекта — причина, по которой это происходит, скоро станет очевидной.
getView
— это место, где происходит основная часть активности. Самая важная строка связана с RestRequest.getRequestForUpdate
. Клиент вызывает это для обновления данных Salesforce; для этого требуется имя пользовательского объекта, его идентификатор и значение для замены (в данном случае имя). Это событие происходит, когда срабатывает afterTextChanged
; то есть после того, как пользователь завершил обновление имени брокера. В реальной производственной среде вам необходимо проверить коды состояния для потенциальных ошибок из API, но для краткости мы опустили какие-либо проверки ответов.
В MainActivity
нам нужно использовать этот адаптер. Во-первых, в верхней части определения класса измените listAdapter
на BrokerListAdapter
вместо ArrayAdapter
, например:
класс MainActivity : SalesforceActivity() {
частный клиент var: RestClient? = ноль
частный var listAdapter: ArrayAdapter
частный lateinit var listAdapter: BrokerListAdapter
Модификатор lateinit
позволяет вам инициализировать ненулевой тип вне конструктора. Затем замените две функции onResume
на эти:
переопределить удовольствие onResume() {
// Скрыть все, пока мы не авторизуемся
mainViewBinding.root.visibility = Вид.НЕВИДИМЫЙ
// Создаем адаптер списка
listAdapter = BrokerListAdapter(этот)
mainViewBinding.brokersList.adapter = listAdapter
супер.onResume()
переопределить удовольствие onResume (клиент: RestClient) {
// Сохраняем ссылку на оставшийся клиент
this.client = клиент
listAdapter.setClient(клиент)
// Показать все
mainViewBinding.root.visibility = View.VISIBLE
sendRequest("ВЫБЕРИТЕ имя, идентификатор ОТ Broker__c")
Наконец, нам нужно отслеживать настоящее имя брокера вместе с его идентификатором записи. Для этого мы можем просто сохранить его в словаре, поддерживаемом BrokerListAdapter
. В sendRequest
замените цикл for на этот:
для (i в 0..records.length() - 1) {
listAdapter.add(records.getJSONObject(i).getString("Имя"))
listAdapter.map(records.getJSONObject(i).getString("Имя"), records.getJSONObject(i).getString("Id"))
Идите вперед и запустите приложение, и элементы вашего списка можно будет редактировать. Внесите изменения, а затем приготовьтесь, потому что все вот-вот станет диким. Вернитесь в свою временную организацию и щелкните вкладку Брокеры в приложении Dreamforce. Ваши изменения должны быть отражены здесь на платформе Salesforce!
Добавление данных
Мы можем редактировать записи, но что, если нам нужно добавить нового брокера? Формат для этого очень похож на логику, которую мы использовали для выборки и редактирования записей. Давайте быстро пройдемся по шагам.
Откройте main.xml и вставьте эти строки прямо перед ListView
:
<LinearLayout андроид: ориентация = "горизонтальный"
Android: layout_width = "match_parent"
android:layout_height="wrap_content"
андроид: фон = "? андроид: цветной фон"
андроид: layout_marginStart = "10dp"
android:layout_marginEnd="10dp"
андроид: layout_marginTop = "10dp"
андроид: layout_marginBottom="10dp">
<Кнопка
android:id="@+id/add_broker"
Android: layout_width = "0dp"
андроид: layout_height = "47dp"
Android: onClick="onAddBrokerClick"
android:text="Добавить брокера"
Android: фон = "? android: colorPrimary"
android:textColor="?attr/sfColorSecondary"
андроид: layout_gravity = "центр"
андроид: layout_weight = "1"
android:layout_marginEnd="10dp"/>
Здесь мы добавили кнопку, которая будет вызывать функцию onAddBrokerClick при каждом ее нажатии. В MainActivity
мы определим этот метод:
весело onAddBrokerClick(v: View) {
listAdapter.add("Новый брокер")
var fields: Map
"Title__c" на "Младший брокер",
"Телефон__c" на "555-555-1234",
"Mobile_Phone__c" на "555-555-1234",
"Электронная почта__c" на "todo@salesforce.com",
«Picture__c» на «https://cdn.iconscout.com/icon/free/png-256/salesforce-282298.png»)
val restRequest = RestRequest.getRequestForUpsert(ApiVersionStrings.getVersionNumber(this), "Broker__c", "Id", null, поля)
клиент?.sendAsync (restRequest, объект: AsyncRequestCallback {
переопределить удовольствие при успехе (запрос: RestRequest, результат: RestResponse) {}
переопределить удовольствие при ошибке (исключение: исключение) {}
Да это оно! Те поля, которые мы определили, относятся непосредственно к пользовательскому объекту. Установив для Id
значение null, мы сообщаем API, что это новая запись. Если вы добавите новую строку, отредактируете ее, а затем вернетесь в свою временную организацию, вы увидите, что новые данные появятся в сети.
Продолжение следует…
Основываясь на том, что мы сделали в прошлый раз, в этом посте мы смогли отредактировать и добавить данные брокера в наше мобильное приложение, а затем увидеть их отражение в Salesforce. Довольно аккуратно!
Однако это только одностороннее изменение данных — из приложения в организацию. Как насчет отправки данных из организации в приложение? Кроме того, как мы можем решить сетевые проблемы, характерные только для мобильных телефонов, такие как проблемы с подключением или одновременное изменение полей несколькими людьми? Мы рассмотрим эти очень реальные проблемы в нашем заключительном посте!
- Впервые опубликовано [здесь] (https://dev.to/mbogan/building-a-kotlin-mobile-app-with-the-salesforce-sdk-editing-and-creating-data-1pb6)*
Оригинал