最近几天,我一直在尝试学习如何在Android Xamarin上创建小部件。我无法使点击事件正常工作。
我知道我需要执行一个动作,创建一个Intent,然后使用创建的Intent创建一个PendingIntent。然后放入我想要的资源,并使用SetOnClickPendingIntent()方法使用PendingIntent。
代码如下:
using Android.App;
using Android.Appwidget;
using Android.Content;
using Android.Widget;
using GerirCalendario.Activities;
using System;
using System.Globalization;
namespace GerirCalendario.Widgets.teste
{
[BroadcastReceiver(Label = "@string/widget_event_list_lbl")]
[IntentFilter(new string[] { "android.appwidget.action.APPWIDGET_UPDATE" })]
[MetaData("android.appwidget.provider", Resource = "@xml/widgetinfo")]
public class WidgetProvider : AppWidgetProvider
{
private static string NEW_EVENT = "new_event";
private static string LAUNCH_CAL = "launch_cal";
private static string REFRESH_CAL = "refresh_cal";
public static string EXTRA_ITEM = "extra_item";
private static string TOAST_ACTION = "toast_action";
private static int PENDING_NEW_EVENT = 10;
private static int PENDING_LAUNCH_CAL = 20;
private static int PENDING_REFRESH_CAL = 30;
public override void OnDeleted(Context context, int[] appWidgetIds)
{
base.OnDeleted(context, appWidgetIds);
}
public override void OnDisabled(Context context)
{
base.OnDisabled(context);
}
public override void OnEnabled(Context context)
{
base.OnEnabled(context);
}
public override void OnReceive(Context context, Intent intent)
{
AppWidgetManager mgr = AppWidgetManager.GetInstance(context);
if (TOAST_ACTION.Equals(intent.Action))
{
int appWidgetId = intent.GetIntExtra(AppWidgetManager.ExtraAppwidgetId, AppWidgetManager.InvalidAppwidgetId);
int viewIndex = intent.GetIntExtra(EXTRA_ITEM, 0);
Toast.MakeText(context, "touched view " + viewIndex, ToastLength.Short).Show();
}
else if (NEW_EVENT.Equals(intent.Action))
{
var pm = context.PackageManager;
try
{
var packageName = "com.android.settings";
var launchIntent = pm.GetLaunchIntentForPackage(packageName);
context.StartActivity(launchIntent);
}
catch
{
// Something went wrong :)
}
}
else if (LAUNCH_CAL.Equals(intent.Action))
{
var pm = context.PackageManager;
try
{
var packageName = "com.android.settings";
var launchIntent = pm.GetLaunchIntentForPackage(packageName);
context.StartActivity(launchIntent);
}
catch
{
// Something went wrong :)
}
}
//switch (intent.Action)
//{
// case NEW_EVENT: NewEvent(context); break;
// case LAUNCH_CAL: LauchCalendar(context); break;
//}
base.OnReceive(context, intent);
}
private void LauchCalendar(Context context)
{
var pm = context.PackageManager;
try
{
var launchIntent = new Intent(context, typeof(LauncherActivity));
context.StartActivity(launchIntent);
}
catch
{
// Something went wrong
}
}
private void NewEvent(Context context)
{
var pm = context.PackageManager;
try
{
var launchIntent = new Intent(context, typeof(CreateEventActivity));
launchIntent.PutExtra(GerirUtils.INTENT_PICKED_DATE, DateTime.Today.ToString("dd/MM/yyyy"));
launchIntent.PutExtra(GerirUtils.BACK_PRESS_TO, GerirUtils.BACK_TO_MainActivity);
context.StartActivity(launchIntent);
}
catch
{
// Something went wrong
}
}
public override void OnUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
{
base.OnUpdate(context, appWidgetManager, appWidgetIds);
for (int i = 0; i < appWidgetIds.Length; i++)
{
RemoteViews remoteViews = UpdateWidgetListView(context, appWidgetIds[i]);
appWidgetManager.UpdateAppWidget(appWidgetIds[i], remoteViews);
}
}
private PendingIntent GetPendingSelfIntent(Context context, string action, int appWidgetId)
{
var intent = new Intent(context, typeof(AppWidget));
intent.SetAction(action);
intent.PutExtra(AppWidgetManager.ExtraAppwidgetId, appWidgetId);
return PendingIntent.GetBroadcast(context, PENDING_REFRESH_CAL, intent, 0);
}
private PendingIntent GetPendingSelfIntent(Context context, string action, int pendingIntentId, int appWidgetIds)
{
var intent = new Intent(context, typeof(AppWidget));
intent.SetAction(action);
intent.PutExtra(AppWidgetManager.ExtraAppwidgetId, appWidgetIds);
intent.SetFlags(ActivityFlags.NewTask);
return PendingIntent.GetBroadcast(context, pendingIntentId, intent, 0);
}
private RemoteViews UpdateWidgetListView(Context context, int appWidgetId)
{
RemoteViews remoteViews = new RemoteViews(context.PackageName, Resource.Layout.widget_events_list);
string PACKAGE_NAME = context.PackageName;
#region ListView
//Intent svcIntent = new Intent(context, typeof(WidgetService));
//svcIntent.SetPackage(PACKAGE_NAME);
//svcIntent.PutExtra(AppWidgetManager.ExtraAppwidgetId, appWidgetId);
//svcIntent.SetData(Android.Net.Uri.Parse(svcIntent.ToUri(Android.Content.IntentUriType.AndroidAppScheme)));
//
//remoteViews.SetEmptyView(Resource.Id.listViewWidget, Resource.Id.empty_view);
//remoteViews.SetRemoteAdapter(Resource.Id.listViewWidget, svcIntent);
// Here we setup the intent which points to the StackViewService which will
// provide the views for this collection.
Intent listIntent = new Intent(context, typeof(WidgetService));
listIntent.PutExtra(AppWidgetManager.ExtraAppwidgetId, appWidgetId);
listIntent.SetPackage(context.PackageName);
// When intents are compared, the extras are ignored, so we need to embed the extras
// into the data so that the extras will not be ignored.
listIntent.SetData(Uri.Parse(listIntent.ToUri(IntentUriType.Scheme)));
remoteViews.SetRemoteAdapter(Resource.Id.listViewWidget, listIntent);
// The empty view is displayed when the collection has no items. It should be a sibling
// of the collection view.
remoteViews.SetEmptyView(Resource.Id.listViewWidget, Resource.Id.empty_view);
// Here we setup the a pending intent template. Individuals items of a collection
// cannot setup their own pending intents, instead, the collection as a whole can
// setup a pending intent template, and the individual items can set a fillInIntent
// to create unique before on an item to item basis.
Intent toastIntent = new Intent(context, typeof(WidgetProvider));
toastIntent.SetAction(WidgetProvider.TOAST_ACTION);
toastIntent.PutExtra(AppWidgetManager.ExtraAppwidgetId, appWidgetId);
toastIntent.SetData(Uri.Parse(toastIntent.ToUri(IntentUriType.Scheme)));
PendingIntent toastPendingIntent = PendingIntent.GetBroadcast(context, 0, toastIntent, PendingIntentFlags.UpdateCurrent);
remoteViews.SetOnClickPendingIntent(Resource.Id.listViewWidget, toastPendingIntent);
#endregion
#region refresh calendar
var intent = new Intent(context, typeof(AppWidget));
intent.SetAction(AppWidgetManager.ActionAppwidgetUpdate);
intent.PutExtra(AppWidgetManager.ExtraAppwidgetId, appWidgetId);
// Register click event for the Background
var piBackground = PendingIntent.GetBroadcast(context, 0, intent, PendingIntentFlags.UpdateCurrent);
remoteViews.SetOnClickPendingIntent(Resource.Id.widget_parent, piBackground);
remoteViews.SetOnClickPendingIntent(Resource.Id.widget_toolbar_bg, piBackground);
remoteViews.SetOnClickPendingIntent(Resource.Id.widget_refresh_img, piBackground);
// Register click event for the Announcement-icon
//remoteViews.SetOnClickPendingIntent(Resource.Id.widget_refresh_img, GetPendingSelfIntent(context, REFRESH_CAL, appWidgetId));
#endregion
#region toolbar items
TextInfo ti = CultureInfo.CurrentCulture.TextInfo;
var todayText = DateTime.Today.ToString("ddd, dd MMM").ToLower();
remoteViews.SetTextViewText(Resource.Id.widget_today_text, ti.ToTitleCase(todayText));
remoteViews.SetOnClickPendingIntent(Resource.Id.widget_add_event,
GetPendingSelfIntent(context, NEW_EVENT, PENDING_NEW_EVENT, appWidgetId));
remoteViews.SetOnClickPendingIntent(Resource.Id.widget_today_text,
GetPendingSelfIntent(context, LAUNCH_CAL, PENDING_LAUNCH_CAL, appWidgetId));
#endregion
return remoteViews;
}
}
}
布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorTransparent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="@color/colorSemiTransparentBlack">
<ImageView
android:id="@+id/widget_refresh_img"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="14dp"
android:src="@drawable/ic_add_white"/>
<ImageView
android:id="@+id/widget_add_event"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:layout_marginStart="11dp"
android:src="@drawable/ic_today_white"/>
<TextView
android:id="@+id/widget_today_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/widget_refresh_img"
android:layout_centerHorizontal="true"
android:text=""
android:textSize="17dp"
android:textStyle="bold"
android:textColor="@color/colorWhite" />
</RelativeLayout>
<ListView
android:id="@+id/listViewWidget"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="10dp" />
<TextView
android:id="@+id/empty_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="EMPTY"
android:textColor="#ffffff"
android:textSize="20sp"
android:visibility="gone" />
</LinearLayout>
有人可以告诉我是否看到点击在何处或为何起作用!?