Как отрегулировать прозрачность виджетов xiaomi

К сожалению, страница, которую вы ищете, недоступна.
Но у нас по-прежнему есть несколько отличных товаров специально для вас
Новости Xiaomi
Подписаться на рассылку

Скачайте приложение Xiaomi Store
Самые актуальные предложения для лучших покупок
Copyright © 2010 — 2023 Xiaomi. All Rights Reserved
Настройка рабочего стола — большая инструкция
В MIUI, на телефонах Xiaomi, нет привычного всем пользователям Android меню. Вместо него, есть рабочие столы, на которых расположены все установленные приложения. Сначала, это кажется довольно неудобным. Но, спустя некоторое время, ты уже не хочешь возвращаться к прежнему меню.
Чтобы вызвать настройки рабочего стола, необходимо сделать щипок двумя пальцами на рабочем столе от краев к центру. Это движение точно такое же, как-будто вы хотите уменьшить изображение в галереи.

1. Меню рабочего стола
В настройках рабочего стола последних версий MIUI, есть 4 основных пункта. Начнем по порядку, слева направо:
Темы
Здесь мы можем выбрать тему оформления вашего устройства. Это меню дублирует то, которое расположено по пути Настройки—>Темы. Останавливаться подробно на нем не будем. Думаю и так все понятно.


Виджеты
Виджет — это часть приложения или самостоятельное приложение, которое может быть размещено на рабочем столе и содержать какую-либо информацию. Например, погода, часы, курсы валют, новости и прочее. Они упрощают доступ к настройкам и переключателям.
Чтобы поместить виджет на рабочий стол, необходимо зайти в «Виджеты» и выбрать нужный нам.

К примеру, выведем виджет, с помощью которого можно включать и выключать Wi-Fi:
-
Выбираем Настройки—>Wi-Fi. И переключатель сети Wi-Fi окажется на рабочем столе.



Теперь вы можете получить к нему доступ очень быстро.
Таким способом, вы можете вывести любой виджет на рабочий стол. Их достаточно много даже на только что приобретенном телефоне. А после установки приложений, станет еще больше.
Чтобы удалить виджет, просто нажмите на него и удерживайте некоторое время, а затем, не отпуская, перетащите его в верхнюю часть экрана, на значек корзины. Таким же образом, можно удалить любую иконку с рабочего стола.

Естественно, вы всегда сможете его вернуть, зайдя в раздел «Виджеты».
Обои
Здесь вы можете выбрать обои рабочего стола и экрана блокировки. Список стандартный. Однако, вы можете открыть вкладку «Онлайн» и загрузить понравившееся.


Эффекты
Это эффекты, которые будут возникать при пролистывании рабочих столов. Например, «поворот», «каскад», «вращение», «3d куб» и др. Попробуйте выбрать любой из них и перейти от одного стола к другому.


2. Добавление нового рабочего стола
При заполнении рабочего стола значка приложений, автоматически создается новый стол. Но, если мы хотим создать его самостоятельно, то нужно:
- Сделать щипок двумя пальцами и пролистать все рабочие столы до конца, влево или вправо. А затем, просто нажать на иконку «плюс». Так мы создали новый рабочий стол.


Есть еще один способ добавления стола. О нем будет рассказано в следующем пункте. О том, как добавить новый рабочий стол MIUI9, можно прочитать здесь.
3. Выбор главного рабочего стола
Если у вас несколько рабочих столов, то при нажатии на сенсорную кнопку «Домой», по умолчанию, всегда открывается первый. Но, что делать, если вам нужно, чтобы открывался, например второй или любой другой. Для этого нужно назначить главный рабочий стол:
-
Делаем щипок тремя пальцами (не двумя, как ранее). Появится новое меню, на котором отображены все ваши рабочие столы.



Нажав на рабочий стол с «Плюсом», мы добавим новый стол так же, как сделали это в пункте 2.

Здесь же, мы можем менять рабочие столы места. Для этого, нажмите на любой из них и переместите в нужное место.
4. Сортировка иконок на рабочем столе
Есть 2 способа сортировки иконок:
- В пределах одного стола. Для этого, просто нажмите и удерживайте палец на иконке, а затем переместите ее в нужное место.
- Перемещение на другой рабочий стол. Для этого:



5. Создание новой папки
Для этого, так же есть два способа:
-
Зажать любую иконку рабочего стола и переместить ее на другую иконку. Тем самым, они окажутся в папке.


Чтобы переименовать папку, заходим в нее и щелкаем на название. Задаем любое.

Папки удаляются так же, как и другие иконки.
На этом, все. Надеюсь, статья будет полезна новичкам.
Виджеты на Android. Редкая фича, в которой придется разобраться
Привет, Хабр! Меня зовут Александр Хакимов, я android-разработчик в компании FINCH.
У вас бывало такое, что ваш дизайн был под iOS, а вам приходится адаптировать его под android? Если да, то часто ли ваши дизайнеры используют виджеты? К сожалению, виджет — редкий кейс для многих разработчиков, потому что с ним редко кто работает,
В статье я подробно расскажу как создать виджет, на что стоит обратить внимание и поделюсь своим кейсом.
Создание виджета
Для создания виджета нужно знать:
- Особенности компонентов виджета.
- Особенности отображения виджета в сетке экрана.
- Особенности обновления виджета.
Особенности компонентов виджета
С этим пунктом знаком любой разработчик, который хоть раз работал с RemoteViews. Если вы из таких, смело переходите к следующему пункту.
RemoteViews предназначен для описания и управления иерархиями Views, которые принадлежат процессу другого приложения. С помощью управления иерархиями можно изменять свойства или вызывать методы, принадлежащие View, которое выступает частью другого приложения. В RemoteViews входит ограниченный набор компонентов стандартной библиотеки компонентов android.widget.
View внутри виджетов работают в отдельном процессе (как правило, это домашний экран), поэтому для изменения UI виджета используется расширение BroadcastReceiver — AppWidgetProvider, работающий в нашем приложении.
Особенности отображения виджета в «сетке» экрана
На самом деле, этот пункт не такой уж и сложный, если заглянуть в официальные гайдлайны:
Each widget must define a minWidth and minHeight, indicating the minimum amount of space it should consume by default. When users add a widget to their Home screen, it will generally occupy more than the minimum width and height you specify. Android Home screens offer users a grid of available spaces into which they can place widgets and icons. This grid can vary by a device; for example, many handsets offer a 4×4 grid, and tablets can offer a larger, 8×7 grid.
Переводя на русский: каждый виджет должен задать свои минимальную ширину и высоту, чтобы обозначить минимальное пространство, которое будет им занято по умолчанию.

Пример настроек виджета при создании в Android Studio
Виджет, который добавили на на Home screen, обычно займет больше места чем минимальные ширина и высота экрана, которые вы задали. Android Home screens предоставляет пользователям сетку доступного пространств, в которых могут быть расположены виджеты и иконки. Эта сетка может отличаться в зависимости от устройства; например, многие телефоны предлагают сетку 4х4, а планшеты могут предложить большие сетки 8х7.
Из этого становится понятно, что сетка устройства может быть какой угодно, а размер ячеек может отличаться, в зависимости от размера сетки. Соответственно, контент виджета должен быть спроектирован с учетом этих особенностей.
Минимальные ширину и высоту виджета для заданного количества столбцов и строк можно вычислить по формуле:
minSideSizeDp = 70 × n − 30, где n —количество строк или столбцов
На текущий момент максимальный минимум сетки, которую вы можете задать это 4х4. Это гарантирует, что ваш виджет будет отображаться на всех девайсах.
Особенности обновления виджета
Так как AppWidgetProvider по своей сути является расширением BroadcastReceiver-а, с ним можно делать все то же самое, что и с обычным BroadcastReceiver. AppWidgetProvider просто парсит соответствующие поля из Intent, полученного в onReceive и вызывает методы перехвата с полученными extras.
Сложность возникла с частотой обновления контента — все дело в разнице внутренней работы виджетов на iOS и Android. Дело в том, что данные на iOS-виджетах обновляются тогда, когда виджет становится виден пользователю. В Android, такого события не существует. Мы не можем узнать, когда пользователь видит виджет.
Для виджетов на Android рекомендуемым способом обновления является обновление по таймеру. Настройки таймера задаются параметром виджета updatePeriodMillis. К сожалению, эта настройка не позволяет обновлять виджет чаще чем раз в 30 минут. Ниже я расскажу об этом подробнее.
Кейс создания виджета
Дальше речь пойдет о кейсе который был у нас в FINCH в крупном лотерейном приложении с приложением «Столото» для участия в государственных лотереях.
Задача приложения – упростить и сделать прозрачным для пользователя выбор лотереи и покупку билета. Поэтому требуемая функциональность виджета довольно проста: показывать пользователю рекомендуемые игры для покупки и по тапу переходить к соответствующей. Список игр определяется на сервере и регулярно обновляется.
В нашем кейсе дизайн виджета предусматривал два состояния:
- Для авторизованного пользователя
- Для неавторизованного пользователя


Как вы могли заметить, еще одной особенностью для авторизованного пользователя является кнопка «обновить», но об этом позже.
Для реализации отображения двух состояний, с учетом дизайна, я использовал RemoteAdapter в виде реализации RemoteViewsService, чтобы генерировать карточки контента.
А теперь немного кода и того, как все работает внутри. Если у вас уже был опыт работы с виджетом, то вы знаете, что любое обновление данных виджета начинается с метода onUpdate:
override fun onUpdate( context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray ) < injector.openScope(this, *arrayOf(this)) // update each of the widgets with the remote adapter appWidgetIds .forEach < updateWidget(context, appWidgetManager, it) >>
Пишем апдейт для каждого инстанса нашего виджета.
private fun updateWidget( context: Context, appWidgetManager: AppWidgetManager, appWidgetId: Int ) < //Создаем remoteViews для текущего widgetId val remoteViews = RemoteViews( context.packageName, R.layout.app_widget_layout . // делаем что то не интересное для этой статьи . // Обновляем адаптер для remoteViews updateRemoteAdapter(context, remoteViews, appWidgetId) //Обновляем виджет созданным remoteViews appWidgetManager.updateAppWidget(appWidgetId, remoteViews) //Обновляем collection view этого виджета appWidgetManager.notifyAppWidgetViewDataChanged( appWidgetId, R.id.lvWidgetItems ) >
private fun updateRemoteAdapter(context: Context, remoteViews: RemoteViews, appWidgetId: Int) < //Назначаем свою реализацию RemoteViewsService на роль RemoteAdapter для нашего списка val adapterIntent = Intent(context, StolotoAppWidgetRemoteViewsService::class.java).apply < putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) >remoteViews.setRemoteAdapter(R.id.lvWidgetItems, adapterIntent) //Формируем actionIntent для pendingIntent чтобы обрабатывать клики элементы виджета val actionIntent = Intent(context, StolotoAppWidgetProvider::class.java).apply < action = WIDGET_CLICK_ACTION putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) >val pendingIntent = PendingIntent.getBroadcast( context, 0, actionIntent, PendingIntent.FLAG_UPDATE_CURRENT ) //Назначаем pendingIntent шаблоном для клика по нашим айтемам remoteViews.setPendingIntentTemplate(R.id.lvWidgetItems, pendingIntent) >
Пишем реализацию нашего сервиса. В нем нам важно указать, какую реализацию интерфейса RemoteViewsService.RemoteViewsFactory использовать, чтобы генерировать контент.
class StolotoAppWidgetRemoteViewsService : RemoteViewsService()
Фактически это тонкий wrapper над Adapter. Благодаря ему, мы можем связывать наши данные с remote collection view. RemoteViewsFactory предоставляет методы генерации RemoteViews для каждого элемента в наборе данных. У конструктора нет никаких требований — все что я делаю, это передаю в нем контекст.
Далее будет пару слов об основных методах:
- onCreate – создание адаптера.
- getLoadingView – метод предлагает возвращать View, которое система будет показывать вместо пунктов списка, пока они создаются. Если ничего здесь не создавать, то система использует некое дефолтное View.
- getViewAt – метод предлагает создать пункты списка. Здесь идет стандартное использование RemoteViews.
- onDataSetChanged вызывается, когда поступил запрос на обновление данных в списке. Т.е. в этом методе мы подготавливаем данные для списка. Метод заточен под выполнение тяжелого, долгого кода.
- onDestroy вызывается при удалении последнего списка, который использовал адаптер (один адаптер может использоваться несколькими списками).
- RemoteViewsFactory живет пока все инстансы списка живы, поэтому мы можем хранить в нем текущие данные, например, список текущих айтемов.
private val widgetItems = ArrayList()
При создании адаптера начинаем загружать данные. Здесь спокойно можно выполнять любые тяжелые задачи, в том числе спокойно ходить в сеть блокируя поток.
override fun onCreate()
При вызове команды на обновление данных, так же вызываем updateDataSync()
override fun onDataSetChanged()
Внутри updateDataSync тоже все просто. Очищаем текущий список item-ов. Загружаем данные профиля и игры.
private fun updateDataSync()
Здесь уже поинтереснее
private fun updateProfileSync()
Так как нам важно показывать профиль только авторизованному пользователю, то и информацию профиля нам нужно загружать только в этом случае:
val isUserFullAuth = isUserFullAuthInteractor .execute() .blockingGet() if (isUserFullAuth) < val profile = getWidgetProfileInteractor .execute() .onErrorReturn < WidgetProfile() //Возвращаем пустую модель профиля в случае ошибок или отсутствия корректных данных профиля >.blockingGet()
Модель WidgetProfile собирается из разных источников, поэтому логика их получения и её дефолтные значения устроены таким образом, что отрицательное значение кошелька говорит о некорректных данных или проблемах с их получением.
Для бизнес логики отсутствие данных кошелька является критичным, поэтому, в случае некорректного кошелька, модель профиля не будет создана и добавлена в список item-ов.
if (profile.walletAmount >= 0L) < widgetItems.add( WidgetItem.Profile( wallet = profile.walletAmount.toMoneyFormat(), waitingTickets = if (profile.waitingTicketsCount >= 0) profile.waitingTicketsCount.toString() else "", unpaidPrizeAmount = if (profile.unpaidPrizeAmount >= 0) profile.unpaidPrizeAmoount.toMoneyFormat() else "" ) ) > > >
Метод updateGamesSync() использует getWidgetGamesInteractor и добавляет в список widgetItems набор актуальных для виджета игр.
Прежде чем перейти к генерации карточек, рассмотрим подробнее модель WidgetItem. Она реализована через kotlin sealed class, что делает модель более гибкой, а работу с ней более удобной.
sealed class WidgetItem
Создаем RemoteViews и определяем их отклик через FillInIntent
override fun getViewAt(position: Int): RemoteViews < return when (val item = widgetItems[position]) < is WidgetItem.Profile -> < RemoteViews( context.packageName, R.layout.item_widget_user_profile ).apply < setTextViewText(R.id.tvWidgetWalletMoney, item.wallet) setTextViewText(R.id.tvWidgetUnpaidCount, item.unpaidPrizeAmount) setTextViewText(R.id.tvWidgetWaitingCount, item.waitingTickets) setOnClickFillInIntent( R.id.llWidgetProfileWallet, Intent().putExtra( StolotoAppWidgetProvider.KEY_PROFILE_OPTIONS, StolotoAppWidgetProvider.VALUE_USER_WALLET ) ) setOnClickFillInIntent( R.id.llWidgetProfileUnpaid, Intent().putExtra( StolotoAppWidgetProvider.KEY_PROFILE_OPTIONS, StolotoAppWidgetProvider.VALUE_UNPAID_PRIZE ) ) setOnClickFillInIntent( R.id.llWidgetProfileWaiting, Intent().putExtra( StolotoAppWidgetProvider.KEY_PROFILE_OPTIONS, StolotoAppWidgetProvider.VALUE_WAITING_TICKETS ) ) >is WidgetItem.Game -> < RemoteViews( context.packageName, R.layout.item_widget_game ).apply < setImageViewResource(R.id.ivWidgetGame, item.iconId) setTextViewText(R.id.tvWidgetGamePrize, item.prizeValue) setTextViewText(R.id.tvWidgetGameDate, item.date) setOnClickFillInIntent( R.id.llWidgetGame, Intent().putExtra( StolotoAppWidgetProvider.KEY_GAME_CLICK, item.id ) ) >> > >
Метод setOnClickFillInIntent назначает указанной viewId intent, который будет объединен с родительским PendingIntent для определения поведения при клике на view с этим viewId. Таким образом, мы сможем реагировать на клики пользователей в нашем WidgetProvider.
Ручное обновление виджета
Для нашего виджета было установлено время обновления в полчаса. Можно обновлять его чаще, например, через танцы с WorkManager, но зачем грузить вашу сеть и аккумулятор? Такое поведение на первых этапах разработки казалось адекватным.
Все изменилось когда «бизнес» обратил внимание, что когда пользователь смотрит на виджет, на нем отображаются неактуальные данные: «Вот на моем iPhone, я открываю виджет и там САМЫЕ свежие данные моего профиля».
Ситуация банальна: iOS генерирует новые карточки при КАЖДОМ показе виджетов, ведь для этого у них отведен специальный экран, а Android не имеет подобных событий для виджета в принципе. Пришлось учесть, что некоторые лотереи проводятся раз в 15 минут, поэтому виджет должен давать актуальную информацию – ты хочешь поучаствовать в каком-то тираже, а он уже прошел.
Чтобы выйти из этой неприятной ситуации и как то решить проблему с обновлением данных, мной было предложено и реализовано проверенное временем решение — кнопка «обновить».
Добавляем эту кнопку в макет layout-a со списком и инициализируем её поведение при вызове updateWidget
. //Создадим Intent с дейстивем AppWidgetManager.ACTION_APPWIDGET_UPDATE val intentUpdate = Intent(context, StolotoAppWidgetProvider::class.java) intentUpdate.action = AppWidgetManager.ACTION_APPWIDGET_UPDATE //Назначим обновление всем инстансам виджета val ids = AppWidgetManager.getInstance(context) .getAppWidgetIds(ComponentName(context, StolotoAppWidgetProvider::class.java)) intentUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids) //Назначим этот intent как PendingIntent, используя PendingIntent.getBroadcast() val pendingUpdate = PendingIntent.getBroadcast( context, appWidgetId, intentUpdate, PendingIntent.FLAG_UPDATE_CURRENT ) //Назначим этот pendingIntent откликом на нажатие пользователем кнопки ‘Обновить’ remoteViews.setOnClickPendingIntent(R.id.ivWidgetRefresh, pendingUpdate) …
Первые наработки показали грустную картину: от нажатия на кнопку «обновить» до фактического обновления, могло пройти несколько секунд. Хотя виджет и генерируется нашим приложением, он фактически находится во власти системы и общается с нашим приложением через broadcast-ы.
Т.е. при нажатии на кнопку «обновить» нашего виджета запускается цепочка:
- Получить Intent в onReceive провайдера action’ .
- AppWidgetManager.ACTION_APPWIDGET_UPDATE.
- Вызов onUpdate для всех указанных в intent-e widgetIds.
- Зайти в сеть за новыми данными.
- Обновить локальные данные и отобразить новые карточки списка.
Во-первых, я добавил флаг isWidgetLoading с глобальным доступом через интерактор. Роль этого параметра довольно проста — не показывать кнопку «обновить», пока идет загрузка данных виджета.
Во вторых, процесс загрузки данных в фабрике я разделил на три этапа:
enum class LoadingStep
START — начало загрузки. На этом этапе состояние всех вьюшек адаптера и глобального флага загрузки меняется на «загружается».
MIDDLE — этап основной загрузки данных. После их загрузки глобальный флаг загрузки переводится в состояние «загружено», а в адаптере отображаются загруженные данные.
END — конец загрузки. Адаптеру на этом шаге не требуется изменять данные адаптера. Этот шаг нужен чтобы корректно обработать этап обновления вьюшек в WidgetProvider.
Давайте посмотрим подробнее как теперь выглядит обновление кнопки в провайдере:
if (isFullAuthorized && !widgetLoadingStateInteractor.isWidgetLoading) < remoteViews.setViewVisibility(R.id.ivWidgetRefresh, View.VISIBLE) . // инициализируем поведение кнопки так же, как в примере ранее . >else < remoteViews.setViewVisibility( R.id.ivWidgetRefresh, if (isFullAuthorized) View.INVISIBLE else View.GONE // Оставляем место под кнопку для авторизованного пользователя. ) >
А теперь посмотрим на то, что происходит в адаптере:
private fun updateDataSync() < when (loadingStep) < START -> < widgetItems.forEach < it.isLoading = true >widgetLoadingStateInteractor.isWidgetLoading = true loadingStep = MIDDLE widgetManager.updateWidgets() > MIDDLE -> < widgetItems.clear() updateProfileSync() updateGamesSync() widgetLoadingStateInteractor.isWidgetLoading = false loadingStep = END widgetManager.updateWidgets() >END -> < loadingStep = START >> >

- В конце этапов START и MIDDLE я вызываю метод updateWidgets для того, чтобы обновить состояние view управляемых провайдером.
- После выполнения шага START для пользователя визуально отображается «загрузка» в ячейках виджета, и начнется этап MIDDLE.
- Перед тем как вызвать обновление данных адаптера на шаге MIDDLE, провайдер скроет кнопку «обновить».
- После выполнения шага MIDDLE, для пользователя будет отображаются новые данные и начнется этап END.
- Перед тем как вызвать обновление данных адаптера, на шаге END, провайдер скроет кнопку «обновить». С точки зрения фабрики все данные будут актуальными, поэтому на шаге END меняем значение loadingStep на START.
Надеюсь, что статья была для вас полезной. Если у вас был опыт создания виджетов для Android, то расскажите об этом в комментариях.
- Разработка мобильных приложений
- Разработка под Android
Как настроить виджеты на Xiaomi
Владельцы Смартфонов Xiaomi каждый день пользуются значительным количеством приложений, которые запускаются через главный экран. Для оптимизации данного процесса предусмотрены специальные автономные модули – так называемые виджеты.
Что это такое?
Виджет - это отдельная программа, которая позволяет пользователю, даже не запуская конкретное приложение, получать нужную для него информацию. Например, при установке виджета для клиента WebMoney можно будет получать актуальные данные о балансе электронного кошелька без запуска Keeper или входа на сайт.
Как установить
Для того чтобы настроить виджеты на Xiaomi для стандартной оболочки MIUI, необходимо на главном экране удерживать палец на свободном месте до характерного звукового сигнала, после которого в нижней части дисплея появятся три дополнительные кнопки, в том числе для настройки виджетов.
Также вызвать функциональное меню можно за счет удержания сенсорной кнопки под экраном (три горизонтальные линии) либо сделать щипок двумя пальцами на свободной части монитора.

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

Настройка модулей обычно производится по размеру либо выполняемым функциям.
Для установки размера выбирается нужный элемент и зажимается до момента появления в верхней части дисплея значка об удалении. По периметру блока появится оранжевый контур, при помощи которого и меняются параметры элемента. Максимальные/минимальные размеры ограничены встроенными линейными пропорциями.

Каждый виджет настраивается индивидуально, так как его настройки зависят от функциональности приложения и возможных операций, которые с ним можно осуществить. К общим настройкам относится выбор цветового оформления для модуля.
Где найти дополнительные виджеты для Ксиаоми
Отдельная установка модулей не требуется, так как для каждого приложения, скачиваемого из сервиса Google Play Market. Достаточно только его скачать и произвести настройки, описанные выше.
Популярные виджеты на Сяоми:
- Часы, так как используемый стандартный интерфейс не удобен для большинства пользователей из-за маленького шрифта и расположения в верхнем правом углу. При задействовании модуля можно настроить не только отображение времени, но и дату. Также доступна возможность быстрого перехода к календарю, таймеру, будильнику и секундомеру;
- Прогноз погоды, информация о котором обычно поступает с таких сервисов, как Sinoptik и Gismeteo;
- Быстрый доступ к медиаплеерам;
- Информация из социальных сетей. При помощи специальных модулей удается без входа на страницу узнавать все актуальные сведения, просматривать сообщения, а также прослушивать аудиофайлы.
Если установить виджеты на Xiaomi, то удастся значительно сэкономить время, необходимое для просмотра уведомлений от приложений. А это, в свою очередь, позволит обеспечить лучший режим энергопотребления на смартфоне и тем самым увеличить срок работы изделия без подзарядки.