Notification基础详解三(宽视图布局通知)

来源:互联网 发布:收割机webshell扫描器 编辑:程序博客网 时间:2024/06/07 02:50
Notification基础详解三(宽视图布局通知)

Notification是在你的应用常规界面之外展示的消息。当app让系统发送一个消息的时候,消息首先以图表的形式显示在通知栏。要查看消息的详情需要进入通知抽屉(notificationdrawer)中查看。通知栏和通知抽屉

(notificationdrawer)都是系统层面控制的,你可以随时查看,不限制于app。

Notification 的设计:

作为Android UI中很重要的组成部分,notification拥有专属于自己的设计准则。

Notification的界面元素在通知抽屉中的notification有两种显示方式,取决于你的android版本以及notification drawer的状态:

(1)普通视图

这种风格是notification drawer的标准显示方式。

(2)宽视图

指你的notification被展开的时候会显示更大的视图,这种风格是android4.1之后才有的新特性。

下面将详细介绍宽视图:

只有当notification被展开的时候这种宽视图的notification才会出现,通过手势操作可以展开一个普通的notification(部分定制系统不可以,会直接显示宽视图)。这种风格的notification从android4.1以后才开始支持。下面的截图展示了inbox风格的notification:

你应该注意到了这种notification其实跟普通的没多大差别,

唯一的区别在于数字7-详情区域。

详情区域根据用途可有多种风格:

1.NotificationCompat.BigPictureStyle 大图片风格:详情区域包含一个256dp高度的位图

2.NotificationCompat.BigTextStyle 大文字风格:显示一个大的文字块

3.NotificationCompat.InboxStyle  收件箱风格:显示多行文字  

下面我们用一个Demo来学习一下宽视图的主要用法及注意事项
效果图
布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingLeft="8dp"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <RadioGroup
        android:id="@+id/options_group"
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="0dp">
        <TextView
            android:textAppearance="?android:textAppearanceLarge"
            android:text="Rich Styles"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <RadioButton
            android:id="@+id/option_basic"
            android:text="Basic Notification"
            android:checked="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <RadioButton
            android:id="@+id/option_bigtext"
            android:text="BigText Style"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <RadioButton
            android:id="@+id/option_bigpicture"
            android:text="BigPicture Style"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <RadioButton
            android:id="@+id/option_inbox"
            android:text="Inbox Style"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <TextView
            android:layout_marginTop="8dp"
            android:text="Secured Style"
            android:textAppearance="?android:textAppearanceLarge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <RadioButton
            android:id="@+id/option_private"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Public Version Lockscreen" />
        <RadioButton
            android:id="@+id/option_secret"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Secret Lockscreen"/>
        <RadioButton
            android:id="@+id/option_headsup"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Heads-Up Notification"/>
    </RadioGroup>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Post a Notification"
        android:onClick="onPostClick"/>
</LinearLayout>
activity文件
public class NotificationActivity extends AppCompatActivity {

    private RadioGroup mOptionsGroup;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_notification);

        mOptionsGroup = (RadioGroup) findViewById(R.id.options_group);
    }

    public void onPostClick(View v) {
        final int noteId = mOptionsGroup.getCheckedRadioButtonId();
        final Notification note;
        switch (noteId) {
            case R.id.option_basic:
            case R.id.option_bigtext:
            case R.id.option_bigpicture:
            case R.id.option_inbox:
                note = buildStyledNotification(noteId);
                break;
            case R.id.option_private:
            case R.id.option_secret:
            case R.id.option_headsup:
                note = buildSecuredNotification(noteId);
                break;
            default:
                throw new IllegalArgumentException("Unknown Type");
        }
        NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        manager.notify(noteId, note);
    }

    private Notification buildStyledNotification(int type) {
        Intent launchIntent = new Intent(this, NotificationActivity.class);
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, launchIntent, 0);

        // 使用发送的时间创建通知
        NotificationCompat.Builder builder = new NotificationCompat.Builder(NotificationActivity.this);
        builder.setSmallIcon(R.drawable.btn_play)
                .setTicker("发送了什么")
                .setWhen(System.currentTimeMillis())
                .setAutoCancel(true)
                .setDefaults(Notification.DEFAULT_SOUND)
                .setContentTitle("完成")
                .setContentText("点击这里")
                .setContentIntent(contentIntent);

        switch (type) {
            case R.id.option_basic:
                // 返回简单的通知
                return builder.build();
            case R.id.option_bigtext:
                // 包括两个动作(自定义动作)
                builder.addAction(android.R.drawable.ic_menu_delete, "打电话", contentIntent);
                builder.addAction(android.R.drawable.ic_media_pause, "重新发送", contentIntent);
                // 在展开时使用 BigTextStyle (一个扩展样式)
                NotificationCompat.BigTextStyle textStyle = new NotificationCompat.BigTextStyle(builder);
                textStyle.bigText("Here is some additional text to be displayed when " +
                        "the notification is " + "in expanded mode. I can fit so much content " +
                        "into this giant view!");
                textStyle.setBigContentTitle("我是BigTextStyle");
                textStyle.setSummaryText("我是我是BigTextStyle的setSummaryText");
                return textStyle.build();
            case R.id.option_bigpicture:
                // 添加一个额外的动作
                builder.addAction(android.R.drawable.ic_menu_edit, "View Location", contentIntent);
                // 在展开时使用 BigPictureStyle
                NotificationCompat.BigPictureStyle pictureStyle = new NotificationCompat.BigPictureStyle(builder);
                pictureStyle.setBigContentTitle("我是BigPictureStyle");
                pictureStyle.setSummaryText("我是我是BigPictureStyle的setSummaryText");
                pictureStyle.bigPicture(BitmapFactory.decodeResource(getResources(), R.drawable.fd));
                return pictureStyle.build();
            case R.id.option_inbox:
                // 在展开时使用 InboxStyle
                builder.addAction(android.R.drawable.ic_menu_delete, "打电话", contentIntent);
                builder.addAction(android.R.drawable.ic_media_pause, "重新发送", contentIntent);
                NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(builder);
                inboxStyle.setSummaryText("4 New Tasks");
                inboxStyle.setBigContentTitle("的方式防守打法");
                inboxStyle.addLine("Male Dinner");
                inboxStyle.addLine("Call Mom");
                inboxStyle.addLine("Call Wife First");
                inboxStyle.addLine("Pick up Kids");
                return inboxStyle.build();
            default:
                throw new IllegalArgumentException("Unknown Type");
        }
    }

    // 这些属性可以由用户的通知设置重写
    private Notification buildSecuredNotification(int type) {
        Intent launchIntent = new Intent(this, NotificationActivity.class);
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, launchIntent, 0);

        // 构造基础通知
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
        builder.setContentTitle("账户余额更新")
                .setContentText("你的余额为250,请尽快充值!")
                .setTicker("发送了什么")
                .setSmallIcon(R.drawable.btn_before)
                .setWhen(System.currentTimeMillis())
                .setStyle(new NotificationCompat.BigTextStyle().bigText("你的卡上的余额只有250,请尽快支付余下的钱!"))
                .setContentIntent(contentIntent);

        switch (type) {
            case R.id.option_private:
                // 为安全的锁定屏幕提供独特的通知版本
                Notification publicNote = new NotificationCompat.Builder(this)
                        .setSmallIcon(R.drawable.loading_01)
                        .setContentTitle("存款通知")
                        .setContentText("你已经收到一条重要消息")
                        .setContentIntent(contentIntent)
                        .build();
                return builder.setPublicVersion(publicNote).build();
            case R.id.option_secret:
                // 从安全的锁定屏幕完全隐藏通知
                builder.setVisibility(Notification.VISIBILITY_PRIVATE);
                return builder.build();
            case R.id.option_headsup:
                // 在发布时显示警告通知
                builder.setDefaults(Notification.DEFAULT_SOUND)
                        .setPriority(Notification.PRIORITY_HIGH);
                return builder.build();
            default:
                throw new IllegalArgumentException("Unknown Type");
        }
    }
}

  在创建通知之前,可以添加其他一些有用的参数,比如当用户在状态栏中展开通知时显示在通知列表中的详细文本信息。
        我们向 Builder 传入一个 PendingIntent 参数,它指向我们的 Activity。这个 Intent 使得通知具有可交互功能,即用户在通知列表中点击通知时可以启动一个 Activity。
       对于每个通知事件,这个 Intent 都会启动一个新的 Activity。如果更愿意用一个已经存在的 Activity 实例来响应启动(在栈中只有一个),则可以在 AndroidManifest.xml 中进行设置:
android:launchMode="singleTop"

 在上面的例子中,在 Nitification.defaults 中加上了系统默认的通知声音,当通知发出时就会播放这个声音。

     1、 在上面的例子中,用到了 扩展通知样式:

      从 Android4.1 开始,可以在通知视图中直接显示更加丰富的、具有交互性的信息,这就是通知的样式。

Android 默认提供了三种样式(它们都实现了 Notification.Style ):

-----> BigTextStyle:显示更多的文本信息,例如显示一条消息或者公告的全部内容。

-----> BigPictureStyle:显示全彩的大图片。

-----> InboxStyle:提供了一个条目列表,样子有点像 Gmail 等应用程序中的收件箱视图。

       其中的 Notification.Style 就是一个接口,应用程序可以实现它来显示任意更加适合自己需求的自定义扩展布局。

      (1)、BigTextStyle 样式的通知,它的代码如上。可以通过 Builder 的 addAction() 方法关联自定义动作。这里演示了如何将布局加入整个视图中。本例中,每个动作的响应结果是一样的,但也可以通过为每个动作都关联一个 PendingIntent,这样每个动作就可以在应用程序中有不同的响应结果了。

      (2)、BigPictureStyle 样式的通知,除了使用 bigPicture() 方法传递一张要显示的全彩图外,剩下的内容几乎和 BigTextStyle 一样。

      (3)、 InboxStyle 样式的通知。在 Notification.InboxStyle 样式下,可以通过 addLine() 方法向列表中添加多个条目。本例使用 setSummaryText() 方法对所有的条目进行了分类,在之前的样式中该方法也是可以使用的。如果程序运行的最低版本目标平台是 Android4.1,可以使用 Nitification.Builder 代替支持库中的 NotificationCompat。本例中,我们可以看到支持库的强大。调用了 API Level 16才有的方法,实际上是支持库在底层进行了版本检验,对于某一平台不支持的方法会忽略;不需要建立判断分支代码来使用新 API。因此,当在 Android4.0 或更早版本的设备上运行这段代码时,只会出现简单的传统通知。


       2、通知的可见性和隐私性:

       从 Android5.0 开始,无需下拉状态栏就可以使通知在锁定屏幕上完全显示出来,即使设备受到密码保护也是如此。其效果如下(剩余部分的效果):


其中的特性如下三个方面:

      (1)、通知的可见性设置控制其在安全锁定屏幕上的默认行为,这意味着对锁定屏幕启动密码(option_secret 按钮)。对于需要简单滑动手势解锁的锁定屏幕,这些功能不会执行任何操作。

       系统提供了 3 个通知可见性选项:

-----> VISIBILITY_PRIVATE:通知的编辑版本,仅包含应用程序标题和图标,在设备解锁时可见。这是默认的可见性设置。

-----> VISIBILITY_PUBLIC:无论设置是解锁还是锁定,都会显示完整的通知。

-----> VISIBILITY_SECRET:此通知将在锁定屏幕上完全隐藏。用户必须解锁设备才能看到此通知的存在。

       点击相应的按钮后得到的效果如下:

注:本例使用的是第三个选项,但是无论是调整最低的 Android 版本为4.0.3 还是 5.1,或者把跟着把最高版本从 6.0 调整到 5.1 都没有实现 API 文档中所说的效果。

       (2)、在 Android4.1 和以后的版本中,通知支持优先级设置(option_headsup 按钮)。在 Android5.0 中,该功能使我们可以在浮动显示模式下显示具有较高优先级的通知(如来电通知)。此模式会将通知与应用程序内容重叠,而不需要等待用户下拉状态栏,从而强迫用户立即回应此通知。优先级设置为 PRIORITY_HIGH 或 PRIORITY_MAX 的通知将在浮动显示模式下尽可能显示出来。效果如下:


     (3)、安全通知功能(option_private 按钮),对于此模块,创建了一个基础通知,计划将其作用从包含往来账户余额的用户银行发出的警告。如果用户使设备保持安全,这就是我们应该保护的敏感信息。Android 框架的默认行为将整个通知隐藏在已经编辑视图的后面,如前面的视图。但是此次采取了更友善的方式。第一个用户选项被选中是,我们构造第二个 Notification 实例并将其传递给 setPublicVersion()。这样,在设备解锁时安全地显示此消息。为解锁时则显示的第二个 Notification 中设置的消息。效果如下:


注:虽说在不支持这些 API 的旧平台上,Android 框架将会直接忽略此部分中设置的值,但是经过在 Android5.0 以上的版本中试验(包括部分真机)也没有得到相应的效果。
锁屏通知(Notifications)
在L开发者预览版中,锁屏可以呈现Notification,用户可以通过设置来选择是否允许在锁屏显示敏感Notification内容。
当Notification呈现在锁屏上时,你的app可以控制可见详情权限,调用android.app.Notification.Builder.setVisibility() 来控制可见权限,其中设置值包括:
VISIBILITY_PRIVATE,显示基本信息,例如Notification图标,隐藏Notification全部内容
VISIBILITY_PUBLIC,显示Notification全部内容
VISIBILITY_SECRET,不显示任何内容,包括Notification图标
当设置VISIBILITY_PRIVATE时,你可以提供已经编辑过的隐藏个人详情的Notification,例如,一个SMS app可能呈现一条Notification显示“你有3条新的短信”,但是隐藏短信内容和发送者。
呈现这种替代方案的Notification,首先使用Notification.Builder创建更换Notification,当你创建私人的Notification对象,
使用Notification.Builder.setPublicVersion()方法附加到它上面的更换通知

通知(Notification)元数据
Android L 开发者预览版使用与你的App Notification相关的元数据来更智能的排列,设置元数据,当初始化你的Notification时,可以使用在android.app.Notification.Builder里的这些方法:
setCategory():根据消息分类,当设备处于非打扰模式时,告诉系统如何处理你的App Notification。
setPriority():如果Notification有声音或者振动,设置优先级为PRIORITY_MAX或者PRIORITY_HIGH的Notification将会出现在小的浮动窗口上。
addPerson():允许你添加人列表到Notification,你的app可以使用这些来暗示系统将这些人集中在一起通知,或者通知这些人是很重要的。


亲测Notification.Builder.setVisibility()和Notification.Builder.setPublicVersion()即使是在5.0系统上也没有用



0 0
原创粉丝点击