最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

react-native滑動吸頂效果的實現(xiàn)過程

 更新時間:2019年06月03日 09:24:43   作者:mguy_1  
這篇文章主要給大家介紹了關(guān)于react-native滑動吸頂效果的實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用react-native具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧

前言

最近公司開發(fā)方向偏向移動端,于是就被調(diào)去做RN(react-native),體驗還不錯,當(dāng)前有個需求是首頁中間吸頂?shù)男Ч?,雖然已經(jīng)很久沒寫樣式了,不過這種常見樣式應(yīng)該是so-easy,沒成想翻車了,網(wǎng)上搜索換了幾個方案都不行,最后去github上復(fù)制封裝好的庫來實現(xiàn),現(xiàn)在把翻車過程記錄下來。

需求效果

翻車過程

第一種方案 失敗

一開始的思路是這樣的,大眾思路,我們需要監(jiān)聽頁面的滾動狀態(tài),當(dāng)頁面滾動到要吸頂元素所處的位置的時候,我們設(shè)置它為固定定位,不過很遺憾,RN對于position屬性只提供了兩種布局方式:absolute和relative,既沒有fixed也沒有仍處于試驗的api:sticky。尷尬了😅

第二種方案 失敗

不過也不慌,看網(wǎng)上有第二種方案,把圖上第二 三塊地方作為ScrollView,然后ScrollView滑動監(jiān)聽距離,把第一塊的marginTop設(shè)為負值,但是這樣第一部分不能滑動,不符合需求,pass

第三種方案 完全失敗

從網(wǎng)上找到第三種方案,就是一二三部分作為ScrollView,

第一部分position設(shè)為absolute,剩下的不設(shè)置,默認(rèn)是relative

第二部分(吸頂部分)marginTop設(shè)置(setState)為第一部分高度的state,

添加滑動onScroll事件=》滑動距離y等于第二部分marginTop的state,但是當(dāng)滑動超過第一部分高度的時候把第二部分(吸頂部分)position設(shè)為absolute,并把其marginTop設(shè)為0,看起來不錯,實際用ios模擬器一跑就無語了😅,效果很奇葩,手指滑動時不吸頂直接劃上去隱藏掉大半,一松突然吸頂了。。。

見下圖

ios的系統(tǒng),手指在屏幕上滾動時,onScroll一直在觸發(fā),如果里面有setState方法,也會不停執(zhí)行并計算state,但是改變react的state是異步的,只要手指不離開屏幕,改變的state就無法生效(觸發(fā)界面渲染)

實現(xiàn)方案

我最終意識到由于ios的機制,react的state機制不能滿足需求,RN里面肯定有借助原生渲染的方式,于是github找了現(xiàn)成的代碼實現(xiàn)之后,反過來進行研究,大家有RN豐富經(jīng)驗的也可以直接看最下面代碼👇

RN的Animator

RN的Animator動畫庫旨在解決動畫問題,由于js橋接過程,動畫通常不能很好展現(xiàn),最好是把動畫的 數(shù)據(jù) 和 變化方法 一次性發(fā)給原生,由原生進行處理,這就是Animator庫的核心作用。

記得原來RN的動畫一直被吐槽,不過現(xiàn)在效果還挺不錯的,可能與近年來手機硬件提升也越來越大也有關(guān)系吧。

簡單用法

由于Animator內(nèi)部封裝了這四個組件,所以默認(rèn)可以導(dǎo)出<Animator.View/>,<Animator.Text/>,<Animator.Image/>,<Animator.ScrollView/>

在這幾個組件里面想做一些動畫處理,數(shù)據(jù)方面也是react的state,但是賦值要給Animated.Value,如下👇

this.state = {
  scrollY: new Animated.Value(0)
}

這里雖然使用的還是原生state,但是經(jīng)過Animated處理,渲染機制完全不一樣了

簡單原理

經(jīng)過Animator包裝后的組件,會遍歷傳入的props和自身的state,查找是否有Animated.Value的實例,并綁定進相應(yīng)的原生操作。

props和自身的state變化時,將Animated.Value值逐個轉(zhuǎn)化為普通數(shù)值,再交給原生進行渲染,但是值得注意的是,這里并不會觸發(fā)react 的 render,更不會有什么domdiff ,是一種特殊處理,類似于Animated.Value改變時每次的shouldUpdateComponent返回都是false(毫秒級的渲染react性能扛不住),shouldUpdateComponent函數(shù)里面判斷Animated.Value,然后會把數(shù)據(jù)變化發(fā)給原生組件

完整的介紹請移步中文官網(wǎng)Animator庫介紹

實現(xiàn)思路

既然用了Animator組件了,渲染的問題解決了,下面思路是動態(tài)設(shè)置吸頂組件的translateY屬性。style:{ transform: [{ translateY:translateY }] }

  • 當(dāng)向下滑動時,不管它
  • 向上滑,但是當(dāng)頭部還沒有完全隱藏時,也不管它
  • 向上滑,頭部完全不見了,這時向上再滑一點,那么他的translateY就應(yīng)該 = 上劃總距離 - 頭部高度,這樣越往上滑,把吸頂組件使勁往下推,這樣吸頂組件就牢牢固定在頂部了

下面利用插值來實現(xiàn)

const translateY = ScrollY.interpolate({
  inputRange: [-1, 0, headerHeight, headerHeight + 1],
  outputRange: [0, 0, 0, 1],
});

插值interpolate略難理解,需要一點基礎(chǔ),這里再細說起來這篇文章就太長了官網(wǎng)介紹,

如果還不懂可以去網(wǎng)上找找這方面的資料

實現(xiàn)源碼

實現(xiàn)的圖中第二部分吸頂功能的核心代碼

import * as React from 'react';
import { StyleSheet, Animated } from "react-native";

/**
 * 滑動吸頂效果組件
 * @export
 * @class StickyHeader
 */
export default class StickyHeader extends React.Component{

  static defaultProps = {
    stickyHeaderY: -1,
    stickyScrollY: new Animated.Value(0)
  }
  
  constructor(props) {
    super(props);
    this.state = {
      stickyLayoutY: 0,
    };
  }
  // 兼容代碼,防止沒有傳頭部高度
  _onLayout = (event) => {
    this.setState({
      stickyLayoutY: event.nativeEvent.layout.y,
    });
  }

  render() {
    const { stickyHeaderY, stickyScrollY, children, style } = this.props
    const { stickyLayoutY } = this.state
    let y = stickyHeaderY != -1 ? stickyHeaderY : stickyLayoutY;
    const translateY = stickyScrollY.interpolate({
      inputRange: [-1, 0, y, y + 1],
      outputRange: [0, 0, 0, 1],
    });
    return (
      <Animated.View
        onLayout= { this._onLayout }
        style = {
          [
            style,
            styles.container,
            { transform: [{ translateY }] }
          ]}
      >

      { children }

      </Animated.View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    zIndex: 100
  },
});

頁面里實際用法如下

// 在頁面constructor里聲明state
this.state = {
  scrollY: new Animated.Value(0),
  headHeight:-1
};
<Animated.ScrollView 
  style={{ flex: 1 }}
  onScroll={
    Animated.event(
      [{
        nativeEvent: { contentOffset: { y: this.state.scrollY } } // 記錄滑動距離
      }],
      { useNativeDriver: true }) // 使用原生動畫驅(qū)動
  }
  scrollEventThrottle={1}
>

  <View onLayout={(e) => {
    let { height } = e.nativeEvent.layout;
    this.setState({ headHeight: height }); // 給頭部高度賦值
  }}>
    // 里面放入第一部分組件
  </View>
  
  <StickyHeader
    stickyHeaderY={this.state.headHeight} // 把頭部高度傳入
    stickyScrollY={this.state.scrollY}  // 把滑動距離傳入
  >
    // 里面放入第二部分組件
  </StickyHeader>
  
  // 這是第三部分的列表組件
  <FlatList
    data={this.state.dataSource}
    renderItem={({item}) => this._createListItem(item)}
  />
  
</Animated.ScrollView>

收尾

具體代碼就是這樣實現(xiàn)了,算是比較完美的方案,特別是照顧了性能,各位可以基于這個封裝來實現(xiàn)更復(fù)雜的需求,原理大概就是這個原理了,在前端動畫領(lǐng)域,自己確實也就剛?cè)腴T水平,如有問題,請直接指出。

另外,這是我找的那個 組件 github的代碼地址:https://github.com/jiasongs/react-native-stickyheader,原地址附上,建議如果項目用了給人家一個star

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。

相關(guān)文章

  • 詳解使用React全家桶搭建一個后臺管理系統(tǒng)

    詳解使用React全家桶搭建一個后臺管理系統(tǒng)

    本篇文章主要介紹了使用React全家桶搭建一個后臺管理系統(tǒng),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • react-beautiful-dnd 實現(xiàn)組件拖拽功能

    react-beautiful-dnd 實現(xiàn)組件拖拽功能

    這篇文章主要介紹了react-beautiful-dnd 實現(xiàn)組件拖拽功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-08-08
  • react中使用swiper的具體方法

    react中使用swiper的具體方法

    本篇文章主要介紹了react中使用swiper的具體方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • 基于React實現(xiàn)表單數(shù)據(jù)的添加和刪除詳解

    基于React實現(xiàn)表單數(shù)據(jù)的添加和刪除詳解

    這篇文章主要給大家介紹了基于React實現(xiàn)表單數(shù)據(jù)的添加和刪除的方法,文中給出了詳細的示例供大家參考,相信對大家具有一定的參考價值,需要的朋友們下面來一起看看吧。
    2017-03-03
  • 在 React 項目中使用 Auth0 并集成到后端服務(wù)的配置步驟詳解

    在 React 項目中使用 Auth0 并集成到后端服務(wù)的配置步驟詳解

    這篇文章主要介紹了在 React 項目中使用 Auth0 并集成到后端服務(wù)的配置步驟詳解,通過本文詳細步驟,您可以將 Auth0 集成到 React 項目并與后端服務(wù)交互,需要的朋友可以參考下
    2024-07-07
  • 基于React封裝一個驗證碼輸入控件

    基于React封裝一個驗證碼輸入控件

    郵箱、手機驗證碼輸入是許多在線服務(wù)和網(wǎng)站常見的安全驗證方式之一,本文主要來和大家討論一下如何使用React封裝一個驗證碼輸入控件,感興趣的可以了解下
    2024-03-03
  • React精髓!一篇全概括小結(jié)(急速)

    React精髓!一篇全概括小結(jié)(急速)

    這篇文章主要介紹了React精髓!一篇全概括小結(jié)(急速),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-05-05
  • React通過ref獲取子組件的數(shù)據(jù)和方法

    React通過ref獲取子組件的數(shù)據(jù)和方法

    這篇文章主要介紹了React如何通過ref獲取子組件的數(shù)據(jù)和方法,文中有詳細的總結(jié)內(nèi)容和代碼示例,具有一定的參考價值,需要的朋友可以參考下
    2023-10-10
  • React中Context的用法總結(jié)

    React中Context的用法總結(jié)

    Context?提供了一種在組件樹中共享數(shù)據(jù)的方式,而不必通過?props?顯式地逐層傳遞,主要用于共享那些對于組件樹中許多組件來說是"全局"的數(shù)據(jù),下面小編就來和大家簡單講講Context的用法吧
    2025-01-01
  • ChatGLM?集成LangChain工具詳解

    ChatGLM?集成LangChain工具詳解

    這篇文章主要為大家介紹了Svelte和React框架使用比較,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04

最新評論

尉氏县| 西贡区| 镇安县| 海南省| 鲜城| 丰顺县| 平陆县| 鄂伦春自治旗| 新余市| 竹北市| 贵阳市| 从江县| 林芝县| 永登县| 大庆市| 新安县| 宜宾县| 宁武县| 广灵县| 呼图壁县| 涿州市| 连南| 五寨县| 桑植县| 肇源县| 巴里| 佛山市| 衡阳市| 台东县| 深州市| 马关县| 乐东| 都江堰市| 兴山县| 三河市| 宜章县| 盐池县| 田林县| 神木县| 成安县| 自治县|