几个按钮的Android小部件onclick监听器

Posted

技术标签:

【中文标题】几个按钮的Android小部件onclick监听器【英文标题】:Android widget onclick listener for several buttons 【发布时间】:2014-06-06 21:31:09 【问题描述】:

我正在尝试为我的应用程序创建一个小部件。从我阅读一个 android 开发者网站来看,你的 onclick 监听器都需要有一个 Intent。但是,如果我只想让我的按钮更新小部件本身中的数据并且不想开始新的活动怎么办?

这是一些 Android 演示代码:

Intent intent = new Intent(context, ExampleActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);

// Get the layout for the App Widget and attach an on-click listener
// to the button
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
views.setOnClickPendingIntent(R.id.button, pendingIntent);

我想要一个按钮,当我单击它时会发起一个 http 网络调用,然后在小部件中显示结果。如果我必须使用意图,我该怎么做?我还需要能够区分点击了哪些按钮。

为什么小部件使用意图而不是普通的 onclick 监听器,它调用类似活动的函数?

编辑

我的小部件提供者:

public class MyWidgetProvider extends AppWidgetProvider 

private static final String MyOnClick1 = "myOnClickTag1";
private static final String MyOnClick2 = "myOnClickTag2";
private static final String MyOnClick3 = "myOnClickTag3";

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) 

    // Get all ids
    ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);
    int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

    for (int widgetId : allWidgetIds) 

        RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);

        remoteViews.setOnClickPendingIntent(R.id.widget_button_stayarm, getPendingSelfIntent(context, MyOnClick1));
        remoteViews.setOnClickPendingIntent(R.id.widget_button_awayarm, getPendingSelfIntent(context, MyOnClick2));
        remoteViews.setOnClickPendingIntent(R.id.widget_button_dissarm, getPendingSelfIntent(context, MyOnClick3));

        remoteViews.setTextViewText(R.id.widget_textview_gpscoords, "gps cords");

        appWidgetManager.updateAppWidget(widgetId, remoteViews);
    


protected PendingIntent getPendingSelfIntent(Context context, String action) 
    Intent intent = new Intent(context, getClass());
    intent.setAction(action);
    return PendingIntent.getBroadcast(context, 0, intent, 0);


@Override
public void onReceive(Context context, Intent intent) 

    if (MyOnClick1.equals(intent.getAction())) 
        // your onClick action is here
        Toast.makeText(context, "Button1", Toast.LENGTH_SHORT).show();
        Log.w("Widget", "Clicked button1");
     else if (MyOnClick2.equals(intent.getAction())) 
        Toast.makeText(context, "Button2", Toast.LENGTH_SHORT).show();
        Log.w("Widget", "Clicked button2");
     else if (MyOnClick3.equals(intent.getAction())) 
        Toast.makeText(context, "Button3", Toast.LENGTH_SHORT).show();
        Log.w("Widget", "Clicked button3");
    
;

我的 Android 清单:

<receiver
    android:name="widget.MyWidgetProvider"
    android:icon="@drawable/fsk"
    android:label="FSK Widget" >
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
    </intent-filter>

    <meta-data
        android:name="android.appwidget.provider"
        android:resource="@xml/example_appwidget_info" />
</receiver>

【问题讨论】:

【参考方案1】:

可以为小部件中的视图创建 onClick 事件。您可以根据需要创建任意数量的 onClick 事件。

在您的 Widget 类之上,创建一个静态变量,这将是您的 onClick 名称标签:

private static final String MyOnClick = "myOnClickTag";

定义一个辅助方法来自动创建每个PendingIntent

protected PendingIntent getPendingSelfIntent(Context context, String action) 
    Intent intent = new Intent(context, getClass());
    intent.setAction(action);
    return PendingIntent.getBroadcast(context, 0, intent, 0);

将此 onClick 标记设置为您的视图,如下所示:

    remoteViews.setOnClickPendingIntent(R.id.button, 
                      getPendingSelfIntent(context, MyOnClick));

在您的 Widget 类中创建一个 onReceive 方法并在其中设置此 onClick 事件:

public void onReceive(Context context, Intent intent) 

    if (MyOnClick.equals(intent.getAction()))
        //your onClick action is here
    
;

每当您设置标签的视图被按下时,onReceive 都会捕捉到它并执行与我们日常的标准 onClick 事件相同的操作。

编辑:根据您的回答,您能否将您的 onUpdate 内容替换为以下几行,然后重试:

    RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget_det);
    thisWidget = new ComponentName(context, MyWidgetProvider.class);    
    remoteViews.setOnClickPendingIntent(R.id.widget_button_stayarm, getPendingSelfIntent(context, MyOnClick1));
    remoteViews.setOnClickPendingIntent(R.id.widget_button_awayarm, getPendingSelfIntent(context, MyOnClick2));
    remoteViews.setOnClickPendingIntent(R.id.widget_button_dissarm, getPendingSelfIntent(context, MyOnClick3));
    remoteViews.setTextViewText(R.id.widget_textview_gpscoords, "gps cords");
    appWidgetManager.updateAppWidget(thisWidget, remoteViews);

【讨论】:

好的,你可以使用 action 标签来区分你点击的按钮。 这是使用小部件服务还是小部件提供者? 是的,您将使用动作标签来区分按钮点击。您可以为 2 个不同的按钮设置相同的按钮,或者您可以创建多个 onclick 事件并单独设置它们。不,这不是一项服务。扩展 AppWidgetProvider 的经典 Widget 类 对不起,这是我的错 :) 添加到我的答案中 抱歉这么痛苦,但是现在已经实现了,但是当我点击小部件中的一个按钮时它没有调用onrecive函数?我设置了一个断点,它没有被击中?我已将我的代码粘贴到原始答案中。【参考方案2】:

只需在你的 onReceive 方法中调用 super

@Override
public void onReceive(Context context, Intent intent) 
    super.onReceive(context, intent);//add this line
    if (MyOnClick1.equals(intent.getAction())) 
        // your onClick action is here
        Toast.makeText(context, "Button1", Toast.LENGTH_SHORT).show();
        Log.w("Widget", "Clicked button1");
     else if (MyOnClick2.equals(intent.getAction())) 
        Toast.makeText(context, "Button2", Toast.LENGTH_SHORT).show();
        Log.w("Widget", "Clicked button2");
     else if (MyOnClick3.equals(intent.getAction())) 
        Toast.makeText(context, "Button3", Toast.LENGTH_SHORT).show();
        Log.w("Widget", "Clicked button3");
    

【讨论】:

super.onReceive(context, intent); 解决了我的问题。谢谢!【参考方案3】:

示例如下:

public class SimpleWidgetProvider extends AppWidgetProvider 

    private static final String MY_BUTTTON_START = "myButtonStart";
    RemoteViews remoteViews;

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) 
        final int count = appWidgetIds.length;

        for (int i = 0; i < count; i++) 
            int widgetId = appWidgetIds[i];

            remoteViews = new RemoteViews(context.getPackageName(),
                R.layout.widget_layout);
            remoteViews.setTextViewText(R.id.textView, number);

            Intent intent = new Intent(context, SimpleWidgetProvider.class);
            intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
            intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
            PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
                0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

            remoteViews.setOnClickPendingIntent(R.id.actionButton,
                getPendingSelfIntent(context, MY_BUTTTON_START));

            appWidgetManager.updateAppWidget(widgetId, remoteViews);
        
    

    public void onReceive(Context context, Intent intent) 
        super.onReceive(context, intent);

        if (MY_BUTTTON_START.equals(intent.getAction()))
            Toast.makeText(context, "Click", Toast.LENGTH_SHORT).show();
        
    ;

    protected PendingIntent getPendingSelfIntent(Context context, String action) 
        Intent intent = new Intent(context, getClass());
        intent.setAction(action);
        return PendingIntent.getBroadcast(context, 0, intent, 0);
    


【讨论】:

你能帮帮我吗?我使用相同的代码,但从未调用过 onReceive。 非常感谢 Faxriddin 的快速回复,我刚刚解决了。我在以下行中缺少 (context,getClass()):Intent intent = new Intent(context, getClass());

以上是关于几个按钮的Android小部件onclick监听器的主要内容,如果未能解决你的问题,请参考以下文章

Android 小部件按钮 Onclick Toast 消息

Android小部件:如何确定单击了哪个按钮?

单击android小部件按钮上的侦听器

小部件 ImageButton 侦听器并不总是被调用

小部件onClick中的Android ListView不起作用

android小部件-重启后并不总是注册待处理的意图