简体   繁体   English

如何在同一个应用程序中添加多个小部件?

[英]How to add multiple widgets in the same app?

I've just finished my Android widget. 我刚刚完成了我的Android小部件。 Now I need to have different sizes of this widget for the user to choose from. 现在我需要有不同大小的这个小部件供用户选择。

For example, I need a medium, small and large size widget, so when the user installs the app and hold the home screen then choose widget, in the widget menu I want him to see three widgets with the same app name but with the size. 例如,我需要一个中型,小型和大型小部件,因此当用户安装应用程序并按住主屏幕然后选择小部件时,在小部件菜单中我希望他看到三个具有相同应用程序名称但具有大小的小部件。 Something like this: 像这样的东西:

helloSmall helloMedium helloLarge helloSmall helloMedium helloLarge

I have the medium one ready, but how can I add the small and the large in the same app? 我准备好了中等版本,但是如何在同一个应用程序中添加小版本和大版本? Knowing that all three sizes contain the same exact data and actions, just the size and the background are different. 知道所有三种尺寸都包含相同的确切数据和动作,只是尺寸和背景不同。

You need a receiver definition for each type in your manifest file like: 您需要清单文件中每种类型的接收器定义,例如:

    <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>

This would allow you to have the same AppWidgetProvider class be used for multiple widgets, with different widget names and different sizes defined in the <appwidget-provider> XML. 这将允许您将相同的AppWidgetProvider类用于多个小部件,具有在<appwidget-provider> XML中定义的不同小部件名称和不同大小。

Now if you need more differences in your widgets than what is in the <appwidget-provider> XML I would create a base widget class that implements all the common behavoir between the different types: 现在,如果您的小部件需要比<appwidget-provider> XML中的更多差异,我将创建一个基本小部件类,它实现不同类型之间的所有常见行为:

public abstract class MyBaseWidget extends AppWidgetProvider

And then each of your concrete implementations could extend MyBaseWidget. 然后你的每个具体实现都可以扩展MyBaseWidget。 Then in your manifest file you would have a receiver definition for each of your concrete implementations like: 然后在您的清单文件中,您将为每个具体实现设置接收器定义,例如:

    <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>

Actually, android:name for each widget have to be different. 实际上,android:每个小部件的名称必须不同。 If you will do this as in example, only one widget will be visible in widgets list. 如果您将在示例中执行此操作,则在窗口小部件列表中只能看到一个窗口小部件。

Guys, I had the same problem. 大家好,我有同样的问题。

You need to actually add a second widget provider aswell; 您还需要实际添加第二个小部件提供程序;

<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>

Enjoy 请享用

Ok so basically you will need: 好的,基本上你需要:

layout file fore each widget. 每个小部件前的布局文件。 ex: main_small.xml, main_medium.xml ... 例如:main_small.xml,main_medium.xml ......

in the xml directory add a provider for each widget. 在xml目录中为每个窗口小部件添加提供程序。 ex: small_provider.xml, medium_provider.xml ... and so on (note if you don't have an xml directory add it under the drawable directory). 例如:small_provider.xml,medium_provider.xml ...等等(注意,如果没有xml目录,请将其添加到drawable目录下)。

now what! 怎么办!

  • define a receiver in the manifest for each widget. 在清单中为每个小部件定义一个接收器。 (just like the example in the main answer) (就像主要答案中的例子一样)

  • you can use the same layout or deferent layout. 您可以使用相同的布局或不同的布局。 basically this is up to you. 基本上这取决于你。

  • in your provider you should have something like this: 在你的提供者中你应该有这样的东西:

 <?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" /> 

make sure, for each provider to specify the target layout file you want to use. 确保为每个提供程序指定要使用的目标布局文件。 in this code I'm asking for the file main.xml in the layout directory. 在这段代码中,我要求布局目录中的文件main.xml。 for my medium widget for example i'll have another provider with the same exact code but i'll change the last line 对于我的中型小部件,例如我将有另一个提供商具有相同的确切代码,但我将更改最后一行

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

I hope this helps if not let me know and I can upload a working example on my website and you can take a closer look at it. 我希望这有帮助,如果不让我知道,我可以在我的网站上传一个工作示例,你可以仔细看看它。 please let me know how it goes. 请让我知道它是怎么回事。

best of luck. 祝你好运。

Some extra info to the other answers... 其他答案的一些额外信息......

  • If you are duplicating the files mentioned, and if your widget uses a Service to provide some functionality, you might have to duplicate your service. 如果您要复制上述文件,并且您的窗口小部件使用Service提供某些功能,则可能必须复制您的服务。

  • If you duplicate your Service , remember to update your manifest with the new service , otherwise the new service won't run... 如果您复制了Service请记住使用新服务更新清单 ,否则新服务将无法运行...

This wasted some time for me. 这浪费了一些时间给我。


If you use any BroadcastReceiver to send Intent s to your duplicate Service s... don't forget to update that code too: 如果您使用任何BroadcastReceiverIntent发送到您的重复Service ...请不要忘记更新该代码:

  • you must now send intents to each of the services. 您现在必须向每个服务发送意图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM