前言
微件是定制主屏幕的一个重要方面。它允许您从用户的主屏幕直接看到最重要的应用程序数据和功能。用户可以在主屏幕面板之间移动微件、调整其大小,并根据自己的喜好自定义微件中的信息量。微贱类型主要分为:信息微件(显示对用户来说很重要的一些关键信息元素,并跟踪该信息随时间变化的情况),集合微件(专门显示同一类型的众多元素),控制微件(专门显示同一类型的众多元素),混合微件(将不同类型的元素组合在一起)。
本文将用一个信息微件——在桌面显示时间为实例简单初步学习appwidget,实例如下:
步骤一:
新建一个NewAppWidget,具体方法如下:
添加好后可看到:
每个微件必须定义 minWidth 和 minHeight,表示默认情况下应占用的最小空间量。微件占用的宽度和高度一般会超过指定的最小值。Android 主屏幕为用户提供了一个可用空间网格,供他们放置微件和图标。此网格可能因设备而异。添加微件后,它将在水平和垂直方向进行拉伸,占用满足其 minWidth 和 minHeight 约束条件所需的最小单元格数。手机一般不能超过4x4网格。
接着可以看到创建成功的NewAppWidget:
package com.example.myapplication;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.widget.RemoteViews;
/**
* Implementation of App Widget functionality.
*/
public class NewAppWidget extends AppWidgetProvider {
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
CharSequence widgetText = context.getString(R.string.appwidget_text);
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
views.setTextViewText(R.id.appwidget_text, widgetText);
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple widgets active, so update all of them
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
@Override
public void onEnabled(Context context) {
// Enter relevant functionality for when the first widget is created
}
@Override
public void onDisabled(Context context) {
// Enter relevant functionality for when the last widget is disabled
}
}
可以看到当发生这些广播事件时,AppWidgetProvider 会接收以下方法调用:
onUpdate():当用户添加应用微件时会调用此方法,所以它应执行基本设置。
onEnabled(context):如果用户添加应用微件的两个实例,只有首次添加时会调用此方法。使用此方法打开一个新的数据库或执行只需要对所有应用微件实例执行一次的其他设置.
onDisabled(Context):从应用微件托管应用中删除了应用微件的最后一个实例时,会调用此方法。使用此方法来清理在 onEnabled(Context) 中完成的所有工作。
还有未显示的onReceive(Context, Intent):针对每个广播调用此方法,并且是在上述各个回调方法之前调用。
步骤二:
创建应用微件布局:
其实当NewAppWidget创建好后,就可以发现在res/layout中已经创建好new_app_widget.xml布局文件,稍微修改后代码如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/Widget.MyApplication.AppWidget.Container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@style/Theme.MyApplication.AppWidgetContainer">
<TextView
android:id="@+id/appwidget_text"
style="@style/Widget.MyApplication.AppWidget.InnerView"
android:layout_width="168dp"
android:layout_height="152dp"
android:layout_centerInParent="true"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:background="#FFBB86FC"
android:contentDescription="@string/appwidget_text"
android:gravity="center"
android:text="@string/appwidget_text"
android:textColor="@color/white"
android:textSize="24sp"
android:textStyle="bold|italic" />
</RelativeLayout>
此时已经创建好的res/xml/new_app_widget_info.xml也需要稍微修改,如下:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/app_widget_description"
android:initialKeyguardLayout="@layout/new_app_widget"
android:initialLayout="@layout/new_app_widget"
android:minWidth="150dp"
android:minHeight="100dp"
android:previewImage="@drawable/example_appwidget_preview"
android:previewLayout="@layout/new_app_widget"
android:resizeMode="horizontal|vertical"
android:targetCellWidth="3"
android:targetCellHeight="3"
android:updatePeriodMillis="86400000"
android:widgetCategory="home_screen" />
步骤三:
到此,基本的微件已经大致完成,现在就需要更改NewAppWidget.Java中的部分代码,将onUpdate()中的代码改为:
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int [] appWidgetIds)
{
final int N = appWidgetIds.length;
for ( int i = 0 ; i < N; i ++ )
{
int appWidgetId = appWidgetIds[i];
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.new_app_widget);
java.text.DateFormat df = new java.text.SimpleDateFormat( " hh:mm:ss " );
views.setTextViewText(R.id.appwidget_text, df.format( new Date()));
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
实现微件显示系统时间
步骤四:
检查配置:
可以看到AndroidMainifest.xml代码如下:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication"
tools:targetApi="31">
<receiver
android:name=".NewAppWidget"
android:exported="false">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/new_app_widget_info" />
</receiver>
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
</application>
</manifest>
步骤五:
运行:
在Android模拟器上长按屏幕,点击Widgets,找到My Application,将其拖拽到主屏幕即可显示系统时间,如实例图所示。
总结:
该文本只是通过简单的实例对appwidgets进行粗略的学习,该实例无法实现每秒刷新。若需进行widgets实时更新,需创建一个服务类Timeservice,并修改NewAppWidget中的方法调用。
参考资料:https://developer.android.google.cn/guide/topics/appwidgets/overview
作者:李美辛
原文链接:https://blog.csdn.net/qq_52631411/article/details/128171263