【问题标题】:How to add multiple widgets in the same app?如何在同一个应用程序中添加多个小部件?
【发布时间】:2011-02-03 22:17:08
【问题描述】:

我刚刚完成了我的 Android 小部件。现在我需要有不同尺寸的这个小部件供用户选择。

例如,我需要一个中、小和大尺寸的小部件,所以当用户安装应用并按住主屏幕然后选择小部件时,在小部件菜单中我希望他看到三个具有相同应用名称的小部件,但与大小。像这样的:

你好小 你好中 你好大号

我已经准备好了中号,但是如何在同一个应用程序中添加小号和大号?知道所有三种尺寸都包含完全相同的数据和操作,只是尺寸和背景不同。

【问题讨论】:

    标签: android android-widget


    【解决方案1】:

    您需要为清单文件中的每种类型定义一个接收器,例如:

        <receiver android:name=".MyWidget" android:label="@string/medium_widget_name">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <meta-data android:name="android.appwidget.provider"
                android:resource="@xml/medium_widget_provider" />
        </receiver>
    
        <receiver android:name=".MyWidget" android:label="@string/large_widget_name">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <meta-data android:name="android.appwidget.provider"
                android:resource="@xml/large_widget_provider" />
        </receiver>
    

    这将允许您将相同的AppWidgetProvider 类用于多个小部件,在&lt;appwidget-provider&gt; XML 中定义不同的小部件名称和不同的大小。

    现在,如果您的小部件需要比&lt;appwidget-provider&gt; XML 中的更多差异,我将创建一个基本小部件类来实现不同类型之间的所有常见行为:

    public abstract class MyBaseWidget extends AppWidgetProvider
    

    然后您的每个具体实现都可以扩展 MyBaseWidget。然后在您的清单文件中,您将为每个具体实现定义一个接收器定义,例如:

        <receiver android:name=".MyMediumWidget" android:label="@string/medium_widget_name">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <meta-data android:name="android.appwidget.provider"
                android:resource="@xml/medium_widget_provider" />
        </receiver>
    
        <receiver android:name=".MyLargeWidget" android:label="@string/large_widget_name">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <meta-data android:name="android.appwidget.provider"
                android:resource="@xml/large_widget_provider" />
        </receiver>
    

    【讨论】:

    • 您好,感谢您的回答。但似乎我不能共享同一个小部件提供程序。 (如果我这样做,只显示清单中的第一个)。所以,基本上,多个小部件提供者将是我的答案。有人与一个小部件提供商合作吗?
    • 是的,只是按照上面的说明进行操作,发现它只有在我指定不同的小部件提供程序类时才有效。总之很好,谢谢大家! :)
    • 这里也一样,需要多个小部件提供程序类才能显示小部件。
    • 我无法使用相同的 AppWidgetProvider 类,因为我不知道如何以编程方式获取布局,即我在构建视图的 AppWidgetProvider 中有这个:RemoteViews views = new RemoteViews (context.getPackageName(), R.layout.widget);注意“R.layout.widget”,这个值会根据清单中的而有所不同。有没有办法以编程方式从 AppWidgetProvider 类中获取小部件提供程序中定义的布局?如果没有,子类化是我们使用具有不同布局的相同 AppWidgetProvider 类的唯一选择。
    • @TheAwnryBear 是的,你使用AppWidgetProviderInfo。这样你可以得到这样的布局:AppWidgetProviderInfo.initialLayout。一个例子可能是:AppWidgetProviderInfo appInfo = appWidgetManager.getAppWidgetInfo(widgetId); appInfo.initialLayout;
    【解决方案2】:

    实际上,每个小部件的 android:name 必须不同。如果您按照示例执行此操作,则小部件列表中将仅显示一个小部件。

    【讨论】:

    • 根据@jblz 的回答(澄清)
    • 是的!这就是问题!!我最终创建了另一个小部件提供程序类,它只是扩展了第一个,然后在清单中为这两个小部件设置了这两个类。
    【解决方案3】:

    伙计们,我遇到了同样的问题。

    您实际上还需要添加第二个小部件提供程序;

    <receiver android:name=**".MyWidget**" android:label="@string/medium_widget_name">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <meta-data android:name="android.appwidget.provider"
            android:resource="@xml/medium_widget_provider" />
    </receiver>
    
    <receiver android:name=**".MyWidget2"** android:label="@string/large_widget_name">
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
        </intent-filter>
        <meta-data android:name="android.appwidget.provider"
            android:resource="@xml/large_widget_provider" />
    </receiver>
    

    享受

    【讨论】:

    • 我们还需要为第二个小部件创建一个单独的 Java 类文件吗?
    【解决方案4】:

    好的,基本上你需要:

    每个小部件的布局文件。例如:main_small.xml、main_medium.xml ...

    在 xml 目录中为每个小部件添加一个提供程序。例如:small_provider.xml、medium_provider.xml ... 等等(请注意,如果您没有 xml 目录,请将其添加到 drawable 目录下)。

    现在怎么办!

    • 在清单中为每个小部件定义一个接收器。 (就像主要答案中的示例)

    • 您可以使用相同的布局或不同的布局。基本上这取决于你。

    • 在你的提供者中你应该有这样的东西:

    <?xml version="1.0" encoding="utf-8"?>
    
    <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
        android:minWidth="146dip"
        android:minHeight="138dip"
        android:updatePeriodMillis="10000"
        android:initialLayout="@layout/main"
        />
    

    确保为每个提供者指定您要使用的目标布局文件。在这段代码中,我要求布局目录中的文件 main.xml。例如,对于我的中型小部件,我将拥有另一个具有相同代码的提供商,但我将更改最后一行

    > android:initialLayout="@layout/medium".
    

    如果不让我知道,我希望这会有所帮助,我可以在我的网站上上传一个工作示例,您可以仔细查看它。请告诉我进展如何。

    祝你好运。

    【讨论】:

      【解决方案5】:

      其他答案的一些额外信息......

      • 如果您要复制提到的文件,并且如果您的小部件使用 Service 来提供某些功能,您可能必须复制您的服务。

      • 如果您复制了 Service记得用新服务更新清单,否则新服务将无法运行...

      这对我来说浪费了一些时间。


      如果您使用任何BroadcastReceiverIntents 发送到您的重复Services...也不要忘记更新该代码:

      • 您现在必须向每个服务发送意图。

      【讨论】:

        猜你喜欢
        • 2012-08-05
        • 1970-01-01
        • 1970-01-01
        • 2022-07-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-23
        • 2021-03-01
        相关资源
        最近更新 更多