Giter Club home page Giter Club logo

recyclerlistview's People

Contributors

abhishek-18 avatar adnaan1703 avatar ae0011 avatar ananyachandra14 avatar anirudhagarwal365 avatar arunreddy10 avatar bobychaudhary avatar cmcaboy avatar dylan0916 avatar elviraburchik avatar fortmarek avatar hirbod avatar inayat1 avatar isle-prashant avatar j-piasecki avatar jayfkipl avatar kevin-kp avatar marnusw avatar muskeinsingh avatar naqvitalha avatar nimishsinghal avatar radeno avatar rajatgupta26 avatar shawnchendev avatar surya-kanoria avatar swapnil1104 avatar tafelito avatar wojtus7 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

recyclerlistview's Issues

onEndReached called when initializing list

Is there any reason why the _processOnEndReached is being called here? https://github.com/Flipkart/ReactEssentials/blob/78203c98ad1caf6ec379687dc3842d29b77f4148/src/core/RecyclerListView.js#L258

The onEndReached callback is always called before loading the first items, so if I wanna add some logic to add more items when reaching the end, like an infinite loading, it will be called even if it's not needed.

Is there any other reason to do that? Or maybe it could check if the dataProvided is not empty?

UPDATE: This only happens if forceNonDeterministicRendering = true

Sticky Headers with an External ScrollView

I've been experimenting with the new externalScrollView prop trying to achieve a true sticky header experience. And this is what I came up with so far.

sticky-header-demo

My solution was replacing the normal ScrollView with an Animated.ScrollView and have its onScroll feed into an Animated value that I then use in the rowRenderer to stick some rows to the top.

This is my custom scrollview component.

class AnimatedScrollView extends React.Component {
  render() {
    return (
      <Animated.ScrollView
        ref={ref => (this._scrollView = ref)}
        scrollEventThrottle={1}
        {...this.props}
        onScroll={Animated.event(
          [{ nativeEvent: { contentOffset: { y:animatedScrollViewOffsetY } } }],
          {
            useNativeDriver: true,
            listener: this.props.onScroll
          }
        )}
      />
    );
  }
}

I then use the animatedScrollViewOffsetY Animated Value in the rowRenderer and I calculate when the views should start sticking to the top like that:

const stickyConfiguration = {
  startAt: 0,
  duration: -1 * HEADER_HEIGHT
};
_.forEach(this.state.dataProvider._data, (row, rowIndex) => {
  if (rowIndex < index) {
    stickyConfiguration.startAt += this.getRowHeight(row.viewType);
  } else {
    if (rowIndex > index && row.viewType === ViewTypes.DAY_HEADER) {
      return false;
    } else {
      stickyConfiguration.duration += this.getRowHeight(row.viewType);
    }
  }
});

I then pass the y:animatedScrollViewOffsetY to my component which positions itself with some transforms:

const translateY = {
  transform: [
    {
      translateY: this.props.animatedScrollViewOffsetY.interpolate({
        inputRange: [
          0,
          stickyConfiguration.startAt,
          stickyConfiguration.startAt + stickyConfiguration.duration
        ],
        outputRange: [0, 0, stickyConfiguration.duration],
        extrapolate: 'clamp'
      })
    }
  ]
};

One of the challenges I faced was with zIndex values. I fixed it for iOS by changing the code for ViewRenderer, but couldn't fix it on Android. There's also the problem with the onScroll event that has to run both the Animated.Event and do recyclerlistview's logic as well. I couldn't get around that myself.

I unfortunately can't just fork recyclerlistview and implement my solution since it doesn't work for Android yet, but that at least shows that the feature can be implemented. I'm thinking an additional property stickyViewTypes or something like that.

Please let me know if you need more clarification on how I made that demo work. Would love to have this added to recyclerlistview soon! ๐Ÿ‘

Opacity = 0 VS Display = none

Relative to #71

A simple example, lets say we have a view that looks like this:
Image + Text

And the Text is optional, while recycling if your component renders Text on the basis of whether text is there or not the Text component will see multiple unmounts/mounts. This might lead to drop in performance. A better way would be to simply hide Text (opacity = 0) and let it be there since it might get reused in future.

I want to know is there any difference between Opacity = 0 and Display = none for hiding objects in recycle view

Is object with Display = none recyclable? I turn on show layout bounds and Display = none has no bounds but Opacity = 0 has , So Is Display = none has inconvenient unmounts/mounts

undefined is not an object (evaluating 'itemRect.y')

This happens when I first run the app on my device:

image uploaded from ios 9

This is my component:

class EventList extends Component {
  render() {
    const { events, starredIds, starFn, unstarFn } = this.props;
    let { width } = Dimensions.get("window");

    let eventsAndStars = events.map(event => {
      return { ...event, starred: _.includes(starredIds, event.id) };
    });

    let dataProvider = new DataProvider((r1, r2) => {
      return r1 !== r2;
    });

    return h(RecyclerListView, {
      dataProvider: dataProvider.cloneWithRows(eventsAndStars),
      ref: "list",
      onContentSizeChange: () => {
        try {
          this.refs.list.scrollToIndex(0);
        } catch (e) {
          console.log("scrolling to top went wrong: ", e);
        }
      },
      style: styles.container,
      layoutProvider: new LayoutProvider(
        index => 0,
        (type, dim) => {
          dim.width = width;
          dim.height = 90;
        }
      ),
      showsVerticalScrollIndicator: false,
      rowRenderer: (type, event) => {
        const {
          id,
          featured,
          name,
          description,
          url,
          startDate,
          endDate
        } = event;
        const starred = _.includes(starredIds, event.id);
        const now = new Date();
        return h(EventRow, {
          id,
          name,
          description,
          url,
          startDate,
          endDate,
          starred,
          starFn,
          unstarFn,
          featured,
          now
        });
      }
    });
  }
}

I'm using RN 0.47.2

Feedback on RecyclerListView

Hi, following up on some conversations with @naqvitalha over in the react-native-web repo. Here are some findings/comparisons to our scroller from @madnl, who tried the component in Twitter Lite's timelines (on desktop Chrome):

  • Proximity events
    • only support for 'bottom reached' event (no distinction between near and at)
    • no at top, near top events
  • new items injected at top leads to loss of scroll position
  • after items injected at top - scrolling upwards leads to constant scroll jumps (even in Desktop Chrome, which is the most forgiving of browsers for scroll adjustments)
  • strange layout issues where items appeared offsetted to the left

  • unsure how virtualization is happening - all items seem to be rendered at once (coming back to a timeline has noticeable lag)

  • frequent stack overflows

  • A mechanism for saving position when coming back to timeline exists, but not sure how it is applied or if it works (see ContextProvider).

  • Sometimes items overlap

Although the following are not blocking issues since our current scroller does not have them either, it should be stated that this library does not seem to provide support for:

  • reverse-order lists
  • tombstones or entry previews to support fast scrolling without the rendering overhead.

For the most part, it could work, although there is a point where it might not be generally usable for our timelines - given that timelines change in a non-linear way, there does not seem to be an anchoring mechanism that ensures the most visible item stays put when new items are rendered or removed above it. This would require identifying the items by key, instead of by index how it is now.

onVisibleIndexesChanged returns wrong values when initialRenderIndex is provided

I've been trying to utilize both the onVisibleIndexesChanged and initialRenderIndex props at the same time, but I'm facing a weird behaviour that I'm not sure if it's intended to be that way.

When I provide an initialRenderIndex value of 10, onVisibleIndexesChanged is fired first with the values [0, 1, 2, 3, ...] and then it's fired again with the correct values [9, 10, 11, 12, 13, ...]

I've reproduced in this snack https://snack.expo.io/ByBPIAtyM

Has it been implemented that way on purpose? And if so, what workaround would you guys suggest?

Redux issue

I have an issue as same as #60 but in both android and iOS (I think the problem is not depends on OS)

My rowRenderer return an element connected to redux and I need to use redux , and I put dataProvider in the mapStateToProps

Can you please provide an example that show how we can use this library with redux?

when set forceNonDeterministicRendering={true}, mistake in performance occurred :(

when set forceNonDeterministicRendering={true}, mistake in performance occurred :(, but i cannot set it to false; because layout will be damaged, any one can help??

this without forceNonDeterministicRendering but performance is high.
43d6a89a-1569-47de-a33f-3f81d01c0055.
and this with forceNonDeterministicRendering, layout is awesome but performance is poor
85dce042-553f-4ffe-b498-7ffc31c88345

any idea ??

Sticky header

How can I have a sticky header like the following gif
sticky header

Prebuild Distributed Files

Currently the library seems to export the source files as they are, without transpiling ES6 or JSX syntax down to more vanilla JS. This forces users of the library to match the assumed babel configuration this library expects.

Blank white when scrolling

when I scroll slowly it looks normal. But if I scroll quickly then the white screen appears but when the scroll stops displaying the item immediately.
It makes the users less comfortable. Is there any suggestion for this?

Force rerendering when data changes

I have a case where some data in my Redux store is being updated, and I want the RecyclerListView to update its rows. Currently, if the row has been rendered it's not updated until I scroll far away and then scroll back. Is there a method that I can call to imperatively rerender the visible rows?

Available Methods for navigating the list

There is no documentation on what available props and methods.
Is there any method for navigating the list like scrollTo, scrollToIndex, scrollToItem
or a prop for setting initial list item to be focused?

RefreshControl Support

From the documents, it looks like there is no RefreshControl support yet. Do you consider this lib as a drop in replacement of FlatList in the future?
Thanks.

JavaScript with staggered grid support.

You mentioned in document that "We built RecyclerListView which is a high performance list view written purely in JavaScript with staggered grid support."

Please provide instruction, How can I achieve staggered RecyclerListView .

Rerendering row causes list to jump / snap unexpectedly

I have a list of Events that users can star. However, whenever I star that event (and therefore add the event ID to starredIds), the list snaps to the row nearest to the top. Is there a way to prevent this? It feels like bad UX.

class MyList extends Component {
  render() {
    const { events, starredIds, starFn, unstarFn } = this.props;
    let { width } = Dimensions.get("window");

    let eventsAndStars = events.map(event => {
      return { ...event, starred: _.includes(starredIds, event.id) };
    });

    let dataProvider = new DataProvider((r1, r2) => {
      return r1 !== r2;
    });

    return h(RecyclerListView, {
      dataProvider: dataProvider.cloneWithRows(eventsAndStars),
      ref: "list",
      oncontentsizechange: () => {
        try {
          this.refs.list.scrolltoindex(0);
        } catch (e) {
          console.log("scrolling to top went wrong: ", e);
        }
      },
      style: styles.container,
      layoutProvider: new LayoutProvider(
        index => 0,
        (type, dim) => {
          dim.width = width;
          dim.height = 90;
        }
      ),
      showsVerticalScrollIndicator: false,
      rowRenderer: (type, event) => {
        const {
          id,
          name,
          description,
        } = event;
        const starred = _.includes(starredIds, event.id);
        const now = new Date();
        return h(MyRow, {
          id,
          name,
          description,
        });
      }
    });
  }
}

Rendering same rows repeatedly on ios

ReactEssentials is exactly what I need. But I faced with this interesting situation when I tested with real data. I have a long list. But all list rendering with the same items (first 13 item).

Working fine on android but I stuck on ios.

recyclerlistview: ^1.1.4
react-native: 0.49.3

class UserList extends Component {
    constructor(props){
        super(props);
        
        let dataProvider = new DataProvider((r1, r2) => {
            return r1 !== r2;
        });

        let { width } = Dimensions.get("window");

        this._layoutProvider = new LayoutProvider(
            index => {
                return ''
            },
            (type, dim) => {
                dim.width = width;
                dim.height = 84;
            }
        );

        this.renderRow = this.renderRow.bind(this);

        this.state = {
            dataProvider: dataProvider.cloneWithRows(props.rows)
        };
    }

    componentWillReceiveProps(nextProps){
        let dataProvider = new DataProvider((r1, r2) => {
            return r1 !== r2;
        });

        this.setState({ dataProvider: dataProvider.cloneWithRows(nextProps.rows)});
    }

    renderRow(type, { node }) {
        return (
            <UserRow user={ node } selectedAccount={this.props.selectedAccount} />
        );
    }

    render(){
        const { listKey } = this.props;
        return (
            <Content>
                <RecyclerListView key={listKey} style={{width: 400, height: 400 }} layoutProvider={this._layoutProvider} dataProvider={this.state.dataProvider} rowRenderer={this.renderRow} />
            </Content>
        )
    }
}

export default UserList;

view recycling and "prepare for reuse"

On iOs and android we use "prepare for reuse" to make sure a view is ready to be reused.
The simplest example is Image if there were an image already loaded and you set a new image that wont load (network error or such), you end with a view with the image for another cell.

Is there any way in your lib to set the image to "null" before it is reused?

Thanks

Maintain scroll position when adding rows to the top of the list

When I call dataProvider.cloneWithRows() and add more rows to the top of the list. The scroll position is lost. I tried investigating by reading the source code. I'd appreciate it if you could help with this!

And thanks for the great library! Its performance is amazing.

Question: How to update initialRenderIndex when changing rows

I'm trying to update the rows with cloneWithRows, but looks like updating initialRenderIndex at the same time as updating the dataProvider doesn't actually work. Maybe that's the way it was intended to work, but I also noticed that the recyclerlistview maintains scrollposition even if the overall height of it changes.

I made a quick snack of this case here: https://snack.expo.io/SJyh3xiyG

You can see that I have an initialRenderIndex of 20, and there are 100 rows in total. Upon changing the rows to be 10, the scroll position hasn't changed and you'd have to scroll the recyclerlistview a little bit and then the scroll position is fixed.

Changing the initialRenderIndex doesn't have an effect as well, as I mentioned before.

Question : Complex layout

I have a list with 10 different layout type , each type can text comment or not , For example I have an Image layout that can contain text or not , layout here is similar to blog post

Another type is Video that may contain text or not

Must I define 20 different ViewTypes for LayoutProvider ?

change size of rendered item

Good day based on the source code I can see that there is an onSizeChange(), but I cannot find anything on how to change the size in such a mater that this event is triggered. Any pointers on what too look for?

Blank area

I have a list with about 100 items . when I scroll I see blank area for 0.5 second

I try your sample with last version of react native

It has not same performance like your YouTube and I see blank area . I test at release mode in android 7 phone with 8 core CPU and 8 gig ram

Also in your sample except image all data is same and not changed so we have no cha he in view except images . If you try with better data and each row has different price and ... , the performance decreases and we have more blank area

I also increase renderAheadOffset to 320 and 640 but still see blank area even in your sample project

Portrait/Landscape rotation - resize issue

When I rotate the device the cells are upgraded their size only when I scroll, and not on rotation. I've set the canChangeSize={true} props, the _layoutProvider is called once the device is rotated with the right new sizes, but the cell width is expanded or reduced only after some scrolling.

ListView starts rendering at index 1

This is almost certainly not a bug in the RecyclerListView code (but might use a clarification in the documentation).

When I render my list, the first visible item in my list is at index 1 in my data provider. When I overscroll to the top (like a pull to refresh gesture), I can see my index 0 item being rendered in that position (off the top of the window). Am I missing styling?

Question : measure hight of text

I have a large data set contains different media and text

I can calculate all dimensions before rendering . except text

How can I exactly calculate text height for known width?? (I need a solution that works for web too)
Is the height depends on font-family too? Or just font-size?

[ReactNative] this.virtualRenderer not always initialized in RecyclerListView

First of all, thanks a lot for creating this great list view component. The built in FlatList and SectionList components of react-native are pretty bad at handling initial scrollOffsets, where this component really shines (especially with ContextProvider).

I found a bug where new props lead to exceptions through the componentWillReceiveProps call in RecyclerListView:

When the RecyclerListViews parent is re-rendered early after being mounted, the RecyclerListView's componentWillReceiveProps is called, but this.virtualizedRenderer is not yet initialized. This will lead to two exceptions in the following lines:

As a quick fix, I wrapped both lines in an if (this.virtualRenderer) { ... } and there are no more exceptions or weird behavior.

You can try out the following sample to reproduce the bug:

Sample Repo

Calling 'scrollToIndex' while manually scrolling causes blank content

I have a specific case here where there's a button that scrolls to a specific index in the list. If I tap the button when the list is idle, it scrolls there and renders things just fine, but if the user is already scrolling in the list, it scrolls to its destination and shows blank content until I start scrolling again.

As far as I understood from the source code, there's a render stack that's prepared and it's being updated on scroll. The problem is that as the user is scrolling, if I force the list to go to a specific index with no animation, the renderStack loses track of the items it should render, until I start scrolling again, and then the renderStack gets updated and it renders things correctly again.

I hope my explanation made sense. Please let me know if I need to elaborate further.

Cannot scroll if nested inside ScrollView

Hi,
I'm facing a problem that RecyclerListView cannot scroll if it's nested inside a ScrollView. It happens in Android, I haven't tested with iOs yet.
Do you have any idea about this problem?

Best regards,
Nghia.

Cannot read property 'reLayoutFromIndex' of undefined

I'm trying to change the content of the recylcerlistview, but I keep getting Cannot read property 'reLayoutFromIndex' of undefined. What could be causing that error?

I'm updating my data in the following way:

this.setState(prevState => ({
   dataProvider: prevState.dataProvider.cloneWithRows(newRows)
}));

The error happens in RecyclerListView.js:224 in the line
this._virtualRenderer.getLayoutManager().reLayoutFromIndex(newProps.dataProvider._firstIndexToProcess, newProps.dataProvider.getSize());

That was called from componentWillReceiveProps of RecyclerListView in the line this._checkAndChangeLayouts(newProps);

_virtualRenderer is getting set to null for some reason. Could you please explain what could be causing that problem

Some callback needed

@naqvitalha I want to implement a simple version of sticky header for my use case
How can I detect that which item is topmost (or bottommost) and which is coming in view report and which is go out?

Invalid semver version for latest update

Hi!

The latest version has been released as version 1.0.7, the version before this was 1.0.61.

If your module is now installed via npm i --save, 1.0.61 is downloaded instead of 1.0.7. A quick fix would be to publish either a version above 1.0.61 or directly go for 1.1.0

LayoutProvider and item

I have an use case that LayoutProvider must pass me item to calculate dim.width and dim.height

like the following code

 this._layoutProvider = new LayoutProvider(
            index => {
                if (index % 3 === 0) {
                    return ViewTypes.FULL;
                } else if (index % 3 === 1) {
                    return ViewTypes.HALF_LEFT;
                } else {
                    return ViewTypes.HALF_RIGHT;
                }
            },
            (type, dim , item) => {
                  dim.width = item.width();
                  dim.height = item.height();
            }
        );

(type, dim , item) => {} OR (type, dim , index) => {} is good

Cannot read property 'getLayoutDimension' of undefined

If I initially load a page before having data, returning an empty page(null/No Data) then fetch data from server after component mounted and set the data for data provider to my new data this error is produced at VirtualRenderer.getLayoutDimension.

On IOS it imediatly displays the "'getLayoutDimension' of undefined" error while on android the red screen displays 'Node has not been attached to a view' and the getLayoutDimension goes as a warning in background and on Debug console.

Commenting out the onEndReached property makes the problem stop.

I have tried to reproduce the error on snack/expo, but it does not reproduce the same error. On snack/expo it sometimes just work and other times expo just crashes.

Link to example: https://snack.expo.io/ryy4QxFRZ

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.