Editor action callback android

Create callback function in Android

In Android, you have to write lots of code for some actions. To reduce lines of code we use functions and classes to reuse the code but sometimes we need the callback of function. So here I will tell how to create the callback with an example.

Let take an example in Android, in most places we need a confirm dialog to confirm any action like delete the record, leave the page etc. The traditional way to do it create a confirm dialog and write code of confirm dialog positive callback. But this might take 13-15 lines to write the code. See the code snippet below:

Here you can see 15 lines of code required to confirm an action. Now we will create a function in our MyHelper class to confirm an action and this function will be reusable anywhere in the whole application.

In the above class, we have created the confirmDialog function that has a callback. The callback will be trigger when the user clicks on the confirm button.

In Android, we need Interface to create the callback. In our Example, we have created MyCallback Interface that has one method callbackCall. In the function confirmDialog we passed the callback object in the last and call the callback object’s function on Dialog button press: callback.callbackCall(); .

Now we will use this function in our activity as below:

As you can see here to confirm the action we need to write only 4 lines of code. confirmDialog function has the callback where you can write your code for your action.

Источник

Android programmers blog

Simply about difficult

Поиск по этому блогу

понедельник, 5 октября 2015 г.

Callback’и в Android

Еще решил написать одну заметку по поводу коллбеков. Штука интересная и полезная, без нее редко когда получается что то разумное написать. По этому решил что надо будет написать пару примеров по работе с колбеками.

Для начала хочу сказать что есть разные библиотеки типа EventBus и OttoBus которые сделают всю работу за вас и еще больше сделают… Но иногда эти библиотеки сильно много делают для обычной тривиальной задачи, например вернуть респонс из AsyncTask’a или еще что-то похожее, из-за этого использовать эти библиотеки не целесообразно и достаточно написать один интерфейс и вызывать его в нужном месте по тому или иному событию. Собственно это я сегодня и хочу продемонстрировать на примере приложения.

У нас будет небольшой апп который будет тянуть список спорт. каналов через AsyncTask, парсить то что вернет сервер с помощью кастомного JsonArray и JsonObject и отдавать это все колбеком в активити для отображения в списке.

Для начала давайте сделаем небольшую настройку. Для работы с интернетом нам нужен премишен в манифесте, давайте его добавим.

И сделаем разметку с списком, все будет елементарно и просто.

Все, с настройками мы закончили, теперь давайте кодить!

Первый вариант Callback’a, получение данных в Activity

Первый вариант у нас будет такой как я описал выше, он имеет вот такую архитектуру:

Это очень краткий пример того что будет происходить. Создаем интерфейс, далее в классе который нам должен что-то вернуть вызываем этот колбек что бы можно было отследить когда он выполнился, а после этого отображаем то что вернул колбек в нашей активити которая включает в себя собственно этот колбек.

Очень сумбурно, нам нужно более детальное рассмотрение этого способа по этому начну.

У вас должен уже быть создан пустой проект с MainActivity, нам она пока не понадобится, мы ее будем использовать в в самом конце.

Читайте также:  Получит ли poco x3 pro андроид 12

Сейчас создайте новый класс который будет называться BackgroundTask, в этом методе у нас будет AsyncTask который у нас будет хватать json строку с удаленного сервера.

Вообще использовать AsyncTask не советую, для таких нужд есть прекрасная библотека Retrofit или Volley или еще куча разных великолепных библиотек которые делают запросы и не валятся при повороте экрана. По этому это чисто пример, так как я сделал запрос лучше не делать, повторюсь, лучше используйте готовые решения.

Вот как то так у нас будет работать наш AsyncTask, но пока что вам не хватает нескольких классов которые выполняют кое какую работу, давайте их напишем что бы все заработало. Нам не хватает интерфейса ResponseCallback, так давайте создадим его.

Так же нам не хватает ChannelsModel, давайте и его создадим.

А еще нам не хватает ChannelsParser который парсит нашу json возвращенную с сервера. Держите, мне не жалко!

Вот! Вроде бы картинка у нас обрисовалась и все нужные классы были созданы. Теперь нам нужно все это собрать в одно, отобразить наш заветный список на экране. Разметка у нас уже готова по-этому нам осталось сделать адаптер и вызвать его в MainActivity. Вот это мы сейчас и сделаем, создаем еще один класс ChannelsAdapter и заполняем его.

Так, тут все просто я думаю все сталкивались с кастомными адаптерами по этому сильно вникать не буду. Если же не сталкивались то у меня в блоге есть статья где я описываю создание кастомного адаптера. Вернемся к функциям, в адаптере мы принимаем ArrayList с данными и отображаем его в TextView который я беру из ресурсов android’a. Собственно и все. Давайте уже наконец закончим и вызовем это все в MainActivity.

Вот так вот просто на примере можно увидеть как работают коллбеки. Но это не все, еще есть второй вариант колбеков которые работают через Setters и Getters. Я на примере этой же программы покажу как это делается, там так же ничего сложного нет.

Второй вариант Callback’a, работа через setters и getters

Как и с первым вариантом во втором я приведу абстрактный пример того как он должен выглядеть в кратце.

Интерфейс можно создавать где угодно и как угодно, по этому не обязательно его выносить в отдельный класс, можно создать как внутри активити или асинк таска так и внутри адаптера и любого другого класса. Создается интерфейс, объявляется, дальше вызывается его инстанс, то есть метод который должен отработать во время евента. А потом в Activity или Fragment’e идет вызов этого метода и получение нужных данных из него. В общем пример опять сумбурный, сейчас на примере нашей программы сделаем и будет все понятно.

Для начала в нашем адаптере нужно создать интерфейс. В самом низу класса пишем вот такое:

Дальше нам надо создать setter для этого интерфейса что бы можно было вызывать его во время создания адаптера и передавать туда наш колбек.

Теперь в getView пишем onClickListener для создания евента клика по айтему:

Вот так должен выглядеть адаптер в целом

А теперь нам нужно перенести в MainActivity этот функционал. Для этого нам нужно присвоить адаптеру новый сеттер и передать туда новый объект нашего коллбека.

В целом MainActivity должна выглядить таким образом

Вот так вот при использовании коллбеков можно достичь дзена. Надеюсь все было понятно так как пока я это писал меня двадцать пять раз отвлекли и я все эти разы терял мысль по этому возможно что то может быть черезчур запутано, спрашивайте если что то не понятно. В любом случае есть исходники рабочие, по ним так точно можно разобраться (:

Источник

Editor actions

Use Action objects to build interactive behavior into Google Workspace Add-ons.

Action objects define what happens when a user interacts with a widget (for example, a button) in the add-on UI.

Add an action to a widget

To attach an action to a widget, use a widget handler function, which also defines the condition that triggers the action. When triggered, the action executes a designated callback function. The callback function is passed an event object that carries information about the user’s client-side interactions. You must implement the callback function and have it return a specific response object.

Читайте также:  Как настроить андроид тв без пульта

Example: Display a new card when a button is clicked

If you want to add a button to your add-on that builds and displays a new card when clicked, follow the steps below:

  1. Create a new button widget.
  2. To set a card-building action, add the button widget handler function setOnClickAction(action) .
  3. Create an Apps Script callback function to execute and specify it as the (action) within the widget handler function. In this case, the callback function should build the card you want and return an ActionResponse object. The response object tells the add-on to display the card the callback function built.

The following example shows the creation of a button widget. The action requests the drive.file scope for the current file on behalf of the add-on.

File access interactions for REST APIs

Google Workspace Add-ons that extend the Editors and use REST APIs can include an additional widget action to request file access. This action requires the associated action callback function to return a specialized response object:

Action attempted Callback function should return
Request file access for current_document EditorFileScopeActionResponse

To make use of this widget action and response object, all of the following must be true:

  • The add-on uses REST APIs.
  • The add-on presents the request file scope dialog using the CardService.newEditorFileScopeActionResponseBuilder().requestFileScopeForActiveDocument().build(); .
  • The add-on includes the https://www.googleapis.com/auth/drive.file Editor scope in its manifest.

Request file access for current document

To request file access for the current document, follow these steps:

  1. Build a homepage card that checks whether the add-on has drive.file scope.
  2. For cases where the add-on hasn’t been granted drive.file scope, build a way to request that users grant drive.file scope for the current document.

Example: Get current document access in Google Docs

The following example builds an interface for Google Docs that displays the size of the current document. If the add-on doesn’t have drive.file authorization, it displays a button to initiate the file scope authorization.

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies. Java is a registered trademark of Oracle and/or its affiliates.

Источник

ActivityLifecycleCallbacks — слепое пятно в публичном API

С детства я люблю читать инструкции. Я вырос, но меня до сих пор удивляет то, как взрослые люди безалаберно относятся к инструкциям: многие из них считают, что все знают, и при этом пользуются одной-двумя функциями, в то время как их намного больше! Кто из вас пользовался функцией поддержания температуры в микроволновке? А она есть почти в каждой.

Однажды я решил почитать документацию к различным классам Android framework. Пробежался по основным классам: View, Activity, Fragment, Application, — и меня очень заинтересовал метод Application.registerActivityLifecycleCallbacks() и интерфейс ActivityLifecycleCallbacks. Из примеров его использования в интернете не нашлось ничего лучше, чем логирование жизненного цикла Activity. Тогда я начал сам экспериментировать с ним, и теперь мы в Яндекс.Деньгах активно используем его при решении целого спектра задач, связанных с воздействием на объекты Activity снаружи.

Что такое ActivityLifecycleCallbacks?

Посмотрите на этот интерфейс, вот как он выглядел, когда появился в API 14:

Возможно, этому интерфейсу уделяют так мало внимания, потому что он появился только в Android 4.0 ICS. А зря, ведь он позволяет нативно делать очень интересную вещь: воздействовать на все объекты Activity снаружи. Но об этом позже, а сначала внимательнее посмотрим на методы.

Каждый метод отображает аналогичный метод жизненного цикла Activity и вызывается в тот момент, когда метод срабатывает на какой-либо Activity в приложении. То есть если приложение запускается с MainActivity, то первым мы получим вызов ActivityLifecycleCallback.onActivityCreated(MainActivity, null).

Отлично, но как это работает? Тут никакой магии: Activity сами сообщают о том, в каком они состоянии. Вот кусочек кода из Activity.onCreate():

Это выглядит так, как если бы мы сами сделали BaseActivity. Только коллеги из Android сделали это за нас, еще и обязали всех этим пользоваться. И это очень даже хорошо!

В API 29 эти методы работают почти так же, но их Pre- и Post-копии честно вызываются до и после конкретных методов. Вероятно, теперь этим управляет ActivityManager, но это только мои догадки, потому что я не углублялся в исходники достаточно, чтобы это выяснить.

Как заставить ActivityLifecycleCallbacks работать?

Как и все callback, сначала их надо зарегистрировать. Мы регистрируем все ActivityLifecycleCallbacks в Application.onCreate(), таким образом получаем информацию обо всех Activity и возможность ими управлять.

Небольшое отступление: начиная с API 29 ActivityLifecycleCallbacks можно зарегистрировать еще и изнутри Activity. Это будет локальный callback, который работает только для этого Activity.

Вот и все. Но это вы можете найти, просто введя название ActivityLifecycleCallbacks в строку поисковика. Там будет много примеров про логирование жизненного цикла Activity, но разве это интересно? У Activity много публичных методов (около 400), и все это можно использовать для того, чтобы делать много интересных и полезных вещей.

Что с этим можно сделать?

А что вы хотите? Хотите динамически менять тему во всех Activity в приложении? Пожалуйста: метод setTheme() — публичный, а значит, его можно вызывать из ActivityLifecycleCallback:

Повторяйте этот трюк ТОЛЬКО дома
Какие-то Activity из подключенных библиотек могут использовать свои кастомные темы. Поэтому проверьте пакет или любой другой признак, по которому можно определить, что тему этой Activity можно безопасно менять. Например, проверяем пакет так (по-котлиновски =)):

Пример не работает? Возможно, вы забыли зарегистрировать ThemeCallback в Application или Application в AndroidManifest.

Хотите еще интересный пример? Можно показывать диалоги на любой Activity в приложении.

Повторяйте этот трюк ТОЛЬКО дома
Конечно же, не стоит показывать диалог на каждом экране — наши пользователи не будут нас любить за такое. Но иногда может быть полезно показать что-то такое на каких-то конкретных экранах.

А вот еще кейс: что, если нам надо запустить Activity Тут все просто: Activity.startActivity() — и погнали. Но что делать, если нам надо дождаться результата после вызова Activity.startActivityForResult()? У меня есть один рецепт:

В примере мы просто закидываем Fragment, который запускает Activity и получает результат, а потом делегирует его обработку нам. Будьте осторожны: тут мы проверяем, что наша Activity является AppCompatActivity, что может привести бесконечному циклу. Используйте другие условия.

Усложним примеры. До этого момента мы использовали только те методы, которые уже есть в Activity. Как насчет того, чтобы добавить свои? Допустим, мы хотим отправлять аналитику об открытии экрана. При этом у наших экранов свои имена. Как решить эту задачу? Очень просто. Создадим интерфейс Screen, который сможет отдавать имя экрана:

Теперь имплементируем его в нужных Activity:

После этого натравим на такие Activity специальные ActivityLifecycleCallback’и:

Видите? Мы просто проверяем интерфейс и, если он реализован, отправляем аналитику.

Повторим для закрепления. Что делать, если надо прокидывать еще и какие-то параметры? Расширим интерфейс:

Но это все еще легко. Все это было только ради того, чтобы подвести вас к по-настоящему интересной теме: нативное внедрение зависимостей. Да, у нас есть Dagger, Koin, Guice, Kodein и прочее. Но на небольших проектах они избыточны. Но у меня есть решение… Угадайте какое?

Допустим, у нас есть некоторый инструмент, вроде такого:

Закроем его интерфейсом, как взрослые программисты:

А теперь немного уличной магии от ActivityLifecycleCallbacks: мы создадим интерфейс для внедрения этой зависимости, реализуем его в нужных Activity, а с помощью ActivityLifecycleCallbacks найдем его и внедрим реализацию CoolToolImpl.

Не забудьте зарегистрировать InjectingLifecycleCallbacks в вашем Application, запускайте — и все работает.

И не забудьте протестировать:

Но на больших проектах такой подход будет плохо масштабироваться, поэтому я не собираюсь отбирать ни у кого DI-фреймворки. Куда лучше объединить усилия и достигнуть синергии. Покажу на примере Dagger2. Если у вас в проекте есть какая-то базовая Activity, которая делает что-то вроде AndroidInjection.inject(this), то пора ее выкинуть. Вместо этого сделаем следующее:

  1. по инструкции внедряем DispatchingAndroidInjector в Application;
  2. создаем ActivityLifecycleCallbacks, который вызывает DispatchingAndroidInjector.maybeInject() на каждой Activity;
  3. регистрируем ActivityLifecycleCallbacks в Application.

И такого же эффекта можно добиться с другими DI-фреймворками. Попробуйте и напишите в комментариях, что получилось.

Источник

Читайте также:  Увеличить чувствительность микрофона гарнитуры андроид
Оцените статью