在主屏幕小部件的列表视图上方添加一个按钮 - 如何捕获单击此按钮?

Posted

技术标签:

【中文标题】在主屏幕小部件的列表视图上方添加一个按钮 - 如何捕获单击此按钮?【英文标题】:adding a button above a listview in Homescreen widget - how to capture click on this button? 【发布时间】:2013-06-27 02:27:27 【问题描述】:

我正在使用 RemoteViewsService.RemoteViewsFactory (link)

在主屏幕小部件中显示列表视图。一切正常,我可以捕获列表视图项目的点击。现在我想在列表视图上方添加一个按钮,以允许用户跳转到配置活动:

这是我的小部件布局 xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/layout"
    android:layout_
    android:layout_
    android:layout_margin="8dip"
    android:background="@drawable/widget_frame"
    android:orientation="vertical" >

 <Button
        android:id="@+id/button1"
        style="?android:attr/buttonStyleSmall"
        android:layout_
        android:layout_
        android:text="Button" />

<ListView android:id="@+id/listview"
  android:layout_
  android:layout_
  android:layout_marginTop="0dp"
  android:layout_marginLeft="0dp"/>


</LinearLayout> 

这是我在 WidgetProvider.java 类中的 onUpdate 方法:

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

  Log.w(LOG, "onUpdate method called");


  for (int i=0; i<appWidgetIds.length; i++) 

      Intent svcIntent=new Intent(context, WidgetService.class);
      svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
      // http://***.com/questions/13199904/android-home-screen-widget-remoteviews-setremoteadapter-method-not-working
      Random generator = new Random();
      int randomNumber = generator.nextInt(1000);
      svcIntent.putExtra("random", randomNumber);
      svcIntent.setData(Uri.parse(svcIntent.toUri(Intent.URI_INTENT_SCHEME)));

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

      //------------------------------------------------------------------------------------
      // trying to capture the button click ... ?
      RemoteViews btn_remoteviews=new RemoteViews(context.getPackageName(), R.id.button1);      

      Intent btn_clickIntent = new Intent(context, Config.class);
      btn_clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
      //PendingIntent btn_pendingIntent = PendingIntent.getBroadcast(context, appWidgetIds[i], btn_clickIntent, 0);
      PendingIntent btn_pendingIntent = PendingIntent.getActivity(context, 0, btn_clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
      btn_remoteviews.setPendingIntentTemplate(R.id.button1, btn_pendingIntent);        
      appWidgetManager.updateAppWidget(appWidgetIds[i], btn_remoteviews);
      //------------------------------------------------------------------------------------




      remoteviews.setRemoteAdapter(appWidgetIds[i], R.id.listview, svcIntent);

      Intent clickIntent=new Intent(context, LoremActivity.class);
      clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
      PendingIntent clickPI=PendingIntent.getActivity(context, 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
      remoteviews.setPendingIntentTemplate(R.id.listview, clickPI);       

      appWidgetManager.updateAppWidget(appWidgetIds[i], remoteviews);

  

super.onUpdate(context, appWidgetManager, appWidgetIds);

如何捕捉按钮点击???

我的列表视图上的所有点击都被捕获,但我无法捕获列表视图上方按钮的点击???

非常感谢您的帮助!

【问题讨论】:

嘿,我很好奇...developer.android.com/guide/topics/appwidgets/index.html 没有任何内容说您不能将 Button 添加为 Widget 上 ListView 的 [header view][1],我的意思是, Button 和 ListView 都是 RemoteViews。你试过吗? [1]:developer.android.com/reference/android/widget/… 【参考方案1】:

如您提供的页面所述:

这个 AppWidgetProvider 只定义了 onUpdate() 方法 定义启动 Activity 的 PendingIntent 的目的和 将其附加到 App Widget 的按钮上 setOnClickPendingIntent(int, PendingIntent)。请注意,它包括一个 循环遍历 appWidgetIds 中的每个条目,这是一个 IDE 的 ID 数组

还有:

如使用 AppWidgetProvider 类中所述,您通常使用 setOnClickPendingIntent() 设置对象的点击行为——例如 导致一个按钮启动一个活动。但是这种做法是不允许的 对于单个集合项中的子视图(澄清一下,您 可以使用 setOnClickPendingIntent() 在 例如,启动应用程序的 Gmail 应用程序小部件,但不在 单个列表项)。相反,将点击行为添加到个人 集合中的项目,您使用 setOnClickFillInIntent()。这需要 为您的集合视图设置待处理的意图模板,以及 然后通过您的在集合中的每个项目上设置填充意图 远程视图工厂。

您提供的链接中的那个例子怎么样?我没有仔细阅读该页面(你肯定应该),但你不应该 setOnClickPendingIntent() 或 setOnClickFillInIntent() 吗?:

public class ExampleAppWidgetProvider extends AppWidgetProvider 

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

        // Perform this loop procedure for each App Widget that belongs to this provider
        for (int i=0; i<N; i++) 
            int appWidgetId = appWidgetIds[i];

            // Create an Intent to launch ExampleActivity
            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);

            // Tell the AppWidgetManager to perform an update on the current app widget
            appWidgetManager.updateAppWidget(appWidgetId, views);
        
    

【讨论】:

这实际上(几乎)是我正在做的。但无论出于何种原因,我使用的是“setPendingIntentTemplate”而不是“setOnClickPendingIntent”,更重要的是我使用了另一个“RemoteViews btn_remoteviews=new RemoteViews(context.getPackageName(), R.id.button1);”而不是第一个声明的“RemoteViews remoteviews=new RemoteViews(context.getPackageName(), R.layout.widget_layout);” 我给你 100 赏金,因为你的回答让我找到了自己的错误,而且你花时间给我写了一个答案。我将在下面发布我最终所做的事情。我添加了另一个按钮来启动另一个活动,一切看起来都很好。 我很高兴能帮上忙。谢谢你的第一个赏金代表 ;) P.S 你也可以看看我的一些未回答的问题,也有一个赏金问题【参考方案2】:

这就是我最终做的......

for (int i=0; i<appWidgetIds.length; i++) 

      Intent svcIntent=new Intent(context, WidgetService.class);
      svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
      // http://***.com/questions/13199904/android-home-screen-widget-remoteviews-setremoteadapter-method-not-working
      Random generator = new Random();
      int randomNumber = generator.nextInt(1000);
      svcIntent.putExtra("random", randomNumber);
      svcIntent.setData(Uri.parse(svcIntent.toUri(Intent.URI_INTENT_SCHEME)));

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

      //------------------------------------------------------------------------------------
      // trying to capture the button click ... ?   

      Intent btn_clickIntent = new Intent(context, Config.class);
      btn_clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
      PendingIntent btn_pendingIntent = PendingIntent.getActivity(context, 0, btn_clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
      remoteviews.setOnClickPendingIntent(R.id.button1, btn_pendingIntent);     

      Intent btn2_clickIntent = new Intent(context, Config2.class);
      btn2_clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
      PendingIntent btn2_pendingIntent = PendingIntent.getActivity(context, 0, btn2_clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
      remoteviews.setOnClickPendingIntent(R.id.button2, btn2_pendingIntent);        

      remoteviews.setRemoteAdapter(appWidgetIds[i], R.id.listview, svcIntent);

      Intent clickIntent=new Intent(context, LoremActivity.class);
      clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
      PendingIntent clickPI=PendingIntent.getActivity(context, 0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
      remoteviews.setPendingIntentTemplate(R.id.listview, clickPI);       

      appWidgetManager.updateAppWidget(appWidgetIds[i], remoteviews);  

【讨论】:

以上是关于在主屏幕小部件的列表视图上方添加一个按钮 - 如何捕获单击此按钮?的主要内容,如果未能解决你的问题,请参考以下文章

如何在android中获取主屏幕小部件列表项的点击事件[重复]

如何在按钮单击 FLUTTER 上刷新列表小部件数据

苹果手机怎么在主屏幕左上方设置自己的名字?

小部件未出现在主屏幕中

带有常用按钮菜单栏的 Sharepoint 2013 列表视图

单击按钮刷新时如何刷新小部件列表视图?