NativeBase(React Native)避免滚动回到顶部

9

我正在尝试使用列表组件来处理大量输入,但注意到在输入后它会不断滚动回顶部。

enter image description here

我不知道这是否与React Native中的ListView总是回滚到顶部有关 - 我尝试过<List style={{flex> 1}} ..>但没有成功。

更新

我想如果我加入一些代码,可能更容易帮助我解决问题。

import React, { Component } from 'react'
import { View } from 'react-native'
import { List, ListItem,  InputGroup, Input, Icon, Button } from 'native-base'

export default class AddInformation extends Component {
  constructor(props) {
    super(props)

    this.state = {
      items: 
[
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"},
{value: "", keyboardType: "default"}]}

}

render () {
    return (
      <List
        dataArray={this.state.items}
        renderRow={
          (obj) => {
            console.log(obj)
            return (
              <ListItem>
                <InputGroup>

                <Input
                  placeholder={`${obj.keyboardType} keyboard`}
                  onChangeText={ (text)=> {
                    //TODO
                  } }
                  keyboardType={obj.keyboardType}
                />
                </InputGroup>
              </ListItem>
            )
        }}>
      </List>
    )
  }
}

更新2

仍然无法工作...

import React, { Component } from 'react'
import { View, ListView, Text, TextInput } from 'react-native'
import { FormLabel, FormInput } from 'react-native-elements'

export default class AddInformation extends Component {
  constructor(props) {
    super(props)
    const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

  }

  componentDidMount() {
   this.state = {
      items: ds.cloneWithRows([
        {hint: "foo", value: "", keyboardType: "default"},
         ...
        {hint: "bar", value: "", keyboardType: "numeric"}
      ])
    }

  }
...

并且渲染方法:

  render () {
    return (
      <View style={{flex: 1}}>
        <ListView

          dataSource={this.state.Specifications}
          renderRow={(rowData) =>
            <View>
              <FormLabel>{rowData.hint}</FormLabel>
              <FormInput
                placeholder={`Keyboard: ${rowData.keyboardType}`}
                />
                <TextInput />
            </View>
          }/>
      </View>
    )
  }
}

不知道这是否与NativeBase布局有关..?
import React, { Component } from 'react'
import { Container, Content, Header, Title, Button, Icon } from 'native-base'
import AddInformation from './AddInformation'

export default class ScreenAddItemInformation extends Component {
  render() {
    return (
      <Container>

        <Header>
          <Button transparent onPress={ () => this.props.navigator.pop() }>
            <Icon name='ios-backspace' />
          </Button>

          <Title>Add New Item</Title>

        </Header>

        <Content>
          <AddInformation />
        </Content>

      </Container>
    );
  }
}

更新3

我刚刚尝试了一个硬编码的<List>和没有动态渲染的<ListItem>,但问题仍然存在,一旦键盘关闭,“视图”就会滚回到顶部。


你是否已经正确实现了rowHasChanged,以便它不会重新渲染已经渲染过的行? - Tudor Constantin
@TudorConstantin 不,我没有。我正在使用NativeBase Dynamic List http://nativebase.io/docs/v0.5.13/components#list,它只需要传递一个数组。 - Norfeldt
你能否添加更新 this.state.items 的代码?Tudor 的评论似乎是正确的。你应该尝试直接使用 ListView 而不是 List widget。根据你设置 items state 的方式,ListView 可能会通过 List widget 重新渲染整个列表。 - while1
@while1 我已经更新了我的问题。 - Norfeldt
3个回答

4

我也遇到了这个问题,对我来说这是一个简单的解决方法。

<Container>
    <ScrollView>{/* <- Use this rather than Content */}
      {/* form with this issue */}
    </ScrollView>
</Container>

1

在将相同的问题发布到NB论坛后,我得到了一个有用的链接来解决这个“错误”:

https://github.com/GeekyAnts/NativeBase/issues/339

Components/ScreenAddInformation.js:

import React, { Component } from 'react'
import { Container, Content, Header, Title, Button, Icon } from 'native-base'
import Information from './Information'

export default class ScreenAddInformation extends Component {
  constructor(props) {
    super(props)    
    this.state = {scrollY: 0}
  }

handleScroll(event) {
    this.setState({ scrollY: event.nativeEvent.contentOffset.y });
  }

  render() {
    _.set(this.refs, 'Content._scrollview.resetCoords', { x: 0, y: this.state.scrollY });
    return (
      <Container>

        <Header>
          <Button transparent onPress={ () => this.props.navigator.pop() }>
            <Icon name='ios-backspace' />
          </Button>

          <Title>Add New Information</Title>

        </Header>

        <Content
          ref="Content"
          onScroll={event => this.handleScroll(event)}
          >
          <AddInformation />
        </Content>

      </Container>
    );
  }
}

Components/AddInformation.js:

import React, { Component } from 'react'
import { View, Text } from 'react-native'
import { List, ListItem, InputGroup, Input } from 'native-base'

export default class AddInformation extends Component {
  render () {
    return (
      <List>
        <ListItem itemDivider>
          <Text>Information to add</Text>
        </ListItem>
        <ListItem >
          <InputGroup borderType="underline">
            <Input stackedLabel label="Foo" />
          </InputGroup>
        </ListItem>
        <ListItem>
          <InputGroup borderType="underline">
            <Input stackedLabel label="Bar" />
          </InputGroup>
        </ListItem>
        <ListItem >
          <InputGroup borderType="underline">
            <Input stackedLabel label="Foo" />
          </InputGroup>
        </ListItem>
        <ListItem>
          <InputGroup borderType="underline">
            <Input stackedLabel label="Bar" />
          </InputGroup>
        </ListItem>
        <ListItem >
          <InputGroup borderType="underline">
            <Input stackedLabel label="Foo" />
          </InputGroup>
        </ListItem>
        <ListItem>
          <InputGroup borderType="underline">
            <Input stackedLabel label="Bar" />
          </InputGroup>
        </ListItem>
        <ListItem >
          <InputGroup borderType="underline">
            <Input stackedLabel label="Foo" />
          </InputGroup>
        </ListItem>
        <ListItem>
          <InputGroup borderType="underline">
            <Input stackedLabel label="Bar" />
          </InputGroup>
        </ListItem>
        <ListItem>
          <InputGroup borderType="underline">
            <Input stackedLabel label="Bar" />
          </InputGroup>
        </ListItem>
        <ListItem >
          <InputGroup borderType="underline">
            <Input stackedLabel label="Foo" />
          </InputGroup>
        </ListItem>
        <ListItem>
          <InputGroup borderType="underline">
            <Input stackedLabel label="Bar" />
          </InputGroup>
        </ListItem>
        <ListItem >
          <InputGroup borderType="underline">
            <Input stackedLabel label="Foo" />
          </InputGroup>
        </ListItem>
        <ListItem>
          <InputGroup borderType="underline">
            <Input stackedLabel label="Bar" />
          </InputGroup>
        </ListItem>
      </List>
    )
  }
}

这里是可行的解决方案:

enter image description here

我很高兴现在它能够工作了!谢谢 booboothefool


很遗憾,这对我没有起作用。在最新版本的库上,它仍然对你有用吗? - jbouaziz
我有一段时间没有使用NativeBase了...所以不太清楚,抱歉。 - Norfeldt
没关系,无论如何谢谢!你为什么离开它呢? - jbouaziz
这很棒,但对我来说还是太多测试版了。在2版本中有很多变化,我想等它变得更加稳定一些 - 我肯定会回来的。我学会了自己构建一些组件(比如卡片)。 - Norfeldt

0

如果您只是在提交时隐藏键盘怎么样?尝试像这样的解决方法:

<TextInput onSubmitEditing={ () => Keyboard.dismiss() }>

不要忘记从'react-native'导入{ Keyboard }。

谢谢您的好建议,但如果我在列表外按下并使键盘关闭,它会起作用吗?这是一样的吗 - 因为我只看到一个onFocus属性而没有offFocus。 - Norfeldt
1
您还可以为TextInput添加onBlur,它是onFocus的相反。 - Matt Aft

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接