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

Question : Is it possible to call ScrollTo_Y on <ListView/> Component? #1389

Closed
MossP opened this issue May 24, 2015 · 11 comments
Closed

Question : Is it possible to call ScrollTo_Y on <ListView/> Component? #1389

MossP opened this issue May 24, 2015 · 11 comments
Labels
Resolution: Locked This issue was locked by the bot.

Comments

@MossP
Copy link

MossP commented May 24, 2015

i.e. is it possible to call a method that scrolls a to a given position - the top in my instance.

@brentvatne
Copy link
Collaborator

@MossP - you can get the underlying ScrollView by calling getScrollResponder on it, and then you can call scrollTo on that 😄

@MossP
Copy link
Author

MossP commented May 24, 2015

Thanks @brentvatne I'll try that out, thank you :) 👍

@jawadrehman
Copy link

can we scroll to using a rowID ?

@brentvatne
Copy link
Collaborator

@jawadrehman - you could use the UIManager measureLayoutRelativeToParent function to determine the position and then scroll to that

@jawadrehman
Copy link

@brentvatne so what parameters would i send to the function ?

Thanks

@brentvatne
Copy link
Collaborator

The function signature is:

RCT_EXPORT_METHOD(measureLayoutRelativeToParent:(NSNumber *)reactTag
                  errorCallback:(RCTResponseSenderBlock)errorCallback
                  callback:(RCTResponseSenderBlock)callback)

So you need to pass in a ref to the component, then an error and success callback - the success callback will give you an array of values:

  callback(@[@(leftOffset), @(topOffset), @(width), @(height)]);

So let's say that your row has some ref like "mySpecialRow"

then..

var UIManager = require('NativeModules').UIManager;

// inside of your component...
React.findNodeHandle(this.refs.mySpecialRow),
function(error) { ... },
function(leftOffset, topOffset, width, height) {
  // Do something
}

@jawadrehman
Copy link

@brentvatne thanks for that...
I have one more problem, how do i use this.refs.mySpecialRow from a listview, i can't seem to access it if its defined in the renderRow function.

@VonD
Copy link
Contributor

VonD commented Jul 1, 2015

Same problem here : the refs defined within the renderRow function don't seem to be accessible.

Besides, the row we wish to scroll to might have not been rendered yet depending on current scroll position and pageSize / scrollRenderAheadDistance props.

Does that mean we have to use a ScrollView instead of a ListView if we want to be able to scroll to any row ?

@MossP @jawadrehman have you found a solution ?

@MossP
Copy link
Author

MossP commented Jul 2, 2015

Hi @VonD I hadn't been trying to scroll to a particular item as you guys had. I was just scrolling to a fixed point (0) so the code provided suffices for me.

@MattFoley
Copy link

@VonD Needed to do the same thing, scroll to an arbitrary view rendered in renderRow.

  1. Added a ref to my listView
  2. Passed a function into the class that is my rendered row to fetch the listView, along with rowData. (this.state.listView() below)
  3. Added a ref to the outmost node of the render function in my rendered row class
  4. On componentDidUpdate of my rendered row, I called my method which did the scrolling, which checked a value in rowData to determine if it needed to be scrolled to.
  5. Used UIManager to calculate the y and height of the cell, as well as the height of the listView using

My scroll method looked something like this:

var cellHandle = React.findNodeHandle(this.cell);
      UIManager.measureLayoutRelativeToParent(cellHandle, () => {}, (x, cellY, width, cellHeight) => {
        var listHandle = React.findNodeHandle(this.state.listView());
        UIManager.measureLayoutRelativeToParent(listHandle, () => {}, (x, y, width, listHeight) => {
          var position = cellY - ((listHeight / 2) - (cellHeight / 2));
          listView.getScrollResponder().scrollWithoutAnimationTo(Math.round(position), 0);
        });
      });

Took awhile to figure this out, part of me really misses scrollToRowAtIndexPath: right now.

@coodoo
Copy link

coodoo commented Sep 20, 2015

Just found another way to solve this, steps below

  1. In renderRow function, store the row element in a map by id
var row = <View><Text>{movie.title}</Text></View>;
this.$rows[movie.id] = row;
  1. Later when you need to find out the position of that row on screen, do this
var row1 = this.$rows['12345'];  // 12345 is the id of the row
var handle = React.findNodeHandle(row1._owner);  // must add ._owner here 
var m = UIManager.measureLayoutRelativeToParent(
    handle,
    (err)=>console.log( 'err:', arguments ),
    (x, y, w, h)=>{
        console.log( 'success: ', x,y,w,h );
        this.$scrollView.scrollTo(y, x);
    })

@facebook facebook locked as resolved and limited conversation to collaborators May 29, 2018
@react-native-bot react-native-bot added the Resolution: Locked This issue was locked by the bot. label Jul 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Resolution: Locked This issue was locked by the bot.
Projects
None yet
Development

No branches or pull requests

7 participants