知识点:开发一个分享组件。

这节开始介绍怎样自定义我们自己的组件。

分享组件

我们单击分享的时候需要弹出一个单独的层,并且这一层里有几个可配置的显示的分享内容和渠道。

这里利用 Modal 组件来实现,Modal 是一个单独的弹出,默认就遮盖在原有界面的上面,利用这点我们可以非常方便的做出一个遮罩。

在 component 下创建一个新文件ShareView.js,使用一个完整的 view 来做背景,这样不管点击哪儿都可以关闭,使用 Animated 组件则是要自定义动画,Modal 自带的动画实现不了我们需要的效果。

render() {return <ModalonRequestClose={() => { }}animationType="none"transparent={true}visible={this.state.isShow}><TouchableWithoutFeedback onPress={() => this.cancel()}><View style={styles.bg} ></View></TouchableWithoutFeedback><Animated.View>{/*具体的内容*/}</Animated.View></Modal>}

这里把几个分享小图标对应的方法名等放在后面,添加分享组件的时候加入这些属性,在初始化的时候就直接固定好了分享可以使用的姿势。这里配置了可使用的分享展示用图片名称以及点击事件使用的方法,具体的实现放在分享内部。

/*** 分享层显示的类型*/
exports.SHARETYPE = {/*** 微信*/WEIXIN: {method: "weiFriend", url: require('../images/icon-weixin'), txt: '微信好友'},/*** 微信朋友圈*/PENGYOUQUAN: {method: 'weiPyq', url: require('../images/icon-wei'), txt: '朋友圈'},/*** 连接地址*/LIANJIE: {method: 'weiLink', url: require('../images/icon-share-link'), txt: '链接'},/*** 二维码*/ERWEIMA: {method: 'weiCode', url: require('../images/icon-share-code'), txt: '二维码'}
}

使用 types 传入到组件里,通过循环传入的类型渲染好最终的页面。

this.list = this.renderType(this.props.types)
renderType(types) {let list = [];if (types) {types.forEach((item,index) => {list.push(<TouchableOpacity key={index}style={styles.shareBtn}onPress={this[item.method].bind(this)}activeOpacity={0.9}><Image source={{ uri: item.url }}resizeMode='cover'style={{ width: px(96), height: px(96) }} /><Text style={styles.shareTxt} allowFontScaling={false}>{item.txt}</Text></TouchableOpacity>)})}return list;}
<ShareModal types={[SHARETYPE.WEIXIN,SHARETYPE.PENGYOUQUAN,SHARETYPE.LIANJIE,SHARETYPE.ERWEIMA]} />

把上面用到的几个方法也实现一次,这里可以先留空,等接入微信之后再真正的实现。

 //链接暂存变量link = ''//实现微信分享给朋友weiFriend() { }//实现转发朋友圈weiPyq() { }//实现复制链接weiLink() {Clipboard.setString(this.link)toast('链接复制成功')}//实现展示二维码weiCode() { }

最后再加上一个主动打开分享的方法,给使用到的时候可以调用就可以了。

//打开分享层open(){if(!this.state.isShow){this.setState({ isShow: true })}}

添加动画

这里简单的给分享组件添加一个动画,在单击按钮之后分享组件会从下面弹出来,点击取消之后又会往下移动出屏幕。

首先要改造 boxY,让这个变量支持 RN 的动画,这里使用 height 这个固定值来设置分享层从下面出来的位置。

constructor(props) {super(props)this.height=px(500)this.state = {isShow: false,//默认不显示弹层boxY: new Animated.Value(this.height),}this.list = this.renderType(this.props.types)}

改造 Modal,在 Modal 显示的时候执行动画事件。

<Modal style={styles.view}onRequestClose={() => { }}onShow={() => this.show()}animationType="none"transparent={true}visible={this.state.isShow}>

RN 提供了几种使用动画的方式,这里使用基于时间轴的动画 timing。第一个参数是我们的位置变量,第二个是动画配置,这里将动画的最终结果设为 0,动画时间设的小一些,让动画显示的快一点。

//打开的动画
show() {if (this.state.isShow) {Animated.timing(this.state.boxY,{toValue: 0,duration: 200}).start();}
}

这里我突然学会了制作 Gif。

当然,打开的动画有了,关闭的动画也要有,不然你会发现动画只有一次显示的机会,这里注意不要先关闭再动画,关闭之后 UI 就销毁了,动画也就执行不了了。

   //关闭弹层cancel() {Animated.timing(this.state.boxY,{toValue: this.height,duration: 200}).start(() => {this.setState({isShow: false})});}

弹出层组件

App 内部会有很多地方用到弹出层,简单的比如一个 alert 形式的,复杂一点会有一些自定义的 UI 的,这里我们就做一个简单的弹出层组件。

在 component 下面创建一个 ModalView.js 文件,添加一个 Modal 层,后面的所有样式都放在这个 Modal 里面,由于要面对复杂的情况,所以这里设置了标题、内容、自定义组件配置这三方面的配置。

/*** alert提示* @param {*} opt.title 标题* @param {*} opt.content<array> 内容* @param {*} opt.btns<array> 按钮组* @param {*} opt.btns.txt 按钮标题* @param {*} opt.btns.click 按钮点击事件*/
exports.DialogModal = class extends React.Component {constructor(props) {super(props)this.enabledExit = this.props.enabledExit;this.state = {show: false,opt: { title: "", content: [], btns: [] }}}render() {let opt = this.state.opt;return <Modalvisible={this.state.show}onShow={() => { }}onRequestClose={() => { }}animationType="none"transparent={true}></Modal>}
}

配置里面必须传 content 数组,其他为默认选项,可以不传,这里推荐把参数重载成几个适合的方法。

//弹框参数open(opt) {if (!opt || !opt.content) return logWarm("alert没有传入内容参数");if (!opt.btns || opt.btns.length === 0) {opt.btns = [{ txt: "确定", click: () => { } }]}if (opt.btns.length == 1) {opt.btns[0].color = "#d0648f";}if (opt.btns.length == 2) {opt.btns[1].color = "#d0648f";}this.setState({show: true, opt})}

比如,重载为一个友好的参数类型的方法:

//重载参数_alert(title, content, success, cancel) {let opt = {title, content,btns: []}if (success) opt.btns.push(success)if (cancel) opt.btns.push(cancel)this.open(opt);}

甚至可以将所有参数设置的更随意一些,默认参数和默认类型都可以随意填写。

/*** alert提示* @param {*} title 标题* @param {*} content<array> 内容* @param {*} success<array> 成功* @param {*} cancel<array> 取消* @param {*} success.txt 按钮标题* @param {*} success.click 按钮点击事件* 重载,(content<string|array>)* 重载,(title<string>,content<string|array>)* 重载,(title<string>,content<string|array>,success<string|object>)* 重载,(title<string>,content<string|array>,success<string|object>,cancel<string|object>)*/alert(title, content, success, cancel) {if (!title) {title = null}if (title && !content) {const tmp = content;content = title;title = tmp;}if (typeof content === "string") content = [content]if (typeof success === "string") success = { txt: success }if (typeof cancel === "string") success = { txt: cancel }this._alert(title, content, success, cancel)}

最后我们看看实际效果,弹出的这个样式就是 App 中最常用的状态,比如结果提示、删除确认、支付确认、升级提示等。

this.refs.dialog.alert("标题","测试内容","取消","确定");

查看大图弹层

商品详情页的图片比较多,如果配置了大图的话最好能让用户更清晰的查看大图,同时也要可以下载下来。

在 component/ModalView.js 里面添加看大图的组件。

/*** 查看大图的弹层* props list 图片列表*/
exports.ImgsModal = class extends React.Component {//滚动scroll = null//当前图片地址currentSrc = ''//最大高度maxH = deviceHeight * 0.95;constructor(props) {super(props);this.height = px(240)this.state = {showModal: false,boxY: new Animated.Value(this.height),current: 1,//当前位置};}render() {return <Modalvisible={this.state.showModal}onShow={() => { }}onRequestClose={() => { }}animationType="none"transparent={true}></Modal>}
}

在商品详情页将所有图片都加入到一个图片数组中,然后引用大图组件并传入图片数组。

{/*大图弹层*/}
<ImgsModal list={this.state.list}/>

给需要看大图并且已经加入到 imgs 变量中图片添加点击事件:

onPress={()=>this.openBigImg(img.image)}

点击的时候调用大图组件的打开方法,传入当前点击的图片字符串,打开之前会根据这个字符串找到图片的位置并设置那个位置的图片展示出来。

openBigImg(key){this.refs.imgsModal.Open(key);
}

这里主要使用了 scrollView 组件,将要显示的图片放在里面横向排列,左滑与右滑的方法已经天然自带了,我们只需要将图片显示隐藏,长按弹出保存按钮的几个东西实现即可。

<View style={imgsStyles.imgBox}><ScrollView ref='scroll'contentContainerStyle={[{ height: deviceHeight }, base.line]}keyboardDismissMode='on-drag'onScroll={() => this.cancel()}onMomentumScrollEnd={(e) => {this.setPage(e.nativeEvent.contentOffset)}}pagingEnabled={true}showsHorizontalScrollIndicator={false}showsVerticalScrollIndicator={false}directionalLockEnabled={true}scrollEventThrottle={0.5}horizontal={true}>{this.props.list.map((item, index) => <TouchableWithoutFeedback key={index}delayLongPress={1400}onLongPress={() => this.pop(item.image)}onPress={() => this.close()}><View style={[imgsStyles.imgItem, base.line]}>{this.resizeImg(item)}</View></TouchableWithoutFeedback>)}</ScrollView></View>

Git 上的代码比较全,这里就不展示了,感兴趣的读者可以在自己实现一遍,也可以在这个的基础上再加入更复杂的放大、缩小动画。

第07课:添加自定义组件相关推荐

  1. 太空射击 第07课: 添加图形

    太空射击 第07课: 添加图形 在本课中,我们将讨论如何在游戏中使用预先绘制的图形. 视频 在这里可以观看本教程的视频 选择图形 我们谈到了 Opengameart.org,这是免费游戏艺术的重要来源 ...

  2. 学习python,北京尚学堂,第07课到第30课的个人的总结

    在学习了那几节课以后,又找了一个新的视频,北京尚学堂的百战程序员,感觉还挺全 链接:https://pan.baidu.com/s/12HT1UCkK9SHadn8zESZRFA  提取码:zc7l ...

  3. QGC添加自定义组件和发送自定义MAVLINK消息

    QGC添加自定义组件和发送自定义MAVLINK消息 一.添加自定义组件 1.1 在飞行界面添加组件 1.2 实现组件事件 1.3 在MOCK模拟链接中实现验证 1.4 验证 二.自定义MAVLINK消 ...

  4. 【个人笔记】OpenCV4 C++ 图像处理与视频分析 07课

    个人资料,仅供学习使用 修改时间--2022年2月13日 09:51:04 学习课程:OpenCV4 图像处理与视频分析实战教程 课程讲师:贾志刚 07 图形绘制与填充+文字绘制+随机绘制+矩形ROI ...

  5. 运维36讲第07课:基于 Django_crontab、Xadmin 做一套定时任务管理系统

    本课时介绍一个定时任务系统 Jcrontab,它用 Python3研发,并用到 Django_crontab 和 Xadmin 等模块. 我们知道在 Linux 环境下,crontab 是一个周期性的 ...

  6. 第05课:组件测试详解

    本课程中所说的组件(Component),是指一个大型系统中,某一个可以独立工作的.封装完整的组成部分.在微服务架构中,组件实际上就代表着微服务本身,或者说单个微服务.以下将其称为"单服务测 ...

  7. 第07课:【实战】调试Redis准备工作

    7.1 Redis源码下载与编译 Redis源码下载与编译在前面已经说过了,同学们可以去第04课:GDB常用命令详解(上)学习. 编译成功后,会在src目录下生成多个可执行程序,其中redis-ser ...

  8. SpringCloud微服务(07):Zipkin组件,实现请求链路追踪

    一.链路追踪简介 1.Sleuth组件简介 Sleuth是SpringCloud微服务系统中的一个组件,实现了链路追踪解决方案.可以定位一个请求到底请求了哪些具体的服务.在复杂的微服务系统中,如果请求 ...

  9. 微服务get请求条用_SpringCloud微服务(07):Zipkin组件,实现请求链路追踪

    一.链路追踪简介 1.Sleuth组件简介 Sleuth是SpringCloud微服务系统中的一个组件,实现了链路追踪解决方案.可以定位一个请求到底请求了哪些具体的服务.在复杂的微服务系统中,如果请求 ...

最新文章

  1. python基础语法有哪些-Python基础语法知识有哪些?
  2. 三天打鱼,两天晒网。
  3. 如何为我们的应用程序提供一个更小、更快的视频通话库
  4. CSS3-文本-text-shadow
  5. 触摸事件touchevent
  6. eclipse添加或者绑定约束文件
  7. JAVA连接SQL server
  8. openstack排错
  9. WPS如何对文档加密,忘记密码又如何解密?
  10. 永中Office—公文的数据集成(转)
  11. 我的Java学习历程03【Java8接口新特性-下】
  12. HTML5+CSS3从入门到精通随书光盘 ISO 镜像视频教程​
  13. 汽车洒水器的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告
  14. 计算机信函 教案模板,一年级信息技术课教案模板三篇
  15. AEG 2A 400-280 HFRL1
  16. Linux 安装rabbitmq
  17. JSP危险化学品管理系统myeclipse开发mysql数据库bs框架java编程jdbc详细设计
  18. 虹科分享 | 基于流的流量分类的工作原理 | 网络流量监控
  19. 部署Kubernetes集群+Dashboard可视化页面-1.18.6版本
  20. c++ opengl 三维图形中显示文字_为什么使用GPU渲染图形图像,而不使用CPU呢?

热门文章

  1. 微信小程序组件生命周期和页面生命周期
  2. Oracle-RAC集群网络,IO性能测试
  3. 前端大牛贺师俊与 360 劳动纠纷引前端圈巨震,技术人维权有多难?
  4. H5页面唤醒App及App之间跳转
  5. 【ABAPFI】使用BAPI进行会计凭证过帐的Tips
  6. 华为鸿蒙智能系统域名,华为,上鸿蒙
  7. windows 任务管理器实现拨号断网自动重连
  8. 基础数学:基本初等函数
  9. 公司sns JSSDK组件列表-20131011
  10. 基于FPGA的通信显示系统设计