简体   繁体   中英

OnScroll Fold the View - React Native

I'm really bad at math, I am trying to calculate the top section of the scrollView as I want it to come on top of the top View to make more place for the scrollView.

I know that I could use Animate.View to accomplish this, But due to a component( RecyclerListView ) Im unable to do that. So my Idee is while I scroll Down I move the component ItemList up until is at -150 and when I scroll up, I will move until the value scrollY hit 0.

There is already a post here on Stack( here ) That displays what I want.

Here is my code.

<View> this is the View i want to cover/fold <View>
<ItemList style={{top:scrollY}}
    onScroll={(nativeEvent, offsetX, offsetY)=>{
       // when scroll down, scrollY should not exeede 0
       // when i scroll up, scrollY should not be more -150
        var maxScroll = 0; 
        var minScroll = -150; 
        // How should i calculate and set setScrollY()
    }}
    columnPerRaw={columnPerRar}
    itemHeight={150}
    onIni={(s: any) => {
      setScroll(s);
    }}
    onItemPress={(item, index) => itemClick(item as item)}
    items={data ?? []}
    renderItem={renderItem}
    onEndReached={() => {
      if (globalContext.value.panination && !isLoading)
        setEffectTrigger(Math.random());
    }}
    keyName="name"
  />

Update

I have done like @Nnay said but its not to smoth

  var maxScroll = 0; // when i scroll up, scrollY should not be more then 0
                var minScroll = -150; // when scroll down, scrollY should not exeede -150
                var top = lastPos - offsetY;
                if (top >minScroll && top <=maxScroll)
                   setScrollY(top);
                lastPos = offsetY;

I have done it like

no matter how you choose to trigger this behaviour (be it scroll position or scroll direction), you should probably use conditional classes.

to get the scroll direction, you will need to store the previous scroll position. if oldPosition - newPosition < 0 you have scrolled down, else you have scrolled up.

if you want the position of the element to trigger it, you should opt for setting a boolean to true or false which triggers the class. something like:

<View class={{this.show ? 'show' : ''}}>

where show is a boolean local to your component.

your show class can then handle the height of the element which will automatically push the following content down (provided it isn't positioned absolute) and you can smoothen this by using transition: .25s in css. otherwise it will jump

your scroll handler could then set the boolean depending on the scroll direction with something like:

this.show = oldPos - newPos > 0;

which will return true if the user has scrolled up which seems to be the behaviour you referenced in the link

let me know if this satisfies your question so I can edit and adapt the answer accordingly

ps: if you just set the top of your element while it has a static position, it won't work. also it will just jump to that position since you're not smoothing anything

EDIT: if CSS animations and transitions don't work and you cannot use react-native's Animate.View , the only option that doesn't require external packages is to set an interval animation if react-native doesn't support the AnimationsAPI

I haven't tried using the AnimationsAPI in react-native yet so I would advise to test that first since it's much more performant.

if you want to use the interval animation, I would still recommend sticking to the boolean solution above, but removing the class and adding a height variable in the style attribute of the <View>

make sure to store your interval in a variable so you can clear it.

if (this.height < 150 /* no idea what height you need, play around */ && show && !this.interval){ 
  this.interval = setInterval(() => {
    this.height += 1;
  }, 10)
} else if (this.height > 0 && !show && !this.interval) {
  this.interval = setInterval(() => {
   this.height -= 1;
  }, 10)
} else {
  clearInterval(this.interval)
}

something like this should work. keep in mind that I haven't used interval animations in years so you might need to play around with some values

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM