React Native 踩坑日记(十) —— 使用 flatlist 的滚动处理键盘遮挡的问题.

前言

这篇文章没有什么特别需要讲的,主要是之前在处理键盘遮挡问题的时候,使用到了flatlist中的滚动问题,所以特别记录一下.

效果图

这种方案最后没有使用,原因有几个:

  • 只有 ios 下可以使用,因为在安卓系统上,如果输入框是最后一行的 cell, 让他往上滚动,是无法让该 cell 的顶部与页面的顶部持平的.(可以看上面的效果图)
  • 在安卓系统下,如果输入框是最底下那一行,点击后键盘弹出,还未滚动到顶部,键盘就立刻又消失了.
  • 这种做法的用户体验并不好,页面给人感觉会有大幅度的自行滚动.

之所以特意写了一篇笔记记录,主要是在这种方案中学到了几个东西.
下面是几个代码片段,一一说明.


实现思路

整个实现的目的,综合来说,就是

  • Textinput里头,当点击输入框时,产生了onFocus的回调,此时先让选中的cell滚动到整个页面的顶部.
  • 滚动必须调用到 flatlist 的scrollToIndex的方法,this._tableview.scrollToIndex({animated: true, index: cellIndex, viewPosition: 0});, viewPosition 为0表示让他的上部与顶部持平.
  • 输入结束后,获取到onEndEdit,再让他滚动到居中的位置,避免最后一行的空白问题.this._tableview.scrollToIndex({animated: true, index: cellIndex, viewPosition: 0.5});
  • 使用scrollToIndex必须要配合flatlistgetItemLayout设置.

片段一

<FlatList ref={(flatlist => this._tableview = flatlist)} data={this.dataSource}
          renderItem={({item}) => this._renderItem(item)}
          keyExtractor={(item) => item.index}
          ItemSeparatorComponent={(item) => this._seperator(item)}
          extraData={this.state}
          getItemLayout={(data, index) => {
              let length = this.dataSource[index].height;
              let totalOffset = 0;
              for (let i = 0; i < index; i++) {
                  totalOffset += this.dataSource[i].height + 1;
              }
              // console.log('当前偏移 =' + totalOffset);
              return {length: length, offset: totalOffset, index: index};
          }}
          onScrollBeginDrag={() => {
              if (!this.isNeedKeyborad) {
                  return;
              }

              this.isNeedKeyborad = false;
              dismissKeyboard();
          }}
/>
  • getItemLayout 最后要返回一个 JSON object
    这几个值必须要返回的.

    • length 是当前 cell 的高度,
    • offset 是整个 flatlist 的当前偏移量(需要如代码中写的,遍历这个 cell 之前所有的 cell 高度,叠加)
    • index, 当前 cell 的索引值

    return {length: length, offset: totalOffset, index: index};

  • onScrollBeginDrag 写这个是为了避免滚动时,最后一行被键盘遮挡. 因为onScrollBeginDrag和另一个回调的onScroll不同,后者代表的是所有的滚动事件(包括用户手动拖曳,以及我们调用 scrollToIndex时候的滚动),所以要监听到我们的手动滚动,必须要使用这个回调.

  • dismissKeyboard(); 这个是系统提供的库,用来让键盘消失用的.

    import dismissKeyboard from '../../../node_modules/react-native/Libraries/Utilities/dismissKeyboard';

片段二

// 按键输入回调, 写入 state 进行保存.
_onEndEditText = (cellIndex, stateName, text) => {
    this.isNeedKeyborad = true;
    this._tableview.scrollToIndex({animated: true, index: cellIndex, viewPosition: 0.5});
    this.setState({[stateName]: text});

    console.log('输入结束的文本 =' + text + '\n返回的 state 名' + stateName);
    console.log('------------------');
};

_onFocusInputCell = (cellIndex) => {
    this.isNeedKeyborad = true;
    let CustomLayoutAnimation = {
        duration: 800,
        create: {
            type: LayoutAnimation.Types.spring,
            property: LayoutAnimation.Properties.scaleXY,
        },
        update: {
            type: LayoutAnimation.Types.spring,
            property: LayoutAnimation.Properties.scaleXY,
        },
    };
    LayoutAnimation.configureNext(CustomLayoutAnimation);

    this._tableview.scrollToIndex({animated: true, index: cellIndex, viewPosition: 0});

};
  • LayoutAnimation只是一个动画,类似于我们ios[UIView animationWithDuration]
  • this._tableview.scrollToIndex主要说明下后面的viewPosition参数,传入的是0到1之间的数.用来控制 cell 在当前滑动区域的位置.0表示与上端持平.
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343

推荐阅读更多精彩内容