响应式ui

A quick recipe to creating an interactive remote notification banner UI in a React Native app, with animations and interactivity.

在React Native应用程序中创建具有动画和交互性的交互式远程通知横幅UI的快速方法。

Remote notifications are an essential part of many types of apps and their use-cases. They are the preferred way for systems to communicate time-sensitive information, from marketing to transactional purposes, to their users individually (using device tokens), a specified target group (using topics), or as a whole. To do this, React Native developers often turn to the ever-popular RNFirebase package by Invertase, which provides a wrapper around the native Firebase SDK for Android and iOS, and taking advantage of the Messaging module to listen to incoming remote messages sent from Firebase Cloud Messaging (FCM).

远程通知是许多类型的应用及其用例的重要组成部分。 它们是系统将时间敏感信息(从营销目的到交易目的)单独(使用设备令牌),指定的目标组(使用主题)或整体传达给用户的首选方式。 为此,React Native开发人员通常会使用Invertase广受欢迎的RNFirebase软件包,该软件包提供了适用于Android和iOS的本地Firebase SDK的包装,并利用Messaging模块来侦听从Firebase Cloud发送的传入远程消息。消息传递(FCM)。

为什么? (Why?)

One might wonder, why the need for a custom notification UI? Won’t remote notifications just automatically be displayed in the notification shade? Looking at the docs, apparently, notifications cannot be displayed while the app is in foreground (while the user is actively using the app) — see table below.

有人可能想知道,为什么需要自定义通知UI? 不会仅在通知阴影中自动显示远程通知? 查看文档,显然,当应用程序处于前台(用户正在积极使用该应用程序时)无法显示通知-参见下表。

here 在此处链接

Notifications will only be shown in the notification shade if the application state is in background or quit/terminated. Hence, some form of in-app UI is needed to display the notifications to the user as they are received.

仅当应用程序状态为后台或退出/终止时,通知才会显示在通知阴影中。 因此,需要某种形式的应用内UI来在收到通知时向用户显示通知。

我看起来怎么样? (How do I look?)

Looks easy, right?
看起来很简单,对吧?

As it is fully custom-made, the notification UI design and interactivity can be tailored to match the app’s overall look and feel. The following style is how I prefer to make it myself.

由于它是完全定制的,因此可以定制通知UI设计和交互性,以匹配应用程序的整体外观。 以下样式是我更喜欢自己制作的样式。

通知组件 (Notification component)

Creating a new standalone component to handle all in-app notification logic is key, since the UI would need to be able to be displayed in and interact with all parts of the app. It can then be attached to the root component (or somewhere close).

创建新的独立组件来处理所有应用程序内通知逻辑是关键,因为UI必须能够显示在应用程序的所有部分并与之交互。 然后可以将其附加到根组件(或靠近某处)。

import React, {FC} from 'react';
import NotificationCenter from './NotificationCenter';const App: FC = () => {return (<>...<NotificationCenter /></>);
}export default App;

Mind the TypeScript :)

注意TypeScript :)

基本使用者介面 (Basic UI)

Now, let’s make a basic design to display the notification title and body. Here I use TailwindRN to handle the styling (because why not). I honestly love using TailwindCSS on the web, and I’m grateful I can get a similar experience in React Native. If you haven’t tried it, I strongly suggest that you give it a shot.

现在,让我们进行基本设计以显示通知标题和正文。 在这里,我使用TailwindRN来处理样式(因为为什么不这样)。 老实说,我喜欢在Web上使用TailwindCSS ,也很高兴能在React Native中获得类似的体验。 如果您还没有尝试过,我强烈建议您试一试。

import {Text, TouchableOpacity, View} from 'react-native';
import React, {FC} from 'react';
import tailwind from 'tailwind-rn';const NotificationCenter: FC = () => {return (<><Viewstyle={tailwind('absolute bottom-0 z-10 inset-x-0 px-2 mb-2')}><TouchableOpacitystyle={tailwind('bg-gray-800 rounded')}onPress={() => {}}><View style={tailwind('py-3 px-4')}><Text style={tailwind('text-white mb-1')} numberOfLines={1}>Notification Title</Text><Text style={tailwind('text-white text-sm')} numberOfLines={2}>Notification body lorem ipsum dolor sit amet.</Text></View></TouchableOpacity></View></>);
}...

Now we’re getting somewhere.

现在我们到了某个地方。

In the example, the component basically displays a dark gray touchable banner, with white title and body text, inside an absolute-ly positioned container (in this case, anchored to the bottom of the screen). The banner uses a touchable component for it to be able to handle actions on presses (more on that later).

在此示例中,组件基本上在absolute放置的容器(在这种情况下,固定在屏幕底部)内显示深灰色可触摸的横幅,带有白色标题和正文。 标语使用可触摸的组件,以便能够处理印刷机上的操作(稍后会详细介绍)。

做个好听众 (Be a good listener)

Next, the component would need to listen (subscribe) to incoming remote messages and store it in state. To do that, it needs to create a listener on mount by invoking the onMessage method of the Messaging module. It also needs to make sure that the remote message is indeed a ‘notification’ (has a title and a body). Display the title and body inside the Text components made previously.

接下来,该组件将需要侦听(订阅)传入的远程消息并将其存储在状态中。 为此,它需要通过调用Messaging模块的onMessage方法在安装时创建侦听器。 它还需要确保远程消息确实是一个“通知”(具有标题和正文)。 在先前制作的“ Text组件中显示标题和正文。

import messaging, {FirebaseMessagingTypes,
} from '@react-native-firebase/messaging';
...
import React, {FC, useState, useEffect} from 'react';
...const NotificationCenter: FC = () => {const [message,setMessage,] = useState<null | FirebaseMessagingTypes.RemoteMessage>(null);useEffect(() => {const unsubscribe = messaging().onMessage((remoteMessage) => {if (remoteMessage.notification) {setMessage(remoteMessage);const timeoutHandler = setTimeout(() => {setMessage(null);}, 5000);return () => {setMessage(null);clearTimeout(timeoutHandler);};}});return () => {unsubscribe();};}, []);if (!message || !message.notification) {return null;}return (...<Text style={tailwind('text-white mb-1')} numberOfLines={1}>{message.notification.title}</Text><Text style={tailwind('text-white text-sm')} numberOfLines={2}>{message.notification.body}</Text>...);
}...

Go on, try it out! A message sent to the device should automatically display its content in the banner. It should also disappear by itself after 5 seconds.

继续尝试一下! 发送到设备的消息应自动在横幅中显示其内容。 5秒后它也应自行消失。

显示他们的动作! (Show ‘em your moves!)

Now comes the fun part — Animations! But don’t get too carried away, it’s just a notification banner and, at least for me, movement in the UI should be kept minimal and non-distracting. Adding subtle enter and exit transition animations to the component goes a little something like this.

现在来了有趣的部分-动画! 但是不要太着迷,它只是一个通知横幅,至少对我来说,应该将UI中的移动保持在最小限度且无干扰。 将微妙的输入和退出过渡动画添加到组件会有点像这样。

  1. Define a transition animation value, starting from 0. The value would then range from 300 (hidden) to 0 (shown), to be used as the container’s translateY value. Note: 300 is just a convenience value to skip measuring real banner height.

    定义一个transition动画值,从0开始。 然后,该值的范围从300 (隐藏)到0 (显示),用作容器的translateY值。 注意: 300只是方便的值,可跳过横幅的实际高度测量。

  2. Define the ‘exit’ transition animation, which should change the transition value from 0 to 300.

    定义“退出”过渡动画,该动画应将过渡值从0更改为300

  3. Define the ‘enter’ transition animation, which is like the ‘exit’ animation, but the other way around.定义“输入”过渡动画,类似于“退出”动画,但反之亦然。
  4. Fire the ‘enter’ animation when a new remote message comes in.收到新的远程消息时,触发“输入”动画。
  5. Fire the ‘exit’ animation 5 seconds the message came in (modify the flow in the previous step slightly).触发消息“退出”动画5秒钟(稍微修改上一步中的流程)。
  6. Change the container View component to an Animated.View component, and set its translateY value from the transition animation value.

    将容器的View组件更改为Animated.View组件,然后从transition动画值设置其translateY值。

import {Animated, Easing, Text, TouchableOpacity, View} from 'react-native';
import messaging, {FirebaseMessagingTypes,
} from '@react-native-firebase/messaging';
import React, {FC, useEffect, useRef, useState} from 'react';const NotificationCenter: FC<Props> = () => {...const transition = useRef<Animated.Value>(new Animated.Value(300)).current;const exitAnim = useRef(Animated.timing(transition, {duration: 500,easing: Easing.in(Easing.exp),toValue: 300,useNativeDriver: true,}),).current;useEffect(() => {const unsubscribe = messaging().onMessage((remoteMessage) => {if (remoteMessage.notification) {transition.setValue(300);const enterAnim = Animated.spring(transition, {toValue: 0,useNativeDriver: true,});setMessage(remoteMessage);enterAnim.start();const timeoutHandler = setTimeout(() => {exitAnim.start(() => {setMessage(null);});}, 5000);...}}...}, [transition, exitAnim]);return (<><Animated.Viewstyle={[tailwind('absolute bottom-0 z-10 inset-x-0 px-2 mb-2'),{transform: [{translateY: transition}]},]}>...</Animated.View></>);
}...

Sick moves! Looks pretty, huh? More importantly, it limits itself to only adding a sense of interactivity and natural movement, by not being too distracting or flashy.

生病的举动! 看起来不错吧? 更重要的是,它不会因过于分散注意力或浮华而使自己仅限于增加互动感和自然运动感。

放开 (Out of the way!)

Another basic feature of notifications we often see is its ability to be dismissed. On the Android notification shade, this is usually done by swiping left or right. Let’s see what we can do with React Native on this front.

我们经常看到的通知的另一个基本特征是其被驳回的能力。 在Android通知栏上,通常是通过向左或向右滑动来完成的。 让我们看看在这方面如何使用React Native。

React Native provides an easy way to handle gestures on a component using its PanResponder API. To handle swipes, the component’s pan handlers would need to respond to horizontal movement and translate it into the container’s translateX value. That movement value can also be interpolated to an opacity value to give it a ‘fading’ effect as it is being dismissed. In sequence, it goes something like this.

React Native提供了一种使用其PanResponder API处理组件上手势的简便方法。 要处理滑动,组件的平移处理程序将需要响应水平移动并将其转换为容器的translateX值。 该运动值也可以插值到不透明度值,以使其在被消除时具有“褪色”效果。 按顺序,它是这样的。

  1. Define a swipe animation value. This value would map to the pan responder’s horizontal movement.

    定义swipe动画值。 该值将映射到声像响应器的水平运动。

  2. Define a resetSwipe animation, to reset the container to its original position if the horizontal movement is not fast enough to qualify as a dismiss action.

    定义一个resetSwipe动画,如果水平移动的速度不够快而无法resetSwipe ,则将容器重置到其原始位置。

  3. Define left and right swipeOut animations, to completely move the container out of the screen if the horizontal movement qualifies as a dismiss action.

    定义左右swipeOut动画,以将容器完全移出屏幕(如果水平移动符合swipeOut动作的资格)。

  4. Define a panResponder to attach to the touchable component and handle gestures acted upon it. Map the onPanResponderMove event’s dx (horizontal movement) to the swipe animation value.

    定义panResponder以附加到可触摸组件并处理在其上执行的手势。 将onPanResponderMove事件的dx (水平移动)映射到swipe动画值。

  5. Attach the panResponder's panHandlers to the touchable component.

    panResponderpanHandlers到可触摸组件。

  6. Add a translateX value to the container component to react to the swipe animation value.

    translateX值添加到容器组件以对swipe动画值做出React。

  7. Define an opacity value as an interpolation from the swipe animation value.

    opacity值定义为swipe动画值的插值。

  8. Add the opacity value to the container component.

    opacity值添加到容器组件。

import {Animated, Dimensions, Easing, PanResponder, Text, View} from 'react-native';
import React, {FC, useState, useEffect, useRef} from 'react';
import tailwind from 'tailwind-rn';const NotificationCenter: FC = () => {...const swipe = useRef(new Animated.Value(0)).current;const resetSwipe = useRef(Animated.timing(swipe, {duration: 200,toValue: 0,easing: Easing.out(Easing.exp),useNativeDriver: true,}),).current;const swipeOutLeft = useRef(Animated.timing(swipe, {duration: 50,toValue: Dimensions.get('screen').width * -1,useNativeDriver: true,}),).current;const swipeOutRight = useRef(Animated.timing(swipe, {duration: 50,toValue: Dimensions.get('screen').width,useNativeDriver: true,}),).current;const opacity = swipe.interpolate({inputRange: [Dimensions.get('screen').width * -1,0,Dimensions.get('screen').width,],outputRange: [0, 1, 0],});const panResponder = useRef(PanResponder.create({onStartShouldSetPanResponder: () => false,onMoveShouldSetPanResponder: () => true,onPanResponderMove: Animated.event([null, {dx: swipe}], {useNativeDriver: false,}),onPanResponderRelease: (e, gs) => {if (gs.vx > 0.5) {swipeOutRight.start(() => {setMessage(null);});} else if (gs.vx < 0.5) {swipeOutLeft.start(() => {setMessage(null);});} else {resetSwipe.start();}},}),).current;useEffect(() => {const unsubscribe = messaging().onMessage((remoteMessage) => {if (remoteMessage.notification) {...swipe.setValue(0);...}}...}return (<><Animated.Viewstyle={[tailwind('absolute bottom-0 z-10 inset-x-0 px-2 mb-2'),{transform: [{translateY: transition}, {translateX: swipe}], opacity},]}><TouchableOpacity{...panResponder.panHandlers}style={tailwind('bg-gray-800')}onPress={() => {exitAnim.start();}}><View style={tailwind('py-3 px-4')}><Text style={tailwind('text-white mb-1')} numberOfLines={1}>{message.notification.title}</Text><Text style={tailwind('text-white text-sm')} numberOfLines={2}>{message.notification.body}</Text></View></TouchableOpacity></Animated.View></>);
};...

Now, by swiping left or right fast enough, we can set the notification aside and out of the way. Neat!

现在,通过以足够快的速度向左或向右滑动,我们可以将通知搁置一旁,并且不打扰。 整齐!

And just like that, the app now has the ability to display (with animation) and dismiss in-app remote notifications. What a time to be alive.

就像这样,该应用程序现在可以显示(带有动画)和关闭应用程序内远程通知。 多么活着的时间。

Another great thing about remote messages is that they can contain data (other than title and body), that we can get and use in the app. A couple of common use-cases are:

远程消息的另一个优点是它们可以包含数据(标题和正文除外),我们可以在应用程序中获取和使用这些数据。 几个常见的用例是:

  1. Setting a route/deeplink URL for the app to navigate to when the user presses the notification. This can be achieved in conjunction with React Navigation — stay tuned for an article on this!

    设置应用程序的路由/深层链接URL,以在用户按下通知时导航到该URL。 这可以与React Navigation结合实现-请继续关注此文章!

  2. Setting a specified key to refresh/revalidate data from server. This can be done in conjunction with SWR — also, stay tuned for this!

    设置指定的密钥以刷新/重新验证服务器中的数据。 这可以与SWR一起完成-敬请期待!

Also check out how to make another commonly used mobile app UI, the bottom swipeable modal, in React Native.

还请查看如何在React Native中制作另一个常用的移动应用UI,即底部可滑动模式 。

It’s amazing how React Native with Firebase can enable more and more developers to easily create and ship quality apps in such a short time. I hope this recipe of an article can do a bit of good to everyone taking the time to read. As always, thank you for reading, it means the world to me. Please do leave responses if you like. I would always love to connect to new people, whoever you are. Find me at endyhardy.co for more info.

具有Firebase的React Native如何使越来越多的开发人员能够在如此短的时间内轻松创建和交付高质量的应用程序,真是令人惊讶。 我希望这篇文章的食谱对每个花时间阅读的人都有好处。 与往常一样,感谢您的阅读,对我而言,这意味着世界。 如果您愿意,请留下答复。 无论您是谁,我总是很想结识新朋友。 在endyhardy.co上找到我以获取更多信息。

Have a great day, stay safe, wear your mask, wash your hands, and keep on creating!

祝您有美好的一天,保持安全,戴好口罩,洗手,继续创新!

翻译自: https://levelup.gitconnected.com/react-native-in-app-remote-notification-ui-8e367fcbe96b

响应式ui


http://www.taodudu.cc/news/show-5850586.html

相关文章:

  • 布局检测与优化(一):布局层级优化
  • Windows 11 的开始菜单都要加广告了?网友:微软你清醒一点!
  • 计算机系运动会横幅怎么写,运动会标语横幅条幅
  • 计算机系运动会横幅怎么写,运动会横幅标语(精选50条)
  • 计算机系运动会横幅怎么写,运动会横幅标语大全
  • js深度冻结一个对象
  • 通过 20 个棘手的ES6面试问题来提高咱们的 JS 技能
  • NodeJS 引入 highlight 报错: Error: Cannot find module ‘./highlight.js‘
  • Deepin20Beta启用网卡远程开机/唤醒功能Wake-on-LAN(WOL)并保持开启状态
  • javascript 链式调用实现原理
  • jsrpc-http接口远程调用js代码
  • (附源码)Springboot + vue远程心电诊断系统 毕业设计091759
  • 李宁网易体育-网易网站
  • win10计算机用户密码,win10台式电脑怎么设置开机密码
  • 腾讯云主机及CentOS7.2简单上手体验
  • 一台计算机的配置,怎么配置一台台式计算机?答案按需求来配
  • 最通俗易懂的多线程面试60题
  • 简单易懂云计算(转自天涯感谢原楼主iamsatisfied)
  • 惠普电脑怎么录屏?图文教学,3种简单易懂的录屏方法
  • 台式计算机软件安装的完整过程,台式电脑怎么自己动手组装 史上最全的组装电脑详细图文教程...
  • ChatGPT技术基石之Transformer技术的简介(简单易懂)
  • GitHub:利用GitHub Desktop实现笔记本与台式机的简单协同开发
  • sscanf函数 linux 物理cpu信息,计算机操作系统实验课程教案2016.doc
  • 2006信息技术会考复习(理论复习)
  • Windows 7 使用随笔
  • 安卓SDK——语音识别
  • 转:使用Java RTP传输声音和视频的程序(绝对经典)
  • lua中自定义加载lua的path
  • Lua 表的遍历
  • nginx使用lua实战

响应式ui_在应用程序远程通知ui中响应本机相关推荐

  1. HTML5响应式企业集团织梦模板,(自适应手机版)响应式企业集团通用类网站织梦模板 HTML5响应式大气通用企业织梦源码+PC+wap+利于SEO优化...

    名称:(自适应手机版)响应式企业集团通用类网站织梦模板 HTML5响应式大气通用企业织梦源码+PC+wap+利于SEO优化 该模板是非常容易存活的,这样的网站很容易吸引访客点击,提升ip流量和pv是非 ...

  2. vueweb端响应式布局_移动端和pc端,响应式设计布局

    1.什么是响应式 Web 设计? 响应式 Web 设计让你的网页能在所有设备上有好显示. 响应式 Web 设计只使用 HTML 和 CSS. 响应式 Web 设计不是一个程序或Javascript脚本 ...

  3. 响应式滚动图懒加载 element ui el-carousel 组件优化代码

    响应式滚动图懒加载 element ui  el-carousel 组件优化代码 懒加载插件vue-lazyload //main.js import VueLazyload from 'vue-la ...

  4. vue 响应式ui_如何在Vue.js中设置响应式UI搜索

    vue 响应式ui Are you thinking of building something awesome with one of the popular modern frameworks o ...

  5. 【响应式编程的思维艺术】 (2)响应式Vs面向对象

    [摘要]本文是Rxjs 响应式编程-第一章:响应式这篇文章的学习笔记. 示例代码托管在:http://www.github.com/dashnowords/blogs 一. 划重点 三句非常重要的话: ...

  6. 响应式html5框架,15个最好的HTML5前端响应式框架(2014)

    注1* 之前我们比较过Foundation和Bootstrap, 这篇文章更加系统地介绍了目前比较浏览的前端响应式框架. 注2* 文中的多个框架基于SASS创建,SCSS是一种比LESS更简洁的样式表 ...

  7. java响应式编程有几种方式_什么是响应式编程,Java 如何实现

    什么是响应式编程,Java 如何实现 我们这里用通过唯一 id 获取知乎的某个回答作为例子,首先我们先明确下,一次HTTP请求到服务器上处理完之后,将响应写回这次请求的连接,就是完成这次请求了,如下: ...

  8. 《响应式Web设计性能优化》一1.1 响应式设计存在的问题

    本节书摘来异步社区<响应式Web设计性能优化>一书中的第2章,第2.1节,作者: [美]Tom Barker 译者: 余绍亮 , 丁一 , 叶磊 责编: 赵轩,更多章节内容可以访问云栖社区 ...

  9. css响应式布局_用 CSS Grid 布局制作一个响应式柱状图

    最新一段时间比较喜欢玩弄图表,出于好奇,我想找出比较好的用 CSS 制作图表的方案.开始学习网上开源图表库,它对我学习新的和不熟悉的前端技术很有帮助,比如这个:CSS Grid. 今天和大家分享我学到 ...

最新文章

  1. Xilinx FPGA全局介绍
  2. 基因 ID 匹配利器
  3. Yelp研发实践:使用服务拆分单块应用
  4. java布尔类型比较器_Java 8比较器类型推论非常困惑
  5. Nginx 中 last、break、permanent、redirect
  6. SAP和CRM相关的标准教材,学通了这些,就算是CRM专家了
  7. 深圳学校积分计算机,深圳小学入学积分多少才够
  8. PS去除图片白底制作微信表情包
  9. php7.4中让gd库支持jpeg格式
  10. eds能谱图分析实例_电子产品质量的提升,离不开这些失效分析!
  11. iphone 文件夹连接服务器 百度云,iPhone与电脑共享文件夹
  12. Filco圣手二代键盘蓝牙连接方法
  13. @RequestParam使用
  14. Linux——缺少ld-linux.so.2,lbiz.so.1库文件
  15. minus subtract deduct这三个单词的区别
  16. Rust包管理 Crate
  17. EXCEL中小数点后面的0怎么去掉
  18. Python2.7字符编码详解
  19. ccsa安学网小程序_CCSA安学网安全题库
  20. 腾讯 Tars 开源 Go 版本 Tars-Go,并发性能比 gRPC 高 5 倍

热门文章

  1. springboot继承组件_springboot 的组件集成
  2. BBR源码-tcp-bbr.c
  3. 神州数码易拓TIPTOP ERP全局大小写
  4. Android_异步加载1
  5. C语言float转char数组
  6. 等待ajax完成再执行相应操作
  7. 无线充发光鼠标垫RGB LED照明无线充电鼠标垫
  8. 985高校明确不再为全部研究生提供宿舍!读研费用又要增加了吗?
  9. SpringBoot整合Hikari
  10. Webpack HMR 原理解析