Використання віджета зі списком в додатку

Post Views: 1 588

Віджети (Widgets) - це такі міні-додатки. які можуть бути вбудовані в головний екран пристрою і виводити корисну інформацію з самого додатка або навіть взаємодіяти з ним, виконуючи будь-які операції. Тому віджети є дуже важливою частиною програми, до того ж вони зручні у використанні: наприклад, у багатьох музичних плеєрів є свій віджет, який дозволяє змінювати треки або ставити їх на паузу без запуску програми.

У ранніх версіях Android віджети могли відображати тільки такі прості елементи, як TextView, ImageView і так далі. Однак зараз їх можливості стали набагато більше, тепер можна використовувати і більш складні ListView, GridView і StackView, що дозволяє показувати в віджети більше найрізноманітнішої інформації.

У цій статті ми розглянемо, як додати список ListView в віджет і обробити натискання на його елементи. Робити це будемо на прикладі віджета для додатка Менеджер паролів від Wi-Fi мереж .

Для початку потрібно створити XML-файли розмітки і метаданих.

Файл розмітки буде визначати зовнішній вигляд нашого віджета і розташування елементів на ньому. В даному випадку віджет буде складатися із заголовка з назвою програми та ListView, який буде містити список активних мереж. Додамо в папку res / layout файл widget_network.xml з наступним кодом:

&lt;? Xml version = "1.0&quot; encoding = "utf-8"?> <LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android" xmlns: tools = "http: // schemas .android.com / tools "android: layout_width =" match_parent "android: layout_height =" match_parent "android: background =" @ color / gray "android: orientation =" vertical "> <LinearLayout android: layout_width =" match_parent "android: layout_height = "wrap_content" android: background = "@ color / primary"> <ImageView android: id = "@ + id / widget_logo" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_margin = "16dp" android: src = "@ drawable / logo_widget" /> </ LinearLayout> <LinearLayout android: layout_width = "match_parent" android: layout_height = "wrap_content" android: orientation = "vertical"> <ListView android: id = "@ + id / widgetList "android: layout_width =" match_parent "android: layout_height =" wrap_content "android: background =" @ color / gray "tools: listitem =" @ layout / widget_list_item "/> </ LinearLayout> </ LinearLayout>

Оскільки елемент в списку містить різні дані, для нього теж зроблена окрема розмітка в файлі widget_list_item.xml, також розташованому в res / layout, яка представляє собою злегка змінену розмітку елемента списку RecyclerView з програми.

&lt;? Xml version = "1.0&quot; encoding = "utf-8"?> <LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android" xmlns: app = "http: // schemas .android.com / apk / res-auto "android: id =" @ + id / widget_container "android: layout_width =" match_parent "android: layout_height =" wrap_content "android: background =" @ color / gray "android: orientation = "vertical"> <LinearLayout android: id = "@ + id / widget_main" android: layout_width = "fill_parent" android: layout_height = "wrap_content" android: layout_gravity = "center_vertical" android: layout_marginEnd = "16dp" android: layout_marginLeft = " 16dp "android: layout_marginRight =" 16dp "android: layout_marginStart =" 16dp "android: layout_marginTop =" 14dp "android: orientation =" horizontal "android: weightSum =" 1 "> <TextView android: id =" @ + id / widget_SSID "android: layout_width =" 0dp "android: layout_height =" wrap_content "android: layout_gravity =" center_vertical "android: layout_weight =" 0.55 "android: fontFamily =" sans-serif "android: text =" Network "android: textColor =" @android: color / black "android: textS ize = "16sp" android: textStyle = "bold" /> <TextView android: id = "@ + id / widget_tv_dot" android: layout_width = "0dp" android: layout_height = "wrap_content" android: layout_gravity = "center_vertical" android: layout_weight = "0.05" android: gravity = "center" android: text = "@ string / dot" android: visibility = "invisible" /> <TextView android: id = "@ + id / widget_tv_hide" android: layout_width = "0dp "android: layout_height =" wrap_content "android: layout_gravity =" center_vertical "android: layout_marginLeft =" 8dp "android: layout_marginStart =" 8dp "android: layout_weight =" 0.3 "android: text =" @ string / card_hidden "android: textSize = "16sp" android: visibility = "invisible" /> <ImageView android: id = "@ + id / widget_arrow" android: layout_width = "0dp" android: layout_height = "wrap_content" android: layout_gravity = "center_vertical" android: layout_weight = "0.1" app: srcCompat = "@ drawable / ic_keyboard_arrow_down_black_24dp" /> </ LinearLayout> <LinearLayout android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_marginBot tom = "14dp" android: layout_marginEnd = "16dp" android: layout_marginLeft = "16dp" android: layout_marginRight = "16dp" android: layout_marginStart = "16dp" android: layout_marginTop = "2dp" android: orientation = "horizontal"> <TextView android: id = "@ + id / widget_password" android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: drawablePadding = "8dp" android: fontFamily = "sans-serif" android: text = "password" android: textIsSelectable = "true" android: textSize = "14sp" /> <TextView android: layout_width = "wrap_content" android: layout_height = "wrap_content" android: layout_marginLeft = "8dp" android: layout_marginStart = "8dp" android: text = "@ string / dot "/> <TextView android: id =" @ + id / widget_date "android: layout_width =" wrap_content "android: layout_height =" wrap_content "android: layout_marginLeft =" 8dp "android: layout_marginStart =" 8dp "android: bufferType = "spannable" android: fontFamily = "sans-serif" android: text = "date" android: textIsSelectable = "true" android: textSize = "14sp" /> </ LinearLayout> <LinearLayout android: id = "@ + id / widget_more" android: layout_width = "match_parent" android: layout_height = "wrap_content" android: layout_marginBottom = "14dp" android: layout_marginEnd = "16dp" android: layout_marginLeft = "16dp" android: layout_marginRight = "16dp" android: layout_marginStart = "16dp" android: layout_marginTop = "2dp" android: orientation = "horizontal" android: visibility = "gone" android: weightSum = "1"> <Button android: id = "@ + id / btn_widget_connect "android: layout_width =" 0dp "android: layout_height =" wrap_content "android: layout_gravity =" center_vertical "android: layout_weight =" 0.7 "android: background =" @ color / green_settings "android: text =" @ string / connect " android: textSize = "14sp" style = "@ style / Base.TextAppearance.AppCompat.Widget.Button.Colored" /> <ImageView android: id = "@ + id / widget_copy" android: layout_width = "0dp" android: layout_height = "wrap_content" android: layout_gravity = "center_vertical" android: layout_marginLeft = "30dp" android: layout_marginStart = "30dp" android: layout_weight = "0.15" android: tint = "@ color / second ary_text "app: srcCompat =" @ drawable / ic_content_copy_black_24px "/> <ImageView android: id =" @ + id / widget_share "android: layout_width =" 0dp "android: layout_height =" wrap_content "android: layout_gravity =" center_vertical "android: layout_weight = "0.15" android: tint = "@ color / secondary_text" app: srcCompat = "@ drawable / ic_share_black_24px" /> </ LinearLayout> </ LinearLayout>

Основними даними для показу тут є SSID мережі, пароль до неї, дата додавання, а також відмітка про те, прихована мережа чи ні. При розкритті елемента будуть відображатися додаткові кнопки, що дозволяють підключитися до мережі, скопіювати пароль або поділитися даними про неї з іншими людьми.

Тепер потрібно створити файл з метаданими. Для цього в папці res / xml створимо файл network_widget.xml.

&lt;? Xml version = "1.0&quot; encoding = "utf-8"?> <Appwidget-provider xmlns: android = "http://schemas.android.com/apk/res/android" android: initialLayout = "@ layout / widget_network "android: minHeight =" 250dp "android: minWidth =" 250dp "android: previewImage =" @ drawable / logo "android: resizeMode =" horizontal | vertical "android: updatePeriodMillis =" 864000 "android: widgetCategory =" home_screen "> </ appwidget-provider>

У цьому файлі ми вказуємо розмітку віджета, яку ми додали раніше, а також розміри віджета, картинку, яка буде відображатися в списку віджетів, час оновлення та можливість змінювати розмір віджету.

Тепер, закінчивши з зовнішнім виглядом віджету, можна приступити до реалізації роботи зі списком. Для цього нам знадобиться створити 3 класу: WidgetRemoteViewsFactory, WidgetRemoteViewsService, WidgetProvider. Логіку їх взаємодії можна описати наступними словами: WidgetProvider при оновленні віджета буде посилати Интент в WidgetRemoteViewsService, який буде повертати назад екземпляр WidgetRemoteViewsFactory. Про те, як це влаштовано, буде розглянуто нижче.

Клас WidgetProvider успадковує від AppWidgetProvider, його завданням є реалізація життєвого циклу віджета. Створимо клас WidgetProvider, що містить наступний код:

public class WidgetProvider extends AppWidgetProvider {private static final String TAG = "PROVIDER"; @Override public void onUpdate (Context context, AppWidgetManager appWidgetManager, int [] appWidgetIds) {super.onUpdate (context, appWidgetManager, appWidgetIds); for (int widgetId: appWidgetIds) {updateWidget (context, appWidgetManager, widgetId); }} Private void updateWidget (Context context, AppWidgetManager appWidgetManager, int widgetId) {RemoteViews views = new RemoteViews (context.getPackageName (), R.layout.widget_network); appWidgetManager.updateAppWidget (widgetId, views); } Public static void sendRefreshBroadcast (Context context) {Intent intent = new Intent (AppWidgetManager.ACTION_APPWIDGET_UPDATE); intent.setComponent (new ComponentName (context, WidgetProvider.class)); context.sendBroadcast (intent); } @Override public void onReceive (Context context, Intent intent) {final String action = intent.getAction (); if (BuildConfig.DEBUG) Log.d (TAG, action); if (! TextUtils.isEmpty (action)) {if (action.equals (AppWidgetManager.ACTION_APPWIDGET_UPDATE)) {AppWidgetManager manager = AppWidgetManager.getInstance (context); ComponentName cn = new ComponentName (context, WidgetProvider.class); manager.notifyAppWidgetViewDataChanged (manager.getAppWidgetIds (cn), R.id.widgetList); }} Super.onReceive (context, intent); }}

Метод onUpdate () викликається, коли відбувається оновлення віджетів, при цьому в параметри передаються контекст додатки, об'єкт AppWidgetManager і ID всіх віджетів, які потрібно оновити.

Якщо подивитися вихідний код класу AppWidgetProvider, то можна побачити, що він успадковує від класу BroadcastReceiver, тому він може приймати широкомовні повідомлення від програми. Метод onReceive () приймає ці повідомлення і обробляє їх в залежності від того, що потрібно розробнику.

Щоб провайдер брав повідомлення, потрібно зареєструвати його в маніфесті. Для цього в файл AndroidManifect.xml в <application> додамо наступний код:

<Receiver android: name = ". Widget.WidgetProvider" android: label = "@ string / app_name"> <intent-filter> <action android: name = "android.appwidget.action.APPWIDGET_UPDATE" /> </ intent-filter > <meta-data android: name = "android.appwidget.provider" android: resource = "@ xml / network_widget" /> </ receiver>

У <intent-filter> вказуємо, що хочемо отримувати повідомлення про оновлення віджета, а в <meta-data> вказуємо XML-файл з метаданими, який ми створили раніше.

Клас WidgetRemoteViewsService виступає посередником між WidgetProvider і WidgetRemoteViewsFactory. Цей сервіс повинен приймати Интент від WidgetProvider і повертати йому об'єкт WidgetRemoteViewsFactory, який заповнює елемент списку в віджеті даними. Створимо клас WidgetRemoteViewsService, що успадковує від RemoteViewsService.

public class WidgetRemoteViewsService extends RemoteViewsService {@Override public RemoteViewsFactory onGetViewFactory (Intent intent) {return new WidgetRemoteViewsFactory (this.getApplicationContext (), intent); }}

Як і будь-який інший сервіс, його потрібно зареєструвати в маніфестве додатки. Для цього в файл AndroidManifect.xml всередині <application> додамо наступний код:

<Service android: name = ". Widget.WidgetRemoteViewsService" android: permission = "android.permission.BIND_REMOTEVIEWS" />

Дозвіл android.permission.BIND_REMOTEVIEWS дозволяє системі прив'язати сервіс з метою додавання уявлення віджета для кожного елемента і не дозволяє іншим додатки отримувати доступ до даних віджета.

Завданням класу WidgetRemoteViewsFactory є заповнення списку в віджеті даними. Іншими словами, тут він виступає як адаптер ListView. Для того, щоб працювати зі списком, клас повинен реалізовувати інтерфейс RemoteViewsService.RemoteViewsFactory. Створимо клас WidgetRemoteViewsFactory з наступним кодом:

public class WidgetRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {private Context mContext; private List <WifiInfoWidget> list; private DateFormat dateFormat; private int mWidgetId; public WidgetRemoteViewsFactory (Context context, Intent intent) {mContext = context; mWidgetId = intent.getIntExtra (AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); } @Override public void onCreate () {list = new ArrayList <> (); String pattern = ((SimpleDateFormat) DateFormat.getDateInstance (DateFormat.MEDIUM, Locale.getDefault ())). ToPattern (); dateFormat = new SimpleDateFormat (pattern, Locale.getDefault ()); } @Override public void onDataSetChanged () {list.clear (); Set <WifiInfoWidget> networkList = new HashSet <> (); String json = SP.getString (mContext, WIDGET_LIST, null); if (json! = null) {networkList = SP.getWidgetList (json); } If (networkList! = Null) {list.addAll (networkList); }} @Override public void onDestroy () {} @Override public int getCount () {return list.size (); } @Override public RemoteViews getViewAt (int i) {WifiInfoWidget wi = list.get (i); RemoteViews rv = new RemoteViews (mContext.getPackageName (), R.layout.widget_list_item); rv.setTextViewText (R.id.widget_SSID, wi.SSID); if (wi.hidden) {rv.setViewVisibility (R.id.widget_tv_dot, View.VISIBLE); rv.setViewVisibility (R.id.widget_tv_hide, View.VISIBLE); } Else {rv.setViewVisibility (R.id.widget_tv_dot, View.INVISIBLE); rv.setViewVisibility (R.id.widget_tv_hide, View.INVISIBLE); } Rv.setTextViewText (R.id.widget_password, wi.password); rv.setTextViewText (R.id.widget_date, dateFormat.format (wi.date)); if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.LOLLIPOP) {rv.setImageViewResource (R.id.widget_copy, R.drawable.ic_content_copy_black_24px); rv.setImageViewResource (R.id.widget_share, R.drawable.ic_share_black_24px); if (wi.widgetExpand) {rv.setImageViewResource (R.id.widget_arrow, R.drawable.ic_keyboard_arrow_up_black_24dp); } Else {rv.setImageViewResource (R.id.widget_arrow, R.drawable.ic_keyboard_arrow_down_black_24dp); }} Else {Drawable drawableCopy = VectorDrawableCompat.create (mContext.getResources (), R.drawable.ic_content_copy_black_24px, mContext.getTheme ()); if (drawableCopy! = null) {setDrawable (rv, R.id.widget_copy, drawableCopy); } Drawable drawableShare = VectorDrawableCompat.create (mContext.getResources (), R.drawable.ic_share_black_24px, mContext.getTheme ()); if (drawableShare! = null) {setDrawable (rv, R.id.widget_share, drawableShare); } Drawable drawableArrow; if (wi.widgetExpand) {drawableArrow = VectorDrawableCompat.create (mContext.getResources (), R.drawable.ic_keyboard_arrow_up_black_24dp, mContext.getTheme ()); } Else {drawableArrow = VectorDrawableCompat.create (mContext.getResources (), R.drawable.ic_keyboard_arrow_down_black_24dp, mContext.getTheme ()); } If (drawableArrow! = Null) {setDrawable (rv, R.id.widget_arrow, drawableArrow); }} If (wi.widgetExpand) {rv.setViewVisibility (R.id.widget_more, View.VISIBLE); } Else {rv.setViewVisibility (R.id.widget_more, View.GONE); } Return rv; } @Override public RemoteViews getLoadingView () {return null; } @Override public int getViewTypeCount () {return 1; } @Override public long getItemId (int i) {return i; } @Override public boolean hasStableIds () {return true; } Private void setDrawable (RemoteViews rv, int id, Drawable drawable) {Bitmap b = Bitmap.createBitmap (drawable.getIntrinsicWidth (), drawable.getIntrinsicHeight (), Bitmap.Config.ARGB_8888); Canvas c = new Canvas (b); drawable.setBounds (0, 0, c.getWidth (), c.getHeight ()); drawable.draw (c); rv.setImageViewBitmap (id, b); }}

Метод onCreate () викликається при створенні адаптера, тут ми инициализируем об'єкт List <WifiInfoWidget> і формат дати для показу.

Метод onDataSetChanged () викликається, коли адаптер оновив віджет. У цьому методі забираємо мережі з SharedPreferences і заповнюємо їм раніше ініціалізований список.

Метод onDestroy () викликається при видаленні списку, тут, якщо потрібно, потрібно реалізовувати логіку очищення.

Метод getCount () повертає кількість елементів в списку.

Метод getViewAt (одночасно) відбувся є найважливішим, він виконує заповнення елемента списку даними, потім повертає в адаптер за допомогою сервісу готовий об'єкт RemoteViews.

Метод getLoadingView () повертає спеціальний об'єкт View, якщо елементи списку ще не встигли скластися.

Метод getViewTypeCount () повертає кількість типів уявлень в ListView. Оскільки уявлення в списку однакові, повертаємо 1.

Метод getItemId () повертає ID елемента в обраній позиції.

Метод hasStableIds () повертає true, якщо один і той же ID завжди відноситься до одного і того ж об'єкту.

Тепер нам потрібно підключити до нашого провайдеру адаптер. Для цього додамо в метод updateWidget () класу WidgetProvider наступний код:

private void updateWidget (Context context, AppWidgetManager appWidgetManager, int widgetId) {RemoteViews views = new RemoteViews (context.getPackageName (), R.layout.widget_network); setList (views, context, widgetId); appWidgetManager.updateAppWidget (widgetId, views); } Private void setList (RemoteViews views, Context context, int widgetId) {Intent intent = new Intent (context, WidgetRemoteViewsService.class); intent.putExtra (AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId); views.setRemoteAdapter (R.id.widgetList, intent); }

Тут за допомогою методу setRemoteAdapter () ми встановлюємо адаптер списку, який підключається до сервісу WidgetRemoteViewsService через спеціальний Интент.

Тепер нам потрібно зробити так, щоб, при натисканні на кнопки в списку віджета, виконувалися певні операції. Складність тут полягає в тому, що при використанні колекцій забороняється встановлювати PendingIntent на окремі елементи. Тому скористаємося методом setPendingIntentTemplate () для установки шаблону PendingIntent в колекції, а окремі елементи будуть викликатися за допомогою методу setOnClickFillInIntent ().

Для початку в методі updateWidget () класу WidgetProvider створимо шаблон для колекції, який буде відправляти в onReceive () подія про натискання.

public static final String ACTION_ON_ITEM_CLICK = "ON_MORE_CLICK"; public static final String COMMAND = "COMMAND"; public static final String MORE = "MORE"; public static final String CONNECT = "CONNECT"; public static final String COPY = "COPY"; public static final String SHARE = "SHARE"; public static final String ITEM = "ITEM"; ... private void updateWidget (Context context, AppWidgetManager appWidgetManager, int widgetId) {... final Intent onItemClick = new Intent (context, WidgetProvider.class); onItemClick.setAction (ACTION_ON_ITEM_CLICK); onItemClick.setData (Uri.parse (onItemClick.toUri (Intent.URI_INTENT_SCHEME))); final PendingIntent onClickPendingIntent = PendingIntent.getBroadcast (context, 0, onItemClick, PendingIntent.FLAG_UPDATE_CURRENT); views.setPendingIntentTemplate (R.id.widgetList, onClickPendingIntent); appWidgetManager.updateAppWidget (widgetId, views); }

Потім в класі WidgetRemoteViewsFactory в методі getViewAt () додамо ІНТЕНТ при натисканні на кнопки.

@Override public RemoteViews getViewAt (int i) {... if (wi.widgetExpand) {rv.setViewVisibility (R.id.widget_more, View.VISIBLE); rv.setOnClickFillInIntent (R.id.btn_widget_connect, createIntent (WidgetProvider.CONNECT, wi)); rv.setOnClickFillInIntent (R.id.widget_copy, createIntent (WidgetProvider.COPY, wi)); rv.setOnClickFillInIntent (R.id.widget_share, createIntent (WidgetProvider.SHARE, wi)); } Else {rv.setViewVisibility (R.id.widget_more, View.GONE); } Rv.setOnClickFillInIntent (R.id.widget_arrow, createIntent (WidgetProvider.MORE, wi)); return rv; } Private Intent createIntent (String cmd, WifiInfoWidget wi) {Intent intent = new Intent (); intent.setAction (WidgetProvider.ACTION_ON_ITEM_CLICK); Bundle bundle = new Bundle (); bundle.putString (WidgetProvider.COMMAND, cmd); bundle.putSerializable (WidgetProvider.ITEM, wi); intent.putExtras (bundle); return intent; }

В об'єкт Bundle крім даних про мережу ми також додаємо команду, за якою провайдер буде розрізняти, натискання на яку кнопку було скоєно і які дії потрібно виконати.

Натискання на кнопки реалізовані, тепер потрібно їх обробити. Повернемося до класу WidgetProvider, в метод onReceive () додамо наступний код:

@Override public void onReceive (Context context, Intent intent) {final String action = intent.getAction (); if (BuildConfig.DEBUG) Log.d (TAG, action); if (! TextUtils.isEmpty (action)) {if (action.equals (AppWidgetManager.ACTION_APPWIDGET_UPDATE)) {AppWidgetManager manager = AppWidgetManager.getInstance (context); ComponentName cn = new ComponentName (context, WidgetProvider.class); manager.notifyAppWidgetViewDataChanged (manager.getAppWidgetIds (cn), R.id.widgetList); } If (action.equals (ACTION_ON_ITEM_CLICK)) {parseItemClick (context, intent.getExtras ()); }} Super.onReceive (context, intent); } Private void parseItemClick (Context context, Bundle bundle) {if (bundle! = Null) {String command = bundle.getString (COMMAND); if (! TextUtils.isEmpty (command)) {if (BuildConfig.DEBUG) Log.d (TAG, command); switch (command) {case MORE: {WifiInfoWidget wi = (WifiInfoWidget) bundle.getSerializable (ITEM); if (wi! = null) {wi.widgetExpand =! wi.widgetExpand; Set <WifiInfoWidget> networkList = new HashSet <> (); String json = SP.getString (context, WIDGET_LIST, null); if (json! = null) {networkList = SP.getWidgetList (json); } If (networkList! = Null) {for (WifiInfoWidget wifiInfo: networkList) {if (wifiInfo.equals (wi)) {wifiInfo.widgetExpand = wi.widgetExpand; SP.saveWidgetList (context, networkList); sendRefreshBroadcast (context); break; }}}} Break; } Case CONNECT: {WifiInfoWidget wi = (WifiInfoWidget) bundle.getSerializable (ITEM); if (wi! = null) {App.selectContent ( "widget", "підключити мережу"); WifiManager wifiManager = (WifiManager) context.getApplicationContext () .getSystemService (Context.WIFI_SERVICE); if (wifiManager == null) {return; } Toast.makeText (context, R.string.wifi_changing_network, Toast.LENGTH_SHORT) .show (); Set <WifiInfo> networkList = new HashSet <> (); String json = SP.getString (context, MAIN_LIST, null); if (json! = null) {networkList = SP.getList (json); } If (networkList! = Null) {for (WifiInfo wifiInfo: networkList) {if (wifiInfo.SSID.equals (wi.SSID) && wifiInfo.password.equals (wi.password) && wifiInfo.hidden == wi.hidden) {WifiConfigManager wcf = new WifiConfigManager (wifiManager); if (wcf.getStatus (). toString (). equals ( "PENDING")) wcf.execute (wifiInfo); break; }}}} Break; } Case COPY: {WifiInfoWidget wi = (WifiInfoWidget) bundle.getSerializable (ITEM); if (wi! = null) {App.selectContent ( "widget", "копіювати"); Tools.CopyToClipboard (context, wi.password); Toast.makeText (context, R.string.Copy_value, Toast.LENGTH_LONG) .show (); } Break; } Case SHARE: {WifiInfoWidget wi = (WifiInfoWidget) bundle.getSerializable (ITEM); if (wi! = null) {App.selectContent ( "widget", "рядок логін-пароль"); String s = "SSID:" + wi.SSID + "\ nPassword:" + wi.password; Intent i = new Intent (); i.setAction (Intent.ACTION_SEND); i.putExtra (Intent.EXTRA_TEXT, s); i.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK); i.setType ( "test / plain"); context.startActivity (i); } Break; }}}}}

Таким чином ми можемо легко обробляти натискання на різні елементи списку.

Залишилося мале: посилати в віджет широковещательное повідомлення, яке буде запускати оновлення при додаванні / видаленні елемента зі списку в додатку. Для цього в класі WidgetProvider додамо метод sendRefreshBroadcast (), який буде відправляти в o nReceive () повідомлення про оновлення віджета, що потім викличе весь ланцюжок WidgetProvider - WidgetRemoteViewsService - WidgetRemoteViewsFactory - WidgetProvider.

public static void sendRefreshBroadcast (Context context) {Intent intent = new Intent (AppWidgetManager.ACTION_APPWIDGET_UPDATE); intent.setComponent (new ComponentName (context, WidgetProvider.class)); context.sendBroadcast (intent); }

Метод цей будемо викликати в класі головною активності в місцях, де відбувається зміна списку.

WidgetProvider.sendRefreshBroadcast (mainView.getContext ());

На цьому все. Результат того, як працює наш віджет, ви можете побачити нижче.

Quot; encoding = "utf-8"?
Lt;?
Quot; encoding = "utf-8"?
Lt;?
Quot; encoding = "utf-8"?

Дополнительная информация

rss
Карта