前言

RemoteViews表面意思就是远程的view,这个就很难理解了,远程的view。但是英语是抽象,remote本身就是偏僻的,偏远的意思。

所以remoteViews 就是地方view,天高皇帝远,要管理地方的view就需要下达圣旨了。

用途:一般就是通知栏与桌面小部件。

通知栏好理解,微信通知经常见到。

桌面小部件,这个无论是苹果还是按照,都有这个东西。



这些就是系统自带的,然后我们也可以自己开发,但是这东西用的并不多,也有特定的app专门做这个,可以把桌面定制的吊炸天。

正文

如果说起这个remoteView,就必须提到一个巡按,这个巡按的名字就叫做pendingIntent。古时候,有些君主会留一个巡按在某一个地方,如果发生了一些大事,就要禀报一下。

remoteView 天高皇帝远,皇帝就要派一个自己人去体察民情,反馈和禀报。因为无法通过findViewById去直接控制地方,所以呢,当remoteView去上任的时候呢,一般都会带上pendingIntent。

pendingIntent 走的时候呢,一般要带上一个intent。比如皇帝派下去一个pendingIntent 和 remoteView 去上任,remoteView 年轻力壮,怕自己不在了,所以走得时候下了一封密旨给pendingIntent。

当用户点击的时候,pendingIntent就带上intent发给中央,留下老皇帝触发用户点击通知栏事件后续要做的事情,大概就是这么一个理。

notification

remoteView 其中一个应用就是通知栏。在通知栏的api(android 不同版本有不同的api,比如说android4.4的api就是19)中,因为api的变换,导致了需要根据不同版本去书写不同的code,美其名曰:兼容。

简单的通知就是这样:

public void createNotify(View view) {
Intent resultIntent = new Intent(this, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
/*
使用Builder构造器来创建Notification对象
*/
Notification notification = new NotificationCompat.Builder(this, "defult")
//指定通知的标题内容
.setContentTitle("Hello Word")
//设置通知的内容
.setContentText("This is just text")
//指定通知被创建的时间
.setWhen(System.currentTimeMillis())
//设置通知的小图标
.setSmallIcon(R.drawable.ic_launcher_foreground)
//设置通知的大图标
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_background))
//添加点击跳转通知跳转
.setContentIntent(resultPendingIntent)
//实现点击跳转后关闭通知
.setAutoCancel(true)
.build();
//id 固定只能是通知到这个通知块,可更新
notificationManager.notify(1, notification);
}

效果:



然后定制是这样的:

我们需要制定界面:

<?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="80dp"
>
<ImageView
android:layout_width="80dp"
android:layout_height="match_parent"
android:id="@+id/icon"
android:src="@color/colorPrimary"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="title"
android:textSize="20dp"
android:id="@+id/title"
android:layout_marginLeft="20dp"
android:gravity="center|left"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="content"
android:textSize="18dp"
android:id="@+id/content"
android:layout_marginLeft="40dp"
android:gravity="center|left"
/>
</LinearLayout>
</LinearLayout>

然后通过remoteViews 来建立他们之间的沟通。

其实简单来说,我们的通知消息就是一个app,通过remoteViews 实现了我们app和通知栏app之间的沟通。

下面是实现code:

public void createCustomNotify(View view) {
Intent resultIntent = new Intent(this, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT); NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
/*
使用Builder构造器来创建Notification对象
*/
RemoteViews remoteView =new RemoteViews(getPackageName(),R.layout.notification_layout);
remoteView.setImageViewResource(R.id.icon,R.drawable.ic_launcher_foreground);
remoteView.setTextViewText(R.id.title,"标题");
remoteView.setTextViewText(R.id.content,"内容");
Notification notification = new NotificationCompat.Builder(this, "defult")
.setContent(remoteView)
//指定通知被创建的时间
.setWhen(System.currentTimeMillis())
//设置通知的小图标
.setSmallIcon(R.drawable.ic_launcher_foreground)
//设置通知的大图标
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_background))
//添加点击跳转通知跳转
.setContentIntent(resultPendingIntent)
.setShowWhen(true)
//实现点击跳转后关闭通知
.setAutoCancel(true)
.build(); //id 固定只能是通知到这个通知块,可更新
notificationManager.notify(2, notification);
}

效果:



非常不好看哈。

如果是这样的自定义,只是界面上的花哨,我们可以点击图片后然后执行一些东西这样才能体现定义。

remoteViews 比如说通知通过intent,然后会用startActivity 去执行intent,所以打开了。

然后同样自定义的同样可以通过intent,在这里,假如自定义layout上有多个的事件,单纯去startActivity效果就无法实现了。

但是如果我们能监听到这个intent那么很多问题就简单了。

创建广播监听:

public class myBroadcastReceiver extends BroadcastReceiver {
public static final String actionImage="imageCallback";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (actionImage.equals(actionImage))
{
Toast.makeText(context,"do this",Toast.LENGTH_SHORT).show();
}
}
}

然后再去创建监听:

private void init()
{
myBroadcastReceiver = new myBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter(myBroadcastReceiver.actionImage);
registerReceiver(myBroadcastReceiver, intentFilter);
}

最后只有设置绑定,也就是说用户点击某些事件后。

    public void createCustomNotify(View view) {
Intent resultIntent = new Intent(this, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
/*
使用Builder构造器来创建Notification对象
*/
RemoteViews remoteView =new RemoteViews(getPackageName(),R.layout.notification_layout);
remoteView.setImageViewResource(R.id.icon,R.drawable.ic_launcher_foreground);
remoteView.setTextViewText(R.id.title,"标题");
remoteView.setTextViewText(R.id.content,"内容");
Intent imageIntent=new Intent(myBroadcastReceiver.actionImage);
PendingIntent imagePintent=PendingIntent.getBroadcast(this,0,imageIntent,0);
remoteView.setOnClickPendingIntent(R.id.icon,imagePintent);
Notification notification = new NotificationCompat.Builder(this, "defult")
.setContent(remoteView)
//指定通知被创建的时间
.setWhen(System.currentTimeMillis())
//设置通知的小图标
.setSmallIcon(R.drawable.ic_launcher_foreground)
//设置通知的大图标
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_background))
//添加点击跳转通知跳转
.setContentIntent(resultPendingIntent)
.setShowWhen(true)
//实现点击跳转后关闭通知
.setAutoCancel(true)
.build(); //id 固定只能是通知到这个通知块,可更新
notificationManager.notify(2, notification);
}

关键部分就是:

// 实例化一个intent
Intent imageIntent=new Intent(myBroadcastReceiver.actionImage);
// 绑定intent,并且以广播的形式执行
PendingIntent imagePintent=PendingIntent.getBroadcast(this,0,imageIntent,0);
// 在icon 点击的时候触发
remoteView.setOnClickPendingIntent(R.id.icon,imagePintent);

效果:

总之就是这个套路了,但是到了android 8 套路就换了,多了一个notificationChannel。

notificationChannel 这个东西用来做啥的呢?

我理解是频道的意思,比如说通知,用户可以更好的管理,接收还是不接受通知。

这东西就是来管理通知的,以前通知过于分散,设置一个id就是一个通知,然后用户不想要要一个一个去取消,同样开发者也麻烦。

    @RequiresApi(api = Build.VERSION_CODES.O)
public void createNotificationChannel(String id, String name, int importance, String desc, String groupId) {
if (mNotificationManager.getNotificationChannel(id) != null) return;
NotificationChannel notificationChannel = new NotificationChannel(id, name, importance);
notificationChannel.enableLights(true);
notificationChannel.enableVibration(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
notificationChannel.setShowBadge(true);
notificationChannel.setBypassDnd(true);
notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400});
notificationChannel.setDescription(desc);
notificationChannel.setGroup(groupId);
// notificationChannel.setSound();
mNotificationManager.createNotificationChannel(notificationChannel);
}

上述中关键部分就两个一个是创建:

NotificationChannel notificationChannel = new NotificationChannel(id, name, importance);
mNotificationManager.createNotificationChannel(notificationChannel);

然后加入进去。中间的基本都是设置了,比如设置分为一个组setGroup,给一些描述setDescription等,必须这个id 注册后才能用于通知中。

Notification notification = new NotificationCompat.Builder(this, "defult")

上面这个defult设置为上面注册的id就行。

然后还有一个关键点:

Notification notification = new NotificationCompat.Builder(this, "defult")

可以设置角标,这就非常好了。在android 我们看到很少有应用可以有角标,基本上看到的只有qq,微信这些霸主才可以。实际上android 系统本身并没有开发,到了8才开发,但是腾讯和这些手机商有一些XXX,所以能拿到手机应用的角标。

到了8后,就不需要了,google本身就支持了。

总结

RemoteViews 不是一种远程view,而是一种远程控制view的方式。

RemoteViews 整理的更多相关文章

  1. dotNET跨平台相关文档整理

    一直在从事C#开发的相关技术工作,从C# 1.0一路用到现在的C# 6.0, 通常情况下被局限于Windows平台,Mono项目把我们C#程序带到了Windows之外的平台,在工作之余花了很多时间在M ...

  2. UWP学习目录整理

    UWP学习目录整理 0x00 可以忽略的废话 10月6号靠着半听半猜和文字直播的补充看完了微软的秋季新品发布会,信仰充值成功,对UWP的开发十分感兴趣,打算后面找时间学习一下.谁想到学习的欲望越来越强 ...

  3. SQL Server 常用内置函数(built-in)持续整理

    本文用于收集在运维中经常使用的系统内置函数,持续整理中 一,常用Metadata函数 1,查看数据库的ID和Name db_id(‘DB Name’),db_name('DB ID') 2,查看对象的 ...

  4. kafka学习笔记:知识点整理

    一.为什么需要消息系统 1.解耦: 允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束. 2.冗余: 消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险. ...

  5. JAVA程序员常用软件整理下载

    ********为了大家学习方便,特意整理软件下载如下:*************Java类软件:-------------------------------JDK7.0:http://pan.ba ...

  6. js数组学习整理

    原文地址:js数组学习整理 常用的js数组操作方法及原理 1.声明数组的方式 var colors = new Array();//空的数组 var colors = new Array(3); // ...

  7. GJM : C#设计模式汇总整理——导航 【原创】

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  8. 整理下.net分布式系统架构的思路

    最近看到有部分招聘信息,要求应聘者说一下分布式系统架构的思路.今天早晨正好有些时间,我也把我们实际在.net方面网站架构的演化路线整理一下,只是我自己的一些想法,欢迎大家批评指正. 首先说明的是.ne ...

  9. 安卓GreenDao框架一些进阶用法整理

    大致分为以下几个方面: 一些查询指令整理 使用SQL语句进行特殊查询 检测表字段是否存在 数据库升级 数据库表字段赋初始值 一.查询指令整理 1.链式执行的指令 return mDaoSession. ...

随机推荐

  1. ftp 拉去远程文件脚本

    ftp 拉去远程文件脚本 cat ftp.sh #!/bin/bash ftp -i -n 192.168.1.1 << EOF user ftpadmin gaofeng binary ...

  2. JAVA类变量、类方法

    类变量(static) 类变量是该类的所有对象共享的变量,任何一个该类的对象去访问它时,取到的都是相同的值,同样任何一个该类的对象去修改它时,修改的也是同一个变量. public class C { ...

  3. AcWing1296. 聪明的燕姿

    聪明的燕姿 解题思路: 首先我们肯定要用到约数之和定理 但是有个问题就是要怎么用 根据经验得知,约数最多也就六七个左右,不然直接就超了s的范围.所以我们考虑用爆搜来做 但是用爆搜的话还是要优化一下思路 ...

  4. JS实现登录页密码的显示和隐藏功能

    在登录页经常会用到通过点击文本框的类似小眼睛图片来实现隐藏显示密码的功能,其实实现原理很简单,通过点击事件来改变input的type类型,具体过程看代码: 在没给大家分享实现代码之前,先给大家展示下效 ...

  5. P4072 [SDOI2016]征途

    斜率优化裸题 题意大概是:求 最小的 \(m^2s^2\) =\(m^2(\frac{1}{m}\sum_{i=1}^{m}(sum_i - {\frac{\sum_{i=1}^{m}sum_i}{m ...

  6. openlayers画区域

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  7. 报表平台发行说明(V0.0.0.1)

    开发周期:共20天(2019-11-04~2019-11-23) 发布日期:2019-11-23 主要功能说明: 1  整体功能技术选型,前端(html+CSS+javascript)+Web API ...

  8. win10中安装与配置maven

    原文链接:https://www.cnblogs.com/wkrbky/p/6350334.html Maven安装配置(Windows10) 想要安装 Apache Maven 在Windows 系 ...

  9. 检测到 LoaderLock Message: 正试图在 OS 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起。

    解决方法: 调试状态=>异常(Ctrl+Alt+E)=>Managed Debuggin Assistants=>LoaderLock 的选中状态去掉即可.

  10. golang channel 的一次内存错误

    起因 原因调查 原因分析 问题解决 总结 起因 今天在做数据库数据读取时, 首先通过多个 goroutine 将从数据库读取的数据写入 channel, 同时通过另一个 goroutine 从 cha ...