Android 通知栏进度条实现详解 | RemoteViews
2025-02-07 03:58:33
Android通知栏进度条的实现方法探究
Android通知栏作为应用与用户交互的重要途径,可以提供实时的状态更新和提醒。 其中的进度条功能, 例如Uber的接单通知栏展示进度, 如何才能准确控制其进度呢? 一个关键的挑战在于无法直接获取通知栏的宽度。 以下提供一些解决此类问题的策略和代码示例。
1. 基于RemoteViews
的定制化视图
定制化视图是实现复杂通知栏内容的基础。 利用RemoteViews
,可以构建一个包含LinearLayout、FrameLayout和ImageView等元素的自定义布局,模拟进度条效果。
核心思想
不依赖通知栏宽度,而是控制进度条“已完成”部分的宽度,使其与总进度百分比对应。
具体步骤
-
创建布局文件 (
notification_progress_layout.xml
):<LinearLayout android:id="@+id/notification_progress" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:orientation="horizontal" xmlns:android="http://schemas.android.com/apk/res/android"> <FrameLayout android:id="@+id/filled" android:layout_width="0dp" android:layout_height="@dimen/height" android:layout_weight="0" android:background="@color/color2"/> <ImageView android:id="@+id/progress_indicator" android:layout_width="wrap_content" android:layout_height="@dimen/indicator_height" android:src="@drawable/ic_progress_indicator" android:scaleType="fitCenter" android:adjustViewBounds="true"/> <FrameLayout android:id="@+id/not_filled" android:layout_width="0dp" android:layout_height="@dimen/height" android:layout_weight="1" android:background="@color/color2"/> </LinearLayout>
-
计算已完成部分和未完成部分的权重比例:
// progress is a float between 0 and 1 representing the progress private void updateProgress(NotificationManager notificationManager, String channelId, int notificationId, float progress) { RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.notification_progress_layout); // 控制已完成部分的layout_weight remoteViews.setFloat(R.id.filled, "layout_weight", progress); // 控制未完成部分的layout_weight。 这里使用了 (1 - progress) 来动态的更新未完成部分的宽度 remoteViews.setFloat(R.id.not_filled, "layout_weight", 1- progress); Notification notification = new NotificationCompat.Builder(context, channelId) .setSmallIcon(R.drawable.ic_notification) //设置通知小图标 .setOngoing(true) //设置为true,notification放置在正在运行栏目中 .setCustomContentView(remoteViews) .build(); notificationManager.notify(notificationId, notification); } // 如何使用上述函数: float currentProgress = 0.6f; // 例如,当前进度为60% NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); String channelId = "your_channel_id"; int notificationId = 12345; // 为每个Notification定义一个唯一的ID updateProgress(notificationManager, channelId, notificationId, currentProgress);
原理
该方法的核心在于layout_weight
属性。 LinearLayout
会根据子View设置的权重值,自动调整各个子View的宽度,最终填充整个可用空间。 将已完成部分和未完成部分的权重加起来保持为一个固定值(比如1),并通过动态调整已完成部分的权重来控制进度条的显示。
2. 巧用ProgressBar
组件
Android SDK提供了一个ProgressBar
组件,虽然标准样式与Uber的进度条有所差异,但是可以通过样式定制进行修改,也可以在定制的 RemoteViews 配合ProgressBar 实现类似的功能。
操作步骤
- 添加
ProgressBar
到RemoteViews中:
修改上述的 notification_progress_layout.xml。使用android sdk 提供的 progressbar. 务必设置progress bar 的id 为 "android:id/progress",这是android sdk 提供的 progressbar 固定的Id<ProgressBar android:id="@android:id/progress" style="?android:attr/progressBarStyleHorizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="50" />
- 更新ProgressBar的进度
这里注意使用setProgressBar
更新进度,需要保证id 为 "android:id/progress"。private void updateProgressBar(NotificationManager notificationManager, String channelId, int notificationId, int progress) { RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.notification_progress_layout); remoteViews.setProgressBar(android.R.id.progress, 100, progress, false); Notification notification = new NotificationCompat.Builder(context, channelId) .setSmallIcon(R.drawable.ic_notification) //设置通知小图标 .setOngoing(true) //设置为true,notification放置在正在运行栏目中 .setCustomContentView(remoteViews) .build(); notificationManager.notify(notificationId, notification); } // 使用该函数的例子 NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); String channelId = "your_channel_id"; int notificationId = 12345; // 为每个Notification定义一个唯一的ID int currentProgress = 75; // 假设当前的进度是 75% updateProgressBar(notificationManager, channelId, notificationId, currentProgress);
3. 利用第三方库
一些第三方库,例如Android Support Library
或AndroidX Library
中的组件,提供了更加灵活和便捷的方式来定制通知栏。 这些库通常包含了各种自定义View和辅助类,可以简化通知栏UI的开发过程。
(鉴于已经有了RemoteViews
和 ProgressBar
实现的思路, 这里就不在使用第三方库上进一步展开了).
总而言之,创建精确定制的进度条,重点在于找到与父容器适配的方法,比如用权重来分配各个视图的大小。使用 Android 提供的进度条组件可以减少许多手动开发的工作,当然定制化就会收到一些限制。希望这些方法能帮助您构建功能强大的通知栏进度条,从而提升用户体验。