欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android Notification自定义样式

程序员文章站 2022-07-13 15:38:54
...

最近开发一个app需要显示Notification, 但是这个Notification的title 需要显示成我们另一只app的名字。查找了很多资料,发现如果用系统默认的样式,这是做不到的。所以只能自定义样式。自定义Notification样式要用到RemoteViews,如下:

    //自定义的notification, 可以自己指定最上面的Title, 即下面给R.id.tag_tv 控件的字串
    //指定了两个layout ,即一个普通视图,一个是大视图。普通视图content只显示一行,显示不了的有省略号。
    // 大视图content可以显示多行。这种notify 可大可小,自动变化
    @TargetApi(16)
    public static void sendCustomNotifyType(Context context, Intent intent, String content,int notifyId) {
        int iUniqueId = (int) (System.currentTimeMillis() & 0xfffffff);
        //getActivity must set  oneof the params of second (as iUniqueId) and forth(PendingIntent.FLAG_UPDATE_CURRENT)
        //or the Activity while show the same as the first time package.
        PendingIntent contentIntent = PendingIntent.getActivity(context, iUniqueId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        final Notification.BigTextStyle bigTextStyle = new Notification.BigTextStyle();
        Notification.Builder builder = new Notification.Builder(context);
        builder.setOngoing(false);
        builder.setPriority(Notification.PRIORITY_MAX);
        builder.setSmallIcon(R.mipmap.noti_icon);
        builder.setAutoCancel(true);
        builder.setContentIntent(contentIntent);
        bigTextStyle.setBigContentTitle(context.getResources().getString(R.string.asus_mobile_manager));
        bigTextStyle.bigText(content);
        builder.setStyle(bigTextStyle);
        builder.setGroup("demogroup1");//如果不加group, 会导致发送四个Notification就会多一个空的notification出来

        RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.view_notification_type_0_singleline);
        remoteViews.setTextViewText(R.id.tag_tv,context.getResources().getString(R.string.asus_mobile_manager));//Top Title
        remoteViews.setTextViewText(R.id.title_tv,context.getResources().getString(R.string.app_name));//src title
        remoteViews.setTextViewText(R.id.content_tv, content);
        remoteViews.setTextViewText(R.id.time_tv, getTime());
        remoteViews.setImageViewResource(R.id.icon_iv, R.mipmap.app_icon);

        RemoteViews remoteViewsBig = new RemoteViews(context.getPackageName(),R.layout.view_notification_type_0);
        remoteViewsBig.setTextViewText(R.id.tag_tv,context.getResources().getString(R.string.asus_mobile_manager));//Top Title
        remoteViewsBig.setTextViewText(R.id.title_tv,context.getResources().getString(R.string.app_name));//src title
        remoteViewsBig.setTextViewText(R.id.content_tv, content);
        remoteViewsBig.setTextViewText(R.id.time_tv, getTime());
        remoteViewsBig.setImageViewResource(R.id.icon_iv, R.mipmap.app_icon);

        builder.setCustomBigContentView(remoteViewsBig);
        builder.setCustomContentView(remoteViews);

        Notification notification = builder.build();

        /*if(android.os.Build.VERSION.SDK_INT >= 16) {
           notification = builder.build();
           notification.bigContentView = remoteViews;

        }
        notification.contentView = remoteViews;
        */
        NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        //notify id 如果相同,则不管调用几次这个函数,最后,都只出来一个notification
        if(notifyId == 0)
            manager.notify(iUniqueId, notification);
        else
            manager.notify(notifyId, notification);
    }

其中R.layout.view_notification_type_0的定义如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingTop="12dp"
    android:paddingBottom="12dp"
    android:id="@+id/notice_view">

    <LinearLayout android:id="@+id/title_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        android:gravity="center_vertical"
        android:paddingStart="10dip"
        android:paddingEnd="10dip">
        <ImageView android:id="@+id/icon_iv"
            android:layout_width="26dp"
            android:layout_height="26dp"
            android:scaleType="fitCenter"
            android:padding="4dp"
            />
        <TextView
            android:id="@+id/tag_tv"
            android:textAppearance="@android:style/TextAppearance.Material.Notification.Title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal"
            android:layout_marginLeft="2dp"
            />
        <TextView
            android:id="@+id/time_tv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textSize="10sp"
            android:gravity="right"
            android:paddingTop="2dip"
            android:paddingBottom="1dip"
            android:paddingStart="14dip"
            android:textAppearance="@android:style/TextAppearance.Material.Notification.Time"
            android:layout_centerVertical="true"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_marginLeft="16dp"
        android:layout_gravity="center_vertical">

        <TextView
            android:id="@+id/title_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="@android:style/TextAppearance.Material.Notification.Title"
            android:layout_marginRight="16dp"
            android:layout_marginTop="-1dp"
            android:layout_marginBottom="-1dp"
            android:fadingEdge="horizontal"
            android:ellipsize="marquee"
            android:layout_weight="1"
            />

        <TextView
            android:id="@+id/content_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="@android:style/TextAppearance.Material.Notification.Title"
            android:layout_marginRight="16dp"
            android:layout_marginTop="-1dp"
            android:layout_marginBottom="-1dp"
            android:fadingEdge="horizontal"
            android:ellipsize="marquee"
            android:layout_weight="1"
            />
    </LinearLayout>
</LinearLayout>

我们主要就是用这个layout创建一个RemoteViews, 然后用这个RemoteViews 替换Notification 的contentView

要强调的几点是,
1.设置bigstyle ,如果你的content字串过长,而又不设置bigstyle,那就会只显示一半,像是被从上往下压得只剩一半了。或者设置了bigstyle, 但是bigcontentview 和contentview用同一个Remoteview, 也会有同样的问题,因为通知多了以后,下面的通知即使是bigstyle, 给的空间仍会变小。所以,我们需要给contentview,和bigcontentview同时指定一个Remoteview, 且,前者content可以只显示一行, 后者content 可以显示多行。这样,你的通知就可以自动根据不同位置,不同空间,应用不同的显示样式。即空间大时,content可以全部显示出来。空间小时,只显示单行,后面加一个省略号,表示后面还有内容。

 2,要setGroup也很重要,如上面所注,如果不设置group, 会导致发送四个Notification后就会多一个空的notification出来,这个空notification点上去没有反应,而且title是我们的app name.
3. pendingIntent.getActivity(), 要指定最后一个参数PendingIntent.FLAG_UPDATE_CURRENT,否则,点击通知时,打开的Activity 内容不会刷新。
4. manager.notify(notifyId, notification);这个notifyId,如果每次发通知这个id相同,则只显示最后一次发的,即只保留一个。只有每次id不一样,才可都保留下来,这就用到了上面第2点的setgroup,否则就有空通知出来的可能。

相关标签: android app