在 android 中,App 小部件是可以嵌入到其他应用程序(例如主屏幕)中以快速访问应用程序数据的小型应用程序视图。
这些应用程序视图在用户界面中被称为小部件,我们可以使用App Widget Provider发布这些视图。能够容纳其他应用程序小部件的应用程序组件称为App Widget Host。
根据我们的要求,一些常用的android小部件是时钟小部件、天气小部件、音乐小部件等。
要创建App Widget,以下是我们需要在我们的 android 应用程序中使用它的主要组件。
零件 | 描述 |
---|---|
AppWidgetProviderInfo | 该对象用于定义 App Widget 的元数据,例如 App Widget 的布局、更新频率和 AppWidgetProvider 类。这应该在 XML 中定义。 |
AppWidgetProvider | 这最适合跨页数未确定的对象集合进行分页。当用户导航到其他页面时,它会破坏片段,从而最大限度地减少内存使用。 |
查看布局 | 它定义了 App Widget 的初始布局。这应该在 XML 中定义。 |
要为我们的 android 应用程序创建应用程序小部件,我们需要设置以下组件。
在 Manifest 中声明一个 App Widget
我们需要在我们的应用程序清单 ( AndroidManifest.xml ) 文件中添加AppWidgetProvider对象,如下所示。
<receiver android:name="ExampleAppWidgetProvider" >
<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>
receiver元素的name属性将指定App Widget 使用的AppWidgetProvider , intent filter用于指定AppWidgetProvider接受ACTION_APPWIDGET_UPDATE 广播,meta-data 元素用于指定AppWidgetProvider资源。
在布局文件中创建 App Widget
我们需要在 XML 中为我们的应用小部件定义一个初始布局,并将其保存在项目的res/layout目录中。我们可以使用以下 布局 和小部件类来设计我们的应用小部件布局。
添加 AppWidgetProviderInfo 元数据
要创建应用小部件,我们需要使用<appwidget-provider>元素定义具有所有必需属性的AppWidgetProviderInfo对象,例如布局尺寸、初始布局源、更新应用小部件的频率等,并将其保存在项目的res/xml/文件夹如下所示。
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="40dp"
android:minHeight="40dp"
android:updatePeriodMillis="86400000"
android:previewImage="@drawable/preview"
android:initialLayout="@layout/example_appwidget"
android:configure="com.example.android.ExampleAppWidgetConfigure"
android:resizeMode="horizontal|vertical"
android:widgetCategory="home_screen">
</appwidget-provider>
如果您观察上面的代码,我们定义了一个 appwidgetprovider,其中包含所有必需的属性来在 android 应用程序中定义一个应用程序小部件。
在 Java 文件中调用 AppWidgetProvider
要处理应用程序小部件 广播,我们需要创建一个新的 Java 文件或通过使用AppWidgetProvider类扩展现有文件并覆盖其更新方法,如下所示。
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);
}
}
}
如果您观察上面的代码,AppWidgetProvider只定义了onUpdate()方法,目的是定义一个PendingIntent启动一个Activity并使用setOnClickPendingIntent (int, PendingIntent)将它附加到 App Widget 的按钮。
除了 onUpdate()方法,AppWidgetProvider还包含以下方法来在我们的应用程序中操作应用程序小部件。
方法 | 描述 |
---|---|
已删除 | 每次从 App Widget 宿主中删除 App Widget 时都会调用此方法。 |
启用 | 首次创建 App Widget 实例时调用此方法。 |
禁用 | 当您的 App Widget 的最后一个实例从 App Widget 主机中删除时,将调用此方法。 |
接收 | 每次广播和上述每个回调方法之前都会调用此方法。 |
现在我们将通过示例了解如何为 android 应用程序创建一个应用程序小部件并将其嵌入到主屏幕上。
Android 应用小部件示例
以下是在 android 应用程序中使用 appwidgetprovider 创建应用小部件并将其添加到主屏幕的示例。
使用 android studio 创建一个新的 android 应用程序并命名为WidgetExample。如果您不知道在 android studio 中创建应用程序,请查看这篇文章Android Hello World App。
一旦我们创建了一个应用程序,从\res\layout文件夹路径中打开activity_main.xml文件并编写如下所示的代码。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/fstTxt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tutlane.com"
android:layout_gravity="center"
android:textSize="18dp"/>
<Button
android:id="@+id/btnClick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="App Widget"
android:layout_gravity="center"/>
</LinearLayout>
现在在res文件夹下创建一个新文件夹xml并在\res\xml路径中添加新的布局资源文件 ( samplewidget.xml ) ,为此,右键单击您的xml文件夹 → 转到新建→ 选择布局资源文件并将名称命名为samplewidget。 .xml _
一旦我们创建了一个新的布局资源文件samplewidget.xml,打开它并编写如下所示的代码
samplewidget.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="146dp"
android:updatePeriodMillis="0"
android:minHeight="146dp"
android:initialLayout="@layout/activity_main">
</appwidget-provider>
现在我们需要在\java\com.tutlane.widgetexample路径中创建新的活动文件WidgetActivity.java,为此右键单击您的应用程序文件夹 à Go to New à 选择Java Class并命名为WidgetActivity.java。
一旦我们创建了一个新的片段文件WidgetActivity.java,打开它并编写如下所示的代码
WidgetActivity.java
package com.tutlane.widgetexample;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.widget.RemoteViews;
import android.widget.Toast;
/**
* Created by tutlane on 20-01-2018.
*/
public class WidgetActivity extends AppWidgetProvider {
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for(int i=0; i<appWidgetIds.length; i++){
int appWidgetId = appWidgetIds[i];
String url = "http://tutlane.com";
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse(url));
PendingIntent pending = PendingIntent.getActivity(context, 0,intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.activity_main);
views.setOnClickPendingIntent(R.id.btnClick, pending);
appWidgetManager.updateAppWidget(appWidgetId,views);
Toast.makeText(context, "widget added", Toast.LENGTH_SHORT).show();
}
}
}
如果您观察上面的代码,我们使用AppWidgetProvider根据我们的要求来实现应用小部件。
现在从\java\com.tutlane.widgetexample路径打开您的主活动文件MainActivity.java并编写如下所示的代码。
MainActivity.java
package com.tutlane.widgetexample;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
我们需要为该打开的清单文件添加我们的 android 应用程序清单文件 ( AndroidManifest.xml ) 的<receiver>元素,并编写如下所示的代码。
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tutlane.widgetexample">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".WidgetActivity">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"></action>
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/samplewidget"></meta-data>
</receiver>
</application>
</manifest>
Android App Widget 示例的输出
当我们在 android 模拟器中运行上述示例时,我们将得到如下所示的结果。
如果您观察到上述结果,我们会根据我们的要求创建一个应用小部件并添加到主屏幕。
这就是我们根据我们的要求在 android 应用程序中创建应用程序小部件的方式。