Android Notification自定义样式
最近开发一个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状态栏适配问题