npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-native-pull-to-refresh-custom

v1.0.3

Published

Custom pull to refresh Header supporting for React Native ScrollView/FlatList

Downloads

157

Readme

react-native-pull-to-refresh-custom

Custom pull to refresh Header supporting for React Native ScrollView/FlatList

React Native 自定义下拉刷新Header

Online Expo demo here: https://snack.expo.io/@sophister/custom-pull-to-refresh-header

WARN: use at your own risk!

Show Case

running demo screenshot

Install

npm i react-native-pull-to-refresh-custom

Usage

Notice: It is only tested with [email protected] and [email protected].

PullToRefresh component can ONLY accept a single child, which must be one of ScrollView, FlatList. (I've only tested it with these two components. Theoretically, it should work with other Scrollable components such as SectionList).

//Props interface for PullToRefresh
interface PullToRefreshProps {
    // container's style. You should give it a `backgroundColor`, without it,
    // the PanResponder will be terminated on iOS, according to my test
    style: ViewStyle;
    // your custom Header component, it will receive props of  PullToRefreshHeaderProps
    HeaderComponent: ComponentType<PullToRefreshHeaderProps & RefAttributes<any>>;
    // Header component's height
    headerHeight: number;
    // pulling height to trigger `onRefresh` callback, default to `headerHeight`
    refreshTriggerHeight?: number;
    // container's sticky top position when `refreshing` is true, default to `headerHeight`
    refreshingHoldHeight?: number;
    // is refreshing
    refreshing: boolean;
    // parent's callback if user's pull distance trigger a refreshing
    onRefresh: () => void;
    // child component
    children: JSX.Element;
    // when the inner scrollable's contentOffset.y <= topPullThreshold,
    // pulling down will trigger container's translate
    topPullThreshold: number;
}

// Header component's Props interface
interface PullToRefreshHeaderProps {
    // current pull distance of container component
    pullDistance: number;
    // current pull ratio range of [0, 1]
    percentAnimatedValue: Animated.AnimatedDivision;
    // current pull ratio, range of [0, 1]
    percent: number;
    // is currently refreshing
    refreshing: boolean;
}
import PullToRefresh, { PullToRefreshHeaderProps } from 'react-native-pull-to-refresh-custom';

class Header extends Component {
    // Header component **MUST** expose a `setProgress` method,
    // which is called when user is pulling container down
    // pullDistance is user's pull distance
    // percent is current pull ratio range of [0, 1]
    setProgress({ pullDistance, percent }: { pullDistance: number; percent: number}) {
        this.setState({
            pullDistance,
            percent,
        });
    }
}

<PullToRefresh
    HeaderComponent={Header}
    headerHeight={100}
    refreshTriggerHeight={140}
    refreshingHoldHeight={140}
    refreshing={this.state.refreshing}
    onRefresh={this.onRefresh}
    style={{ flex: 1, backgroundColor: 'red' }}
>
    <FlatList
        style={{ flex: 1 }}
        scrollEventThrottle={20}
        {...otherProps}
    />
</PullToRefresh>

Header component WARNING

Your custom Header component, MUST have a method called setProgress!

Your custom Header component, MUST have a method called setProgress!

Your custom Header component, MUST have a method called setProgress!

But why?

I've tried to pass the pullDistance and percent to header component through the traditional React's props flow. To do so, I've to keep pullDistance on PullToRefresh's state, and call setState() every time when user is pulling down the container. But it results in a janky animation. So, I decide to pass pullDistance to the header component through a method call.

PullToRefresh style WARNING

When I test PullToRefresh component on iOS, the container's pan responder will be terminated after it is granted, if I don't give it a backgroundColor. So, PullToRefresh will have a white background color default.

Implementation detail

Basically, PullTeRefresh is just a wrapper, the view hierarchy is simple like below:

<View>
    <Animated.View>
        <YourCustomHeader />
    </Animated.View>
    <FlatList />
</View>

Your custom Header component is within an Animated.View, which is absolute positioned with top equals - props.headerHeight, so that the header is not visible by default.

PullToRefresh has a property to track the scroll position of inner FlatList. When the inner FlatList's scrollTop is <= topPullThreshold (which defaults to 2), and if user tries to pull down, the container will catch user's drag action. Along user pulling down, it translates the Animated.View into visible region, and passes the pullDistance and percent to your custom Header component constantly through calling Header's setProgress directly.

When user releases their finger, PullToRefresh will check current pullDistance. If it's >= props.refreshTriggerHeight, it will call props.onRefresh; otherwise, it will animate the Animated.View back to it's hidden position.