2017-08-02 75 views
1

我有一個ScrollView作爲我的視圖的根。在裏面,我展示了一堆文本組件。每個組件都有自己的'ref',因此它們是可訪問的。 現在,我通過一個數字的道具,這個數字告訴我我應該滾動到哪個文本。所以我需要先測量它。我嘗試了這四種方法,但他們每個人只給我未定義的值。 任何想法的人?React Native - 道具收到時測量組件

componentWillReceiveProps(nextProps) { 
 
    //this is a reference to my 'Text' component 
 
    const chapterNo = nextProps.navigation.state.params.chapter; 
 
    const chapterRef = this.refs["chapter" + chapterNo]; 
 

 
    //method 1: 
 
    var RCTUIManager = require('NativeModules').UIManager; 
 
    var handle = ReactNative.findNodeHandle(chapterRef); 
 
    RCTUIManager.measure(handle, (x, y, width, height, pageX, pageY) => { 
 
     console.log(x, y, width, height); 
 
    }); 
 

 
    //method 2: 
 
    NativeMethodsMixin.measure.call(chapterRef, (x, y, width, height) => { 
 
     console.log(x, y, width, height); 
 
    }); 
 

 
    //method 3: 
 
    chapterRef.measure((ox, oy, width, height, px, py) => { 
 
     console.log(ox, oy, width, height); 
 
    }); 
 

 
    //method 4 (same as 3 but with setTimout): 
 
    setTimeout(() => { 
 
     chapterRef.measure((ox, oy, width, height, px, py) => { 
 
      console.log(ox, oy, width, height); 
 
     }); 
 
    }, 0); 
 
}

+0

你確定'chapterRef'指向有效的組件嗎?你應該避免使用字符串作爲參考。他們已被棄用。 –

+0

是的,這是我檢查過的東西,我敢肯定,這個裁判是好的,compoent參考是有效的。 我知道字符串不是最好的,但稍後我會更新,一旦我解決了這個問題。 我發現,測量scrollview內的任何東西都是RN中屁股的痛處... –

回答

3

參見下文

一個例子假設你的滾動視圖的每個項目都有不同的大小(否則它會更簡單):

  • 創建陣列,將收到每個項目的高度。例如在組件的構造函數中。默認情況下它是空的。
  • 使用onLayout屬性獲取scrollView的每個項目的高度(您也可以在屏幕上獲取寬度和確切的x,y位置)。在掛載和佈局更改時調用onLayout:https://facebook.github.io/react-native/docs/view.html#onlayout
  • 在您的回調函數(您調用onLayout的函數)中將此高度與項目的索引一起存儲。你會得到如下例子:this.widthsTab [0] = 312
  • 然後,你只需要通過你的widthsTab來獲取你的元素的確切位置,並滾動到確切的位置。
  • 您還可以移除屏幕高度的一半,以確保元素位於屏幕中間。

對不起,如果它不完全清楚,但我相信你會明白。我會盡快添加一個示例。

編輯:

class HorizontalNavCustomerFlow extends Component { 

    state = { 
    heights: [], 
    totalHeight: 0, 
    heightsChecked: 0, 
    }; 

    componentDidUpdate() { 
    const { currentParagraph } = this.props; // Id of the paragraph you want to scroll to 
    // Compute current item position and scroll when all item heights are computed 
    if (this.state.widthsChecked === HOW_MANY_ITEMS_YOU_HAVE) { // use for example .lenght if you have an array 
     let yposition = 0; 
     const screenHeight = Dimensions.get('window').height; 
     for (let i = 0; i <= currentParagraph; i++) { 
     yposition += this.state.heights[i]; 
     } 
     // Removing half of current element 
     yposition -= this.state.heights[currentParagraph]/2; 
     // And half of screen's height 
     yposition -= screenHeight/2; 
     // Last elements 
     if (yposition > (this.state.totalWidth - screenWidth)) { 
     yposition = this.state.totalHeight - screenHeight; 
     } 
     // Scroll 
     if (yposition > 0) this.refs.MainScrollView.scrollTo({ y: yposition, animated: false }); 
    } 
    } 

    // Render 
    render() { 
    return (
     <View> 
     <ScrollView 
      ref='MainScrollView' 
      showsVerticalScrollIndicator={false} 
     > 

      // ... Your items 
      <View 
      onLayout={(object) => { 
       const { height } = object.nativeEvent.layout; 
       const newState = this.state; 
       newState.heights[index] = width; 
       newState.heightsChecked = this.state.heightsChecked + 1; 
       newState.totalHeight = this.state.totalHeight + height; 
       this.setState(newState); 
      }} 
      > 
      <Text>...</Text> 
      </View> 

     </ScrollView> 
     </View> 
    ); 
    } 
} 

數組的索引可能我關閉的一個,這取決於你從0開始計數或1.您可以隨意+/- 1進行調整。 此外,我刪除了當前項目的一半寬度,因爲我想在它的中間向右滾動,但是如果您想滾動到開頭或此項目或其他內容,請隨時更改。

+0

是的,我一直在挖掘這個主題幾個小時,它看起來像你描述它的方式是唯一可能的方式。 對於高度相同的行,確實很容易,因爲我可以使用FlatList並且它是goToIndex方法。 感謝您的好評。我現在應該可以進一步了。 –

相關問題