Android 创建自定义大通知

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21237495/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 04:11:43  来源:igfitidea点击:

Create Custom Big Notifications

androidandroid-layoutandroid-notifications

提问by MalaKa

I wanted to create a Notification including some controls. Since text and controls are small with default notification size (64dp), i wanted have it larger than default size.
It is possible to create larger notifications, and I think it is possible to have a custom layout, too, but I don't know how.

我想创建一个包含一些控件的通知。由于文本和控件很小,默认通知大小 (64dp),我希望它大于默认大小。
可以创建更大的通知,我认为也可以有自定义布局,但我不知道如何。

To be more specific, the following screenshot shows the notification from spotify (image take from here): Spotify notification

更具体地说,以下屏幕截图显示了来自 spotify 的通知(图片取自此处):Spotify 通知

As you can see, the size is bigger than default. Further, it has some kind of ImageButtons without text - if you use Notification.Builder.addAction(), you may provide an icon but also need to provide a CharSequence as a description - if you leave the description empty, there will still be space reserved for the text and if you pass null, it will crash.

如您所见,大小大于默认值。此外,它有一些没有文本的 ImageButtons - 如果你使用Notification.Builder.addAction(),你可以提供一个图标,但也需要提供一个 CharSequence 作为描述 - 如果你将描述留空,仍然会有空间为文本保留,如果您传递null,它将崩溃。

Can anybody tell me how to create a big notification with a custom layout?

谁能告诉我如何使用自定义布局创建大通知?

Thanks

谢谢

回答by MalaKa

Update due to API changes:

由于 API 更改而更新:

From API 24 on, the Notification.Buildercontains a setCustomBigContentView(RemoteViews)-method. Also the NotificationCompat.Builder(which is part of the support.v4 package) contains this method.
Please note, that the documentation for the NotificationCompat.Builder.setCustomBigContentViewstates:

从 API 24 开始,Notification.Builder包含一个setCustomBigContentView(RemoteViews)方法。还NotificationCompat.Builder(这是support.v4包的一部分)包含此方法。
请注意,NotificationCompat.Builder.setCustomBigContentView的文档说明:

Supply custom RemoteViews to use instead of the platform template in the expanded form. This will override the expanded layout that would otherwise be constructed by this Builder object. No-op on versions prior to JELLY_BEAN.

提供自定义 RemoteViews 来代替展开形式的平台模板。这将覆盖否则将由此 Builder 对象构造的扩展布局。JELLY_BEAN 之前的版本无操作。

Therefore, this will also only work for API >= 16 (JELLY_BEAN).

因此,这也仅适用于 API >= 16 (JELLY_BEAN)。



Original Answer

原答案

So after excessive google usage, I found this tutorialexplaining how to use custom big layouts. The trick is not to use setStyle()but manually set the bigContentViewfield of the Notificationafter building it. Seems a bit hacky, but this is what I finally came up with:

所以在过度使用谷歌之后,我发现这个教程解释了如何使用自定义大布局。诀窍不是使用setStyle()而是手动设置构建后bigContentView字段。似乎有点hacky,但这是我最终想出的: Notification

notification_layout_big.xml:

notification_layout_big.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="100dp" <!-- This is where I manually define the height -->
    android:orientation="horizontal" >

    <!-- some more elements.. --> 
</LinearLayout>

Building Notificationin code:

Notification在代码中构建:

Notification foregroundNote;

RemoteViews bigView = new RemoteViews(getApplicationContext().getPackageName(),
    R.layout.notification_layout_big);

// bigView.setOnClickPendingIntent() etc..

Notification.Builder mNotifyBuilder = new Notification.Builder(this);
foregroundNote = mNotifyBuilder.setContentTitle("some string")
        .setContentText("Slide down on note to expand")
        .setSmallIcon(R.drawable.ic_stat_notify_white)
        .setLargeIcon(bigIcon)
        .build();

foregroundNote.bigContentView = bigView;

// now show notification..
NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotifyManager.notify(1, foregroundNote);

Edit
As noted by chx101, this only works for API >= 16. I did not mention it in this answer, yet it was mentioned in the given linked tutorial above:

编辑
正如 chx101 所指出的,这仅适用于 API >= 16。我没有在这个答案中提到它,但在上面给定的链接教程中提到了它:

Expanded notifications were first introduced in Android 4.1 JellyBean [API 16].

扩展通知首先在 Android 4.1 JellyBean [API 16] 中引入。

回答by Ashish Kumar

enter image description hereUsing Kotlin make custom notification
dialog_custom_notification

在此处输入图片说明使用 Kotlin 制作自定义通知
dialog_custom_notification

                    <LinearLayout
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_margin="@dimen/dp_10"
                        android:background="@drawable/shape_bg_main_notification"
                        android:gravity="center"
                        android:orientation="horizontal"
                        android:padding="@dimen/dp_10">

                        <LinearLayout
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="top">

                            <ImageView
                                android:id="@+id/ivAppIcon"
                                android:layout_width="@dimen/dp_36"
                                android:layout_height="@dimen/dp_36"
                                android:layout_gravity="top"
                                android:background="@mipmap/ic_launcher" />
                        </LinearLayout>

                        <LinearLayout
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="top"
                            android:layout_marginLeft="@dimen/dp_10"
                            android:layout_weight="1"
                            android:orientation="vertical">

                            <TextView
                                android:id="@+id/tvNotificationTitle"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:text="Notification Tile"
                                android:textStyle="bold" />

                            <TextView
                                android:id="@+id/tvNotificationDescription"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_marginTop="@dimen/dp_5"
                                android:text="Notification Description" />

                        </LinearLayout>

                        <LinearLayout
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:layout_gravity="top">

                            <TextView
                                android:id="@+id/tvDateTime"
                                android:layout_width="wrap_content"
                                android:layout_height="wrap_content"
                                android:layout_alignParentRight="true"
                                android:layout_gravity="top"
                                android:text="09:50" />
                        </LinearLayout>
                    </LinearLayout>
                </LinearLayout>

        shape_bg_main_notification
        <?xml version="1.0" encoding="utf-8"?>
        <shape xmlns:android="http://schemas.android.com/apk/res/android"
            android:shape="rectangle">
            <solid android:color="@color/white" />

            <corners android:radius="@dimen/dp_6" />

        </shape>



        @SuppressLint("WrongConstant")
                    fun showOfflineNotification(context: Context, title: String, description: String) {
                        val NOTIFICATION_CHANNEL_ID = "com.myapp"
                        val intent = Intent(context, HomeActivity::class.java)
                        intent.putExtra("notification", 1)
                        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
                        if (intent != null) {
                            val pendingIntent = PendingIntent.getActivity(
                                context, getTwoDigitRandomNo(), intent,
                                PendingIntent.FLAG_ONE_SHOT
                            )
                            val defaultSoundUri =
                                RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)

                            val remoteCollapsedViews = RemoteViews(packageName, R.layout.dialog_custom_notification)
                            remoteCollapsedViews.setTextViewText(R.id.tvNotificationTitle, title)
                            remoteCollapsedViews.setTextViewText(R.id.tvNotificationDescription, description)
                            remoteCollapsedViews.setTextViewText(R.id.tvDateTime, getTime())

                            val notificationBuilder = NotificationCompat.Builder(context)
                            notificationBuilder.setCustomBigContentView(remoteCollapsedViews)
                            notificationBuilder.setSmallIcon(R.mipmap.ic_launcher_round)
                            notificationBuilder.setLargeIcon(
                                BitmapFactory.de

        codeResource(
                                        context.resources,
                                        R.mipmap.ic_launcher
                                    )
                                )
                                notificationBuilder.setBadgeIconType(R.mipmap.ic_launcher_round)
                                notificationBuilder.setContentTitle(title)
                                if (description != null) {
                                    notificationBuilder.setContentText(description)
                                    notificationBuilder.setStyle(
                                        NotificationCompat.BigTextStyle().bigText(description)
                                    )
                                }
                                notificationBuilder.setPriority(NotificationCompat.PRIORITY_HIGH)
                                notificationBuilder.setAutoCancel(true)
                                notificationBuilder.setSound(defaultSoundUri)
                                notificationBuilder.setVibrate(longArrayOf(1000, 1000))
                                notificationBuilder.setContentIntent(pendingIntent)

                                val notificationManager =
                                    context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                                    val importance = NotificationManager.IMPORTANCE_MAX
                                    val notificationChannel = NotificationChannel(
                                        NOTIFICATION_CHANNEL_ID,
                                        "NOTIFICATION_CHANNEL_NAME",
                                        importance
                                    )
                                    notificationChannel.enableLights(true)
                                    notificationChannel.lightColor = Color.RED
                                    notificationChannel.enableVibration(true)
                                    notificationChannel.vibrationPattern = longArrayOf(1000, 1000)
                                    assert(notificationManager != null)
                                    notificationBuilder.setChannelId(NOTIFICATION_CHANNEL_ID)
                                    notificationManager.createNotificationChannel(notificationChannel)
                                }
                                notificationManager.notify(
                                    getTwoDigitRandomNo()/*Id of Notification*/,
                                    notificationBuilder.build()
                                )
                            }
                        }

                        private fun getTime(): String {
                            val calendar = Calendar.getInstance()
                            val mdformat = SimpleDateFormat("HH:mm")
                            val strDate = mdformat.format(calendar.time)
                            return strDate
                        }

                        fun getTwoDigitRandomNo(): Int {
                            return Random().nextInt(90) + 10
                        }



      [1]: https://me.stack.imgur.com/rQFP8.png


  [1]: https://me.stack.imgur.com/fKM9C.png