Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FlatList] The maintainVisibleContentPosition doesn't work for the 1st time change. #19621

Closed
5 tasks
chinalwb opened this issue Jun 8, 2018 · 5 comments
Closed
5 tasks
Labels
Stale There has been a lack of activity on this issue and it may be closed soon.

Comments

@chinalwb
Copy link

chinalwb commented Jun 8, 2018

Environment

Environment:
OS: macOS High Sierra 10.13.4
Node: 6.11.3
Yarn: 0.24.5
npm: 5.5.1
Watchman: 4.7.0
Xcode: Xcode 9.2 Build version 9C40b
Android Studio: 3.1 AI-173.4670197

Packages: (wanted => installed)
react: 16.3.1 => 16.3.1
react-native: 0.55.2 => 0.55.2

Description

I have a FlatList with 8 items: 100 ~ 107 are being shown
I set minIndexForVisible = 0 for maintainVisibleContentPosition:

        <FlatList
          style={styles.flatList}
          data={this.state.items}
          renderItem={this._renderItem}
          maintainVisibleContentPosition={{
            minIndexForVisible: 0,
          }}
        />

I have a button to prepend 90 ~ 99 (10 items in total) to the FlatList.
At beginning, the top item 100 is being shown at top of the FlatList, then I scroll down a bit, then 102 is being at top of the screen.

By clicking the prepend button, I expect the FlatList:

  1. The items should be changed to 90 ~ 99 + 100 ~ 107 --- this is OK
  2. I expect the 1st visible item, i.e.: 102, to be keep its position -- this is not OK -- instead the FlatList scrolls to top, i.e.: the item 92 is being shown at top.

Then I click the prepend button again, this time, I expect the FlatList:

  1. The items should be changed to 80 ~ 89 + 90 ~ 107 --- this is OK
  2. I expect the 1st visible item, i.e.: 92, to be keep its position -- this is OK this time.

Steps to Reproduce

See my code on snack. https://snack.expo.io/@rainliu123/flatlisttest

import React, { Component } from 'react';
import {
  Platform,
  StyleSheet,
  Text,
  View,
  FlatList,
  Button,
} from 'react-native';

const instructions = Platform.select({
  ios: 'Press Cmd+R to reload,\n' +
    'Cmd+D or shake for dev menu',
  android: 'Double tap R on your keyboard to reload,\n' +
    'Shake or press menu button for dev menu',
});

export default class App extends Component<Props> {

  constructor(props) {
    super(props)

    this.messages =  [{key: '100'}, {key: '101'}, {key: '102'}, {key: '103'},
    {key: '104'}, {key: '105'}, {key: '106'}, {key: '107'}]
    this.state = {
      items: [
       ...this.messages
        // {key: '104'}, {key: '105'}, {key: '106'}, {key: '107'}
      ],
    }

    this.topNumber = 100

    this._append = this._append.bind(this)
  }

  _renderItem = ({item}) => {
    return (
      <View style={styles.item}>
         <Text>{item.key}</Text>
      </View>
    )
  }


  _preppend = () => {
    console.log(`this.state.items len == ${this.state.items.length}`)
    let newItems = []
    for (var i = 10; i >= 1; i--) {
      const itemNumber = this.topNumber - i
      console.log(itemNumber)
      const newItemText = '' + itemNumber
      console.log(`${newItemText}`)
      const newItem = {
        key: newItemText,
      }
      newItems.push(newItem)
    }

    this.topNumber = this.topNumber - 10
    
    setTimeout(()=>{
      this.setState({
        items: [...newItems, ...this.state.items]
      })
    }, 1000)
    
  }

  _append = () => {
    const newItemText = '' + (100 + this.state.items.length)
    const newItem = {
      key: newItemText,
    }
    this.setState({
      items: [...this.state.items, newItem]
    })
  }

  render() {
    return (
      <View style={styles.container}>

        <FlatList
          style={styles.flatList}
          data={this.state.items}
          renderItem={this._renderItem}
          maintainVisibleContentPosition={{
            minIndexForVisible: 0,
          }}
        />

        <View style={styles.buttons}>
          <Button onPress={this._preppend}
            title="Preppend" />
          <Button onPress={this._append} 
            title="Append" />
        </View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  flatList: {
    flex: 8,
  },
  buttons: {
    height: 30,
    marginBottom: 10,
    flexDirection: 'row',
    justifyContent: 'space-around',
  },
  item: {
    flex: 1,
    width: 300,
    justifyContent: 'center',
    alignItems: 'center',
    height: 100,
    backgroundColor: '#fff000',
    marginBottom: 20,
  },
  container: {
    flex: 10,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#05FC0F',
  },
});

Expected Behavior

The first time I prepend items to FlatList, the content position should be locked

Actual Behavior

The first time I prepend items to FlatList, the content position cannot be locked.
BTW, the subsequent prepend items to FlatList is able to keep the position.

@react-native-bot
Copy link
Collaborator

It looks like your issue may be missing some necessary information. Can you run react-native info and edit your issue to include these results under the Environment section?

@chinalwb
Copy link
Author

chinalwb commented Jun 8, 2018

@react-native-bot I updated Environment section. Thanks.

@stale
Copy link

stale bot commented Sep 10, 2018

Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs. You may also label this issue as "For Discussion" or "Good first issue" and I will leave it open. Thank you for your contributions.

@stale stale bot added the Stale There has been a lack of activity on this issue and it may be closed soon. label Sep 10, 2018
@stale
Copy link

stale bot commented Sep 17, 2018

Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.

@stale stale bot closed this as completed Sep 17, 2018
@facebook facebook locked as resolved and limited conversation to collaborators Sep 18, 2018
chinalwb referenced this issue Nov 5, 2018
Summary:
Builds off of cae7179

- Make the prop a dictionary for more configuration options
- Rename `maintainPositionAtOrBeyondIndex` -> `maintainVisibleContentPosition` + `minIndexForVisible`
- Add autoscroll threshold feature

Given the async native of RN JS and background layout, there is no way to trigger the scrollTo from JS without risking a delay, so we add the feature in native code.

== Test Plan ==
ScrollViewExample:
https://youtu.be/pmY8pxC9PRs

Reviewed By: shergin

Differential Revision: D6729160

fbshipit-source-id: 70f9bae460ce84567857a4f696da78ce9b3b834c
@sahrens
Copy link
Contributor

sahrens commented Dec 11, 2018

Sorry no one got to this, and thanks so much for writing up such a detailed and complete repro / test case! We'll try to take a look at this soon.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Stale There has been a lack of activity on this issue and it may be closed soon.
Projects
None yet
Development

No branches or pull requests

4 participants