Uber 有一篇文章 https://www.uber.com/en-DE/blog/live-activity-on-ios/ 他们说他们用进度条发出了通知。我知道这篇文章说的是关于 iOS 的,但也有一部分是关于 android 的。通知看起来像这样:通知,android 在右侧 我理解他们在 xml 中做了什么通知,但我无法理解他们如何从代码中控制它。如果无法获取通知宽度,他们如何计算进度?
我尝试使用屏幕宽度并从中减去通知边缘的一些值(大约 110 dp)。然后将其设置为进度条填充线的左内边距。
val displayMetrics: DisplayMetrics = Resources.getSystem().displayMetrics
val screenWidth = displayMetrics.widthPixels
val edgeDistance = 100dip // take it from values file
val progress = (screenWidth - edgeDistance) * p // 0 <= p <= 1
setViewPadding(filledLineId, progress, 0, 0, 0)
但是通知宽度通常比屏幕宽度小得多。在这种情况下,通知右侧的进度条会被切断。 我的进度条 xml:
<LinearLayout android:gravity="center_vertical" android:orientation="horizontal" android:id="@id/notification_progress" android:layout_width="fill_parent" android:layout_height="wrap_content"
xmlns:android="http://schemas.android.com/apk/res/android">
<FrameLayout
android:id="@id/filled"
android:background="@color/color2"
android:layout_width="wrap_content"
android:layout_height="@dimen/height"
android:layout_weight="1.0"
android:layout_marginEnd="2dp" />
<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:background="@color/color2"
android:layout_width="wrap_content"
android:layout_height="@dimen/height"
android:layout_weight="100" />
</LinearLayout>
要使用进度条正确控制自定义通知布局的进度,重要的是要考虑到通知的实际宽度不能总是根据屏幕宽度来估计,特别是因为通知可能由于内容差异而具有可变的大小(例如, 、文本、图标)或系统 UI 元素。
由于您的目标是将进度表示为百分比,因此您可以调整方法,而无需通知的确切宽度。您可以根据百分比为填充和未填充的视图使用预定义的宽度(以重量计)。
这是实现进度逻辑的更好方法:
not_filled
和 filled
FrameLayout 的权重。p
是进度(0到1),则可以确定总重量中有多少已填充,有多少未填充。
例如,如果总重量为 100,则可以将已填充的重量指定为 p * 100
,将未填充的重量指定为 (1 - p) * 100
。<LinearLayout
android:id="@+id/notification_progress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<FrameLayout
android:id="@+id/filled"
android:background="@color/color2"
android:layout_width="0dp"
android:layout_height="@dimen/height"
android:layout_weight="0" /> <!-- Initially set to 0 -->
<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:background="@color/color2"
android:layout_width="0dp"
android:layout_height="@dimen/height"
android:layout_weight="100" /> <!-- Initially set to full weight -->
</LinearLayout>
// Example function to update the progress
fun updateProgress(p: Float) {
// Ensure p is between 0 and 1
val progress = p.coerceIn(0f, 1f)
// Calculate filled and not filled weights
val filledWeight = (progress * 100).toFloat()
val notFilledWeight = (1 - progress) * 100
// Update weights dynamically
val filledLayout = remoteViews.getViewId(R.id.filled)
val notFilledLayout = remoteViews.getViewId(R.id.not_filled)
// Set the layout weights of the filled and not filled layouts
remoteViews.setViewLayoutWidth(filledLayout, 0) // width will be set because of weight
remoteViews.setViewLayoutWidth(notFilledLayout, 0) // width will be set because of weight
remoteViews.setViewLayoutWeight(filledLayout, filledWeight)
remoteViews.setViewLayoutWeight(notFilledLayout, notFilledWeight)
// Notify the change to the system
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.notify(notificationId, notificationBuilder.build())
}