Android 添加自己的时钟小部件

小部件,也叫微件,
它的介绍参考官网 应用 widget 概览 https://developer.android.google.cn/develop/ui/views/appwidgets/overview?hl=zh-cn

直接上图,原生系统上,时钟应用的小部件效果。
在这里插入图片描述

我也整一个。

1.创建小部件布局文件

这个文件就是最终显示在桌面的小部件的样式。
res/layout/time_widget_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingTop="6dp"
    android:paddingBottom="6dp"
    android:gravity="center"
    android:orientation="vertical">

    <TextClock
        android:id="@+id/tv_date"
        android:layout_width="match_parent"
        android:layout_height="22dp"
        android:format12Hour="yyyy/MM/dd E"
        android:format24Hour="yyyy/MM/dd E"
        android:gravity="center"
        android:textSize="17sp"
        android:textColor="#DBE1FF" />

    <TextClock
        android:id="@+id/tv_time"
        android:layout_width="match_parent"
        android:layout_height="101dp"
        android:format12Hour="h:mm"
        android:format24Hour="HH:mm"
        android:gravity="center"
        android:textColor="#DBE1FF"
        android:textSize="@dimen/textclock_time_size" />

</LinearLayout>

使用 TextClock 显示日期、时间,很方便,它会自己更新,不需要添加刷新逻辑。

2.创建小部件配置文件

AppWidgetProviderInfo 对象定义了 widget 的基本特性。

res/xml/time_widget.xml

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/time_widget_layout"
    android:minHeight="110dp"
    android:minWidth="110dp"
    android:resizeMode="vertical|horizontal"
    android:previewImage="@drawable/pic_beauty"
    android:updatePeriodMillis="3000" />
  • android:initialLayout :指向小部件布局文件 。
  • android:minHeight 、android:minWidth :小部件原始占用区域大小,也是最小占用区域大小,我的示例占用的是 2 x 2 。
  • android:resizeMode=“vertical|horizontal” :是否支持调整大小,这个是横向、纵向都支持。
  • android:previewImage :小部件的预览图。
  • android:previewLayout:小部件预览页面的布局。本例只设置了预览图,没有添加布局,有需要自己添加即可。
  • android:updatePeriodMillis :小部件更新时间间隔。

小部件的大小要根据实际情况计算,参考官网示例
在这里插入图片描述
参考 Android Developers 应用微件设计指南

3.实现AppWidgetProvider

3.1 在清单中声明自定义的 AppWidgetProvider

AppWidgetProvider 本质是 receiver 。

        <receiver
            android:name=".appwidget.TimeWidgetProvider"
            android:exported="true"
            android:label="TimeWidgetLabel">
            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/time_widget" />

            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
        </receiver>
  • android:name=“.appwidget.TimeWidgetProvider” :要实现的自定义 AppWidgetProvider
  • <meta-data/> 里的 android:name 是默认格式,不要改;android:resource 指向小部件配置文件。
  • <intent-filter> 里的是默认格式,不要修改。

3.2 实现自定义的 AppWidgetProvider

创建 TimeWidgetProvider ,继承 AppWidgetProvider

public class TimeWidgetProvider extends AppWidgetProvider {

    public static final String TAG = TimeWidgetProvider.class.getSimpleName();

    @Override
    public void onReceive(Context context, Intent intent) {
        super.onReceive(context, intent);
        Log.d(TAG, "onReceive : " + intent.getAction());
    }

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        super.onUpdate(context, appWidgetManager, appWidgetIds);
        Log.d(TAG, "onUpdate");
    }
}

onReceive 里会接收到这些广播:

  • android.appwidget.action.APPWIDGET_ENABLED :小部件第一次被添加到桌面时触发。如果添加同一个小部件两次,第二次添加不会触发。对应 onEnabled 方法。
  • android.appwidget.action.APPWIDGET_UPDATE :小部件被添加到桌面或者小部件更新时触发。对应 onUpdate 方法。
  • android.appwidget.action.APPWIDGET_DELETED :小部件被删除时触发。如果同一个小部件有多个,删一个触发一次。对应 onDeleted方法。
  • android.appwidget.action.APPWIDGET_DISABLED :同一个小部件,最后一个被删除时触发。对应 onDisabled方法。
  • android.appwidget.action.APPWIDGET_UPDATE_OPTIONS :用户调整小部件大小时触发。对应 onAppWidgetOptionsChanged 方法。

到这里,初版已OK。

3.3 更新小部件

使用 RemoteViews 更新调整UI 、添加点击事件,然后调用 AppWidgetManager.updateAppWidget 即可。

	private RemoteViews remoteViews;
	private AppWidgetManager mAppWidgetManager;
    private int[] mAppWidgetIds;

	public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        super.onUpdate(context, appWidgetManager, appWidgetIds);
        Log.d(TAG, "onUpdate");
        mAppWidgetManager = appWidgetManager;
        mAppWidgetIds = appWidgetIds;
        Log.d(TAG, "onUpdate appWidgetIds:" + Arrays.toString(mAppWidgetIds));
        createRemoteViews(context);
    }

    private void createRemoteViews(Context context) {
        if (remoteViews == null) {
            Log.d(TAG, "createRemoteViews");
            remoteViews = new RemoteViews(context.getPackageName(), R.layout.time_widget_layout);//注释1

            Intent intent = new Intent("android.settings.DATE_SETTINGS");
            intent.setPackage("com.android.settings");
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
            
            PendingIntent pendingIntent1, pendingIntent2;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
                pendingIntent1 = PendingIntent.getActivity(context, 101, intent, PendingIntent.FLAG_IMMUTABLE);
                pendingIntent2 = PendingIntent.getActivity(context, 102, intent, PendingIntent.FLAG_IMMUTABLE);
            } else {
                pendingIntent1 = PendingIntent.getActivity(context, 101, intent, PendingIntent.FLAG_UPDATE_CURRENT);
                pendingIntent2 = PendingIntent.getActivity(context, 102, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            }
            remoteViews.setOnClickPendingIntent(R.id.tv_time, pendingIntent1);
            remoteViews.setOnClickPendingIntent(R.id.tv_date, pendingIntent2);//注释2

            for (int id:mAppWidgetIds) {
                mAppWidgetManager.updateAppWidget(id, remoteViews);//注释3
            }

        }

注释1 :通过 RemoteViews 找到 小部件布局文件,

RemoteViews 提供了很多方法更新小部件,如

  • setTextViewText(@IdRes int viewId, CharSequence text) :根据 id 设置 TextView 。
  • setImageViewResource(@IdRes int viewId, @DrawableRes int srcId) :根据 id 设置 ImageView。
  • setOnClickPendingIntent(@IdRes int viewId, PendingIntent pendingIntent) :根据 id 设置点击事件。

本例用的 TextClock ,会自动更新时间,就没有加 RemoteViews 的逻辑。

注释2 :使用 PendingIntent 为各个控件添加点击事件。如果不加,默认打开应用首页。本例打开原生设置的 日期和时间 。

注释3 :调用 AppWidgetManager.updateAppWidget 更新小部件。

最终效果:
在这里插入图片描述

  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Android Studio创建一个简单的时钟部件的步骤和示例代码: 1. 创建一个新的Android项目,并在布局文件中添加一个TextView组件,用于显示时间。 2. 在MainActivity.java文件中,添加以下代码来获取当前时间并更新TextView组件的文本: ```java import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; import android.widget.RemoteViews; import java.text.SimpleDateFormat; import java.util.Date; public class ClockWidget extends AppWidgetProvider { @Override 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对象 RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout); // 获取当前时间 SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss"); String currentTime = sdf.format(new Date()); // 更新TextView组件的文本 views.setTextViewText(R.id.widget_textview, currentTime); // 更新小部件 appWidgetManager.updateAppWidget(appWidgetId, views); } } } ``` 3. 在AndroidManifest.xml文件中,添加以下代码来注册时钟部件: ```xml <receiver android:name=".ClockWidget"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_info" /> </receiver> ``` 4. 创建一个widget_info.xml文件,并在其中定义小部件的属性,例如大小、更新间隔等。 ```xml <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="40dp" android:minHeight="40dp" android:updatePeriodMillis="1000" android:initialLayout="@layout/widget_layout"> </appwidget-provider> ``` 5. 创建一个widget_layout.xml文件,并在其中定义小部件的布局,例如TextView组件。 ```xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/widget_textview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="24sp" android:layout_gravity="center_horizontal" /> </LinearLayout> ``` 这样,您就创建了一个简单的Android桌面数字时钟部件。当您将该小部件添加到桌面后,它将每秒钟更新一次,并显示当前的时间。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值