Android Notification常見樣式總結

轉載自 http://blog.csdn.net/w804518214/article/details/51231946

所需權限

    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.FLASHLIGHT"/>

一.普通通知

這是最常見通知樣式,如下圖
這裏寫圖片描述
這裏寫圖片描述

舉例

private void simpleNotify(){
        //爲了版本兼容  選擇V7包下的NotificationCompat進行構造
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        //Ticker是狀態欄顯示的提示
        builder.setTicker("簡單Notification");
        //第一行內容  通常作爲通知欄標題
        builder.setContentTitle("標題");
        //第二行內容 通常是通知正文
        builder.setContentText("通知內容");
        //第三行內容 通常是內容摘要什麼的 在低版本機器上不一定顯示
        builder.setSubText("這裏顯示的是通知第三行內容!");
        //ContentInfo 在通知的右側 時間的下面 用來展示一些其他信息
        //builder.setContentInfo("2");
        //number設計用來顯示同種通知的數量和ContentInfo的位置一樣,如果設置了ContentInfo則number會被隱藏
        builder.setNumber(2);
        //可以點擊通知欄的刪除按鈕刪除
        builder.setAutoCancel(true);
        //系統狀態欄顯示的小圖標
        builder.setSmallIcon(R.mipmap.ic_launcher);
        //下拉顯示的大圖標
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.push));
        Intent intent = new Intent(this,SettingsActivity.class);
        PendingIntent pIntent = PendingIntent.getActivity(this,1,intent,0);
        //點擊跳轉的intent
        builder.setContentIntent(pIntent);
        //通知默認的聲音 震動 呼吸燈 
        builder.setDefaults(NotificationCompat.DEFAULT_ALL);
        Notification notification = builder.build();
        manger.notify(TYPE_Normal,notification);
    }

build內提供了很多設置,但是在不同的系統版本顯示有很多差異,使用時需要注意

  1. setTicker 通知到來時低版本上會在系統狀態欄顯示一小段時間 5.0以上版本好像沒有用了
  2. setContentInfo和setNumber同時使用 number會被隱藏
  3. setSubText顯示在通知欄的第三行文本,在低版本上不顯示,比如4.0系統
  4. setVibrate設置震動 參數是個long[]{震動時長,間隔時長,震動時長,間隔時長…}單位毫秒 設置提醒聲音 setSound(Uri sound) 一般默認的就好
  5. builder.setLights()設置呼吸燈的顏色 並不是所有顏色都被支持 個人感覺沒什麼用
  6. 清除通知欄特定通知 manager.cancel(id) id即爲manger.notify()的第一個參數

二.下載進度的通知

效果圖
這裏寫圖片描述

代碼舉例
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.push));
        //禁止用戶點擊刪除按鈕刪除
        builder.setAutoCancel(false);
        //禁止滑動刪除
        builder.setOngoing(true);
        //取消右上角的時間顯示
        builder.setShowWhen(false);
        builder.setContentTitle("下載中..."+progress+"%");
        builder.setProgress(100,progress,false);
        //builder.setContentInfo(progress+"%");
        builder.setOngoing(true);
        builder.setShowWhen(false);
        Intent intent = new Intent(this,DownloadService.class);
        intent.putExtra("command",1);
        Notification notification = builder.build();
        manger.notify(MainActivity.TYPE_Progress,notification);
注意事項
1. setProgress的第三個bool類型的參數表示progressbar的Indeterminate屬性 指是否使用不確定模式

2. 高版本上progressbar的進度值可以在setContentInfo顯示,但是低版本上使用這個屬性會導致progressbar不顯示,setContentText一樣

三.BigTextStyle通知

點擊後展開可顯示大段文字內容的通知

效果圖
點擊前
這裏寫圖片描述
點擊後
這裏寫圖片描述

代碼舉例

    private void bigTextStyle(){

        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setContentTitle("BigTextStyle");
        builder.setContentText("BigTextStyle演示示例");
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.notification));
        android.support.v4.app.NotificationCompat.BigTextStyle style = new android.support.v4.app.NotificationCompat.BigTextStyle();
        style.bigText("這裏是點擊通知後要顯示的正文,可以換行可以顯示很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長很長");
        style.setBigContentTitle("點擊後的標題");
        //SummaryText沒什麼用 可以不設置
        style.setSummaryText("末尾只一行的文字內容");
        builder.setStyle(style);
        builder.setAutoCancel(true);
        Intent intent = new Intent(this,SettingsActivity.class);
        PendingIntent pIntent = PendingIntent.getActivity(this,1,intent,0);
        builder.setContentIntent(pIntent);
        builder.setDefaults(NotificationCompat.DEFAULT_ALL);
        Notification notification = builder.build();
        manger.notify(TYPE_BigText,notification);
    }
注意事項
1. 使用類 Android.support.v4.app.NotificationCompat.BigTextStyle
2. 在低版本系統上只顯示點擊前的普通通知樣式 如4.4可以點擊展開,在4.0系統上就不行
3. 點擊前後的ContentTitle、ContentText可以不一致,bigText內容可以自動換行 好像最多5行的樣子

四.InboxStyle

與bigTextStyle類似,點擊前顯示普通通知樣式,點擊後展開
效果圖 (點擊後)
這裏寫圖片描述

代碼舉例

    public void inBoxStyle(){
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setContentTitle("InboxStyle");
        builder.setContentText("InboxStyle演示示例");
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.notification));
        android.support.v4.app.NotificationCompat.InboxStyle style = new android.support.v4.app.NotificationCompat.InboxStyle();
        style.setBigContentTitle("BigContentTitle")
                .addLine("第一行,第一行,第一行,第一行,第一行,第一行,第一行")
                .addLine("第二行")
                .addLine("第三行")
                .addLine("第四行")
                .addLine("第五行")
                .setSummaryText("SummaryText");
        builder.setStyle(style);
        builder.setAutoCancel(true);
        Intent intent = new Intent(this,SettingsActivity.class);
        PendingIntent pIntent = PendingIntent.getActivity(this,1,intent,0);
        builder.setContentIntent(pIntent);
        builder.setDefaults(NotificationCompat.DEFAULT_ALL);
        Notification notification = builder.build();
        manger.notify(TYPE_Inbox,notification);
    }
注意事項
1. 使用類android.support.v4.app.NotificationCompat.InboxStyle
2. 每行內容過長時並不會自動換行
3. addline可以添加多行 但是多餘5行的時候每行高度會有截斷
4. 同BigTextStyle 低版本上系統只能顯示普通樣式

五.BigPictureStyle

點擊後可以顯示一個大圖的通知
效果圖(點擊後)
這裏寫圖片描述

代碼舉例
public void bigPictureStyle(){
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setContentTitle("BigPictureStyle");
        builder.setContentText("BigPicture演示示例");
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setDefaults(NotificationCompat.DEFAULT_ALL);
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.notification));
        android.support.v4.app.NotificationCompat.BigPictureStyle style = new android.support.v4.app.NotificationCompat.BigPictureStyle();
        style.setBigContentTitle("BigContentTitle");
        style.setSummaryText("SummaryText");
        style.bigPicture(BitmapFactory.decodeResource(getResources(),R.drawable.small));
        builder.setStyle(style);
        builder.setAutoCancel(true);
        Intent intent = new Intent(this,ImageActivity.class);
        PendingIntent pIntent = PendingIntent.getActivity(this,1,intent,0);
        //設置點擊大圖後跳轉
        builder.setContentIntent(pIntent);
        Notification notification = builder.build();
        manger.notify(TYPE_BigPicture,notification);
    }

注意事項
1. 使用類android.support.v4.app.NotificationCompat.BigPictureStyle
2. style.bigPicture傳遞的是個bitmap對象 所以也不應該傳過大的圖 否則會oom
3. 同BigTextStyle 低版本上系統只能顯示普通樣式

六.hangup橫幅通知

類似於手機QQ消息的通知,不顯示在通知欄而是以橫幅的模式顯示在其他應用上方

效果圖
這裏寫圖片描述

代碼示例

NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setContentTitle("橫幅通知");
        builder.setContentText("請在設置通知管理中開啓消息橫幅提醒權限");
        builder.setDefaults(NotificationCompat.DEFAULT_ALL);
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.notification));
        Intent intent = new Intent(this,ImageActivity.class);
        PendingIntent pIntent = PendingIntent.getActivity(this,1,intent,0);
        builder.setContentIntent(pIntent);
        //這句是重點
        builder.setFullScreenIntent(pIntent,true);
        builder.setAutoCancel(true);
        Notification notification = builder.build();
        manger.notify(TYPE_Hangup,notification);
注意事項
1. 此種效果只在5.0以上系統中有效
2. mainfest中需要添加<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
3. 可能還需要在設置開啓橫幅通知權限(在設置通知管理中)
4. 在部分改版rom上可能會直接彈出應用而不是顯示橫幅

七.MediaStyle

主要是用來關聯音頻播放服務的,點擊後不會自動消失,通知欄的清空也不可用
效果圖
點擊前
這裏寫圖片描述
點擊展開後
這裏寫圖片描述
在4.0系統上的效果 不能展開但是可以最多顯示3個按鈕外加一個CancelButton
這裏寫圖片描述

代碼示例
    private void mediaStyle(){
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setContentTitle("MediaStyle");
        builder.setContentText("Song Title");
        builder.setSmallIcon(R.mipmap.ic_launcher);
        builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.notification));
        builder.setDefaults(NotificationCompat.DEFAULT_ALL);
        Intent intent = new Intent(this,ImageActivity.class);
        PendingIntent pIntent = PendingIntent.getActivity(this,1,intent,0);
        builder.setContentIntent(pIntent);
        //第一個參數是圖標資源id 第二個是圖標顯示的名稱,第三個圖標點擊要啓動的PendingIntent
        builder.addAction(R.drawable.ic_previous_white,"",null);
        builder.addAction(R.drawable.ic_stop_white,"",null);
        builder.addAction(R.drawable.ic_play_arrow_white_18dp,"",pIntent);
        builder.addAction(R.drawable.ic_next_white,"",null);
        NotificationCompat.MediaStyle style = new NotificationCompat.MediaStyle();
        style.setMediaSession(new MediaSessionCompat(this,"MediaSession",
                new ComponentName(MainActivity.this,Intent.ACTION_MEDIA_BUTTON),null).getSessionToken());
        //CancelButton在5.0以下的機器有效
        style.setCancelButtonIntent(pIntent);
        style.setShowCancelButton(true);
        //設置要現實在通知右方的圖標 最多三個
        style.setShowActionsInCompactView(2,3);
        builder.setStyle(style);
        builder.setShowWhen(false);
        Notification notification = builder.build();
        manger.notify(TYPE_Media,notification);
    }
注意事項
1. 使用類v7包下的NotificationCompat.MediaStyle
2. addAction方法並普通樣式也可以用,使用後普通通知可以點擊展開,展開部分會顯示一排添加的圖標,並且可以給每個圖標設置不同的點擊事件
3. 最多可以添加5哥action 並排顯示在點擊展開的部分
4. setShowActionsInCompactView的參數是添加的action在所有action組成的數組中的下標,從0開始
5. setShowActionsInCompactView設置的action會顯示在點擊前的通知的右側,低版本上也可以顯示
6. setShowCancelButton(true)會在通知的右上部分顯示一個刪除圖標 5.0以下有效

八.自定義通知欄佈局

其實就是設置一個romateViews
演示效果
這裏寫圖片描述

代碼示例
    //command是自定義用來區分各種點擊事件的
    private void sendCustomerNotification(int command){
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setContentTitle("Notification");
        builder.setContentText("自定義通知欄示例");
        builder.setSmallIcon(R.mipmap.ic_launcher);
        //builder.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.push));
        builder.setAutoCancel(false);
        builder.setOngoing(true);
        builder.setShowWhen(false);
        RemoteViews remoteViews = new RemoteViews(getPackageName(),R.layout.notification_template_customer);
        remoteViews.setTextViewText(R.id.title,"Notification");
        remoteViews.setTextViewText(R.id.text,"song"+index);
        if(command==CommandNext){
            remoteViews.setImageViewResource(R.id.btn1,R.drawable.ic_pause_white);
        }else if(command==CommandPlay){
            if(playerStatus==StatusStop){
                remoteViews.setImageViewResource(R.id.btn1,R.drawable.ic_pause_white);
            }else{
                remoteViews.setImageViewResource(R.id.btn1,R.drawable.ic_play_arrow_white_18dp);
            }
        }
        Intent Intent1 = new Intent(this,MediaService.class);
        Intent1.putExtra("command",CommandPlay);
        //getService(Context context, int requestCode, @NonNull Intent intent, @Flags int flags)
        //不同控件的requestCode需要區分開 getActivity broadcoast同理
        PendingIntent PIntent1 =  PendingIntent.getService(this,5,Intent1,0);
        remoteViews.setOnClickPendingIntent(R.id.btn1,PIntent1);

        Intent Intent2 = new Intent(this,MediaService.class);
        Intent2.putExtra("command",CommandNext);
        PendingIntent PIntent2 =  PendingIntent.getService(this,6,Intent2,0);
        remoteViews.setOnClickPendingIntent(R.id.btn2,PIntent2);

        Intent Intent3 = new Intent(this,MediaService.class);
        Intent3.putExtra("command",CommandClose);
        PendingIntent PIntent3 =  PendingIntent.getService(this,7,Intent3,0);
        remoteViews.setOnClickPendingIntent(R.id.btn3,PIntent3);

        builder.setContent(remoteViews);
        Notification notification = builder.build();
        manger.notify(MainActivity.TYPE_Customer,notification);
    }

佈局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/status_bar_latest_event_content"
    android:layout_width="match_parent"
    android:layout_height="64dp" android:gravity="center_vertical"
    android:orientation="horizontal">
    <ImageView android:id="@+id/icon"
        android:layout_width="64dp"
        android:layout_height="50dp"
        android:scaleType="fitCenter"
        android:src="@drawable/push"/>
    <LinearLayout android:orientation="vertical"
        android:paddingRight="8dp"
        android:paddingEnd="8dp"
        android:paddingTop="2dp"
        android:paddingBottom="2dp"
        android:layout_width="0dp" android:layout_weight="1"
        android:layout_height="wrap_content">

        <TextView android:id="@+id/title"
            android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:layout_marginLeft="2dp"
            android:layout_marginStart="2dp"
            android:paddingTop="6dp"
            android:paddingBottom="6dp"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal"
            android:layout_weight="1"
            android:text="Title"/>

        <TextView android:id="@+id/text"
            android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="2dp"
            android:layout_marginStart="2dp"
            android:singleLine="true"
            android:text="Content"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal"
            />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/media_actions"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="center_vertical|end"
        android:orientation="horizontal"
        android:layoutDirection="ltr"
        >
        <ImageButton
            style="?android:attr/borderlessButtonStyle"
            android:id="@+id/btn1"
            android:layout_width="48dp"
            android:layout_height="match_parent"
            android:layout_marginLeft="2dp"
            android:layout_marginRight="2dp"
            android:layout_weight="1"
            android:src="@drawable/ic_play_arrow_white_18dp"
            android:gravity="center"
            />
        <ImageButton
            style="?android:attr/borderlessButtonStyle"
            android:id="@+id/btn2"
            android:layout_width="48dp"
            android:layout_height="match_parent"
            android:layout_marginLeft="2dp"
            android:layout_marginRight="2dp"
            android:layout_weight="1"
            android:src="@drawable/ic_next_white"
            android:gravity="center"
            />
        <ImageButton
            style="?android:attr/borderlessButtonStyle"
            android:id="@+id/btn3"
            android:layout_width="48dp"
            android:layout_height="match_parent"
            android:layout_marginLeft="2dp"
            android:layout_marginRight="2dp"
            android:layout_weight="1"
            android:src="@drawable/abc_ic_clear_mtrl_alpha"
            android:gravity="center"
            />
    </LinearLayout>

    <ImageView android:id="@+id/end_padder"
        android:layout_width="6dp"
        android:layout_height="match_parent"
        />
</LinearLayout>
注意事項
1. 不同控件 PendingIntent.getXXX的requestCode不能相同
2. RemoteViews的具體用法請自行百度 這裏就不展開說明了
3. 自定義佈局的高需要是64dp 沒有爲什麼 官方給的
4. 需要更改通知欄佈局的時候 其實就是以同一個NotifyId發個新的通知 替換掉老的
5. LargeIcon可以不設置,但是smallIcon和title需要設置,不然通知不能顯示
6. LargeIcon如果設置了並且自定義佈局內相同位置還有一個icon的畫在低版本系統上可能會都顯示,高版本不會顯示LargeIcon

九.仿 QQ 音樂的 Notification

有人想要仿 QQ 音樂的樣式,其實代碼很簡單和自定義的差不多。

點擊或下拉後展示效果圖
這裏寫圖片描述
代碼示例

    if(Build.VERSION.SDK_INT>=16){
        Notification notification = new Notification();
        notification.icon = R.mipmap.ic_launcher;
        notification.tickerText = "BigContent";
        notification.contentView = new RemoteViews(getPackageName(), R.layout.notification_template_customer);
        RemoteViews expandedView = new RemoteViews(getPackageName(), R.layout.notification_big_content);
        //contentView和expandedView的 pendingIntent 我就不寫了 和自定義的一樣的
        notification.bigContentView = expandedView;
        manger.notify(10,notification);
    }else{
        Toast.makeText(MainActivity.this, "系統版本過低,不支持此種樣式!", Toast.LENGTH_SHORT).show();
    }

R.layout.notification_big_content的佈局文件也很簡單就不上代碼了
需要注意的是
bigContentView是 api16以上才支持的,所以4.1以下還是沒有效果的
另外bigContentView佈局的高度需要是100dp。

Demo下載地址
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章