热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ReactNative实现城市选择列表

引言使用RN开发了一段时间,最近遇到了一个比较棘手的问题,就是用react写个城市选择列表,当然这个如果用Android原生来写,网上的例子数不胜数,随便就能找到,但是react却

引言

使用RN开发了一段时间,最近遇到了一个比较棘手的问题,就是用react写个城市选择列表,当然这个如果用Android原生来写,网上的例子数不胜数,随便就能找到,但是react却很少,也没有一个和我这个需求相匹配的,所以就只能自己动手撸一个出来咯.

效果

这个城市列表和其他的有点区别

1,有当前定位城市 2,有热门城市 3,每个子项是一个类似GridView的效果,而不是ListView 实现的效果图如下:

实现步骤

  • 首先需要一个city.json的json文件 例:

{"key": "A","data": [{"citys": [{"city": "阿拉善盟","id": 152900},{"city": "鞍山","id": 210300},{"city": "安庆","id": 340800},{"city": "安阳","id": 410500},.....]}

  • 整个列表采用sectionList SectionList提供了粘性的header,设置为true即可stickySectionHeadersEnabled=true,这样在滚动的时候就有实现了粘性效果;

代码如下:

"sectionList"renderSectionHeader={this.renderSectionHeader}renderItem={this.renderItem}stickySectionHeadersEnabled={true}showsHorizontalScrollIndicator={false}sections={this.state.sections}keyExtractor={this._extraUniqueKey}/>

  • 右边采用ScrollView来实现,最开始采用View,发现会有事件抢夺问题,具体的原因不祥,毕竟我对RN的事件传递也不是特别熟 代码如下:

/*右侧索引*/sectionItemView() {const sectionItem = this.state.sections.map((item, index) => {if (index === 0) {return null}return {item.key}});return ("sectionItemView"onStartShouldSetResponder={() => true} onMoveShouldSetResponder={() => true}onResponderTerminationRequest={() => true}onResponderGrant={this.responderGrant}onResponderMove={this.responderMove} onResponderRelease={this.responderRelease}>{sectionItem});}

这里的几个方法需要具体说明一下(React Native手势响应,就和android的onTouchEvent一个意思): 通过实施正确的处理方法,视图可以成为接触响应器。有两种方法来询问视图是否想成为响应器:

  • View.props.onStartShouldSetResponder: (evt) => true,——这个视图是否在触摸开始时想成为响应器?
  • View.props.onMoveShouldSetResponder: (evt) => true,——当视图不是响应器时,该指令被在视图上移动的触摸调用:这个视图想“声明”触摸响应吗? 如果视图返回 true 并且想成为响应器,那么下述的情况之一就会发生:
  • View.props.onResponderGrant:(evt)= > { } ——视图现在正在响应触摸事件。这个时候要高亮标明并显示给用户正在发生的事情。
  • View.props.onResponderReject:(evt)= > { }——当前有其他的东西成为响应器并且没有释放它。 如果视图正在响应,那么可以调用以下处理程序:
  • View.props.onResponderMove:(evt)= > { }——用户正移动他们的手指
  • View.props.onResponderRelease:(evt)= > { }——在触摸最后被引发,即“touchUp”
  • View.props.onResponderTerminationRequest:(evt)= >true——其他的东西想成为响应器。这种视图应该释放应答吗?返回 true 就是允许释放

事件处理:

/*用户手指开始触摸*/responderGrant(event) {this.scrollSectionList(event);this.setState({isTouchDown: true,})}/*用户手指在屏幕上移动手指&#xff0c;没有停下也没有离开*/responderMove(event) {console.log("responderMove")this.scrollSectionList(event);this.setState({isTouchDown: true,})}/*用户手指离开屏幕*/responderRelease(event) {console.log("onTouchUp")this.setState({isTouchDown: false,})}/*手指滑动&#xff0c;触发事件*/scrollSectionList(event) {const touch &#61; event.nativeEvent.touches[0];// 手指滑动范围 从 A-Q 范围从50 到 50 &#43; sectionItemHeight * cities.lengthif (touch.pageY >&#61; sectionTopBottomHeight&#43;headerHeight&#43;statusHeight&& touch.pageY <&#61; statusHeight &#43;headerHeight&#43;sectionTopBottomHeight &#43; sectionItemHeight * 25&& touch.pageX >&#61; width - sectionWidth&& touch.pageX <&#61; width) {console.log("touchx" &#43; touch.pageX &#43; &#39;.&#61;&#61;&#61;&#61;&#61;&#61;&#61;touchY&#39; &#43; touch.pageY)const index &#61; (touch.pageY - sectionTopBottomHeight - headerHeight) / sectionItemHeight;console.log("index" &#43; index);if (Math.round(index)>&#61;0&&Math.round(index)<&#61;25){this.setState({selectText: this.state.sections[Math.round(index)].key})//默认跳转到 第 index 个section 的第 1 个 itemthis.refs.sectionList.scrollToLocation({animated: true,sectionIndex: Math.round(index),itemIndex: 0,viewOffset: headerHeight});}}}

这里根据手指在右边索引栏的滑动事件,获取到当前的x轴和y轴的具体值,然后计算出具体的子项目的标题,让SectionList滚动到具体的index位置;

  • 子项目列表采用FlatList实现GridView的效果

false}numColumns&#61;{4}showsHorizontalScrollIndicator&#61;{false}renderItem&#61;{({item}) &#61;> this._createItem(item)}keyExtractor&#61;{this._extraUniqueKey2}/>

这样基本大体的效果就实现了

最后

React native实现这个有个很坑爹的地方,就是渲染列表会花费很长的时间,Android是这样,ios没试过,所以如果没有渲染完就去滑动索引栏会报这个scrolltoindex-should-be-used-in-conjunction-with-getitemlayout-or-on异常,网上找了很多资料,说是SectionList没有渲染完就调用scrollToLocation,如果要在没有渲染完之前调用scrollToLocation需要配合getitemlayout使用,但是这个getitemlayout又需要传入具体item的高度,然而我的FlatList的高度是不确定的,所以就很坑爹了,找不到办法解决,只能延时加载右边索引栏; 代码如下:

componentDidMount() {setTimeout(() &#61;> {this.setState({canTouch: true})}, 1600)}

这样全部基本就完成了 项目地址: github.com/mouxuefei/R…

转:https://juejin.im/post/5d0854d651882533e13372c8



推荐阅读
  • 欢乐的票圈重构之旅——RecyclerView的头尾布局增加
    项目重构的Git地址:https:github.comrazerdpFriendCircletreemain-dev项目同步更新的文集:http:www.jianshu.comno ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文介绍了响应式页面的概念和实现方式,包括针对不同终端制作特定页面和制作一个页面适应不同终端的显示。分析了两种实现方式的优缺点,提出了选择方案的建议。同时,对于响应式页面的需求和背景进行了讨论,解释了为什么需要响应式页面。 ... [详细]
  • android 触屏处理流程,android触摸事件处理流程 ? FOOKWOOD「建议收藏」
    android触屏处理流程,android触摸事件处理流程?FOOKWOOD「建议收藏」最近在工作中,经常需要处理触摸事件,但是有时候会出现一些奇怪的bug,比如有时候会检测不到A ... [详细]
  • macOS命令行创建Android模拟器
    macOS下不安装AndroidStudio使用VSCode来开发Flutter应用使用命令行创建和管理Android模拟器设备avdmanageravdmanager 是一种命令 ... [详细]
  •  项目地址https:github.comffmydreamWiCar界面做的很难看,美工方面实在不在行。重点是按钮触摸事件的处理,这里搬了RepeatListener项目代码,例 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • 在开发app时,使用了butterknife后,在androidStudio打包apk时可能会遇到报错。为了解决这个问题,可以通过打开proguard-rules.pro文件进行代码混淆来解决。本文介绍了具体的混淆代码和方法。 ... [详细]
  • ASP.NET2.0数据教程之十四:使用FormView的模板
    本文介绍了在ASP.NET 2.0中使用FormView控件来实现自定义的显示外观,与GridView和DetailsView不同,FormView使用模板来呈现,可以实现不规则的外观呈现。同时还介绍了TemplateField的用法和FormView与DetailsView的区别。 ... [详细]
  • 本文详细介绍了Android中的坐标系以及与View相关的方法。首先介绍了Android坐标系和视图坐标系的概念,并通过图示进行了解释。接着提到了View的大小可以超过手机屏幕,并且只有在手机屏幕内才能看到。最后,作者表示将在后续文章中继续探讨与View相关的内容。 ... [详细]
  • 本文介绍了Cocos2dx学习笔记中的更新函数scheduleUpdate、进度计时器CCProgressTo和滚动视图CCScrollView的用法。详细介绍了scheduleUpdate函数的作用和使用方法,以及schedule函数的区别。同时,还提供了相关的代码示例。 ... [详细]
  • 本文介绍了iOS开发中检测和解决内存泄漏的方法,包括静态分析、使用instruments检查内存泄漏以及代码测试等。同时还介绍了最能挣钱的行业,包括互联网行业、娱乐行业、教育行业、智能行业和老年服务行业,并提供了选行业的技巧。 ... [详细]
  • 涉及的知识点-ViewGroup的测量与布局-View的测量与布局-滑动冲突的处理-VelocityTracker滑动速率跟踪-Scroller实现弹性滑动-屏幕宽高的获取等实现步 ... [详细]
author-avatar
mobiledu2502913165
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有