क्या स्क्रॉल स्क्रॉल को नीचे तक रखना संभव है?


87

चैट जैसी ऐप के लिए, मैं एक ScrollViewघटक को नीचे तक स्क्रॉल करना चाहता हूं , क्योंकि पुराने वाले के तहत नवीनतम संदेश दिखाई देते हैं। क्या हम स्क्रॉल की स्थिति को समायोजित कर सकते हैं ScrollView?


3
मैं प्रतिक्रिया-मूल के बारे में कुछ नहीं जानता, लेकिन कभी-कभी ध्यान रखें कि उपयोगकर्ता चैट इतिहास देखने के लिए स्क्रॉल करना चाहते हैं। यदि कोई नया संदेश आने पर चैट को पहले ही नीचे तक सभी तरह से स्क्रॉल कर दिया गया था, तो केवल चैट को स्क्रॉल करना सुनिश्चित करें।
डेविड

यह एक अच्छा विचार है। हम इस मुद्दे को यहाँ ट्रैक कर रहे हैं: github.com/facebook/react-native/issues/107
एरिक विसेंटी

मैंने सिर्फ एक समान प्रश्न का उत्तर दिया है, कृपया इसे यहाँ देखें - stackoverflow.com/a/32652967/1541508
कोहवर

क्या इससे आपके सवाल का जवाब मिलता है? कैसे
रिएक्टिव

जवाबों:


165

0.41 रीऐक्टिव नेटिव के लिए और बाद में , आप इसे बिल्ट-इन scrollToEndविधि से कर सकते हैं :

<ScrollView
    ref={ref => {this.scrollView = ref}}
    onContentSizeChange={() => this.scrollView.scrollToEnd({animated: true})}>
</ScrollView>

3
देशी 0.55.4 और अधिक प्रतिक्रिया से, मुझे rootअन्यथा का उपयोग करना पड़ा, स्क्रॉलटंड अपरिभाषित है। अर्थातthis.scrollView.root.scrollToEnd
साइमन

4
वर्तमान में प्रतिक्रिया 0.58.6 का उपयोग करते हुए और rootवास्तव में एक अपरिभाषित त्रुटि फेंकता है।
जोस बर्नहार्ट

1
यह होना चाहिए: ref={ref => {this.scrollView = ref}}जैसा कि आप असाइनमेंट को वापस नहीं करना चाहते हैं
हम्पाइकल्क

25

स्क्रॉल दृश्य (ऊंचाई) के नीचे Y का ट्रैक रखने के लिए onContentSizeChange का उपयोग करें

https://facebook.github.io/react-native/docs/scrollview.html#oncontentsizechange

var _scrollToBottomY

<ScrollView
    onContentSizeChange={(contentWidth, contentHeight)=>{
    _scrollToBottomY = contentHeight;
    }}>
</ScrollView>

फिर स्क्रॉल दृश्य के रेफरी नाम का उपयोग करें

this.refs.scrollView.scrollTo(_scrollToBottomY);

2
ध्यान दें कि यह दृश्य को पूरी तरह से नीचे तक स्क्रॉल करता है, इसलिए दृश्य अनिवार्य रूप से दिखाई नहीं देता है (जब तक कि आपने माप के बाद इसमें कुछ नहीं जोड़ा)। यह समझ में आता है क्योंकि कोड स्क्रॉल करने योग्य क्षेत्र की ऊंचाई तक स्क्रॉल करता है, स्क्रॉल करने योग्य क्षेत्र के अतिप्रवाह वाले बच्चों की ऊंचाई तक नहीं (शायद ओपी नहीं चाहता था)। इसके बजाय stackoverflow.com/a/39563193/1526986 देखें ।
xixixao

20

यहाँ सबसे सरल समाधान है जो मैं कर सकता था:

 <ListView
ref={ref => (this.listView = ref)}
onLayout={event => {
    this.listViewHeight = event.nativeEvent.layout.height;
}}
onContentSizeChange={() => {
    this.listView.scrollTo({
        y: this.listView.getMetrics().contentLength - this.listViewHeight
    });
}}
/>;

1
जब मैं इस या अन्य समान उत्तरों का उपयोग करता हूं, तो यह सूची में आइटम को गायब कर देता है (ऐसा लगता है कि यह बहुत दूर स्क्रॉल कर रहा है, लेकिन मुझे यकीन नहीं हो सकता है)। एक छोटे से बिट को स्क्रॉल करना सब कुछ फिर से प्रकट करता है, और इस तरह का दिखता है कि यह वापस देखने में फिसल रहा है (इसलिए स्क्रॉल बहुत दूर सिद्धांत)। किसी भी स्पष्ट विचार क्यों हो सकता है?
tscizzle

11

किसी भी फ़ंक्शन फ़ंक्शन के लिए हुक का उपयोग कर सकते हैं,

import React, { useRef } from 'react';
import { ScrollView } from 'react-native';

const ScreenComponent = (props) => {
  const scrollViewRef = useRef();
  return (
    <ScrollView
      ref={scrollViewRef}
      onContentSizeChange={() => scrollViewRef.current.scrollToEnd({ animated: true })}
    />
  );
};

5

इस समाधान का प्रयास करें

xcode 10.0

आरएन: 56.0.0

<ScrollView ref="scrollView"
             onContentSizeChange={(width,height) => this.refs.scrollView.scrollTo({y:height})}>  </ScrollView> // OR height -  width

क्यों ref=? एक वेब देव अवशेष की तरह लगता है
युंगगुन

5

मामले में किसी को भी 2020 या बाद में सोच रहा है कि कार्यात्मक घटकों के साथ इसे कैसे प्राप्त किया जाए। मैंने ऐसा किया है:

ref={ref => scrollView = ref }
onContentSizeChange={() => scrollView.scrollToEnd({ animated: true })}>

नोट: आप उल्लेख कर सकते हैं कि आप useref का उपयोग कर रहे हैं। अधिकांश पीपीएल को हुक के साथ रेफरी का उपयोग करना नहीं पता है।
ʎzʎ

हाँ। बात यह है कि यह तब भी काम किया जब तक कि useRef हुक का उपयोग नहीं किया। लेकिन इसका उपयोग करने का सही तरीका है! आप सही कह रहे हैं
Marlon Englemam

4

आप react-native-invertible-scroll-viewमॉड्यूल का उपयोग करके स्क्रॉल / सूची दृश्य को उल्टा कर सकते हैं , फिर बस कॉल कर सकते हैंref.scrollTo(0) नीचे स्क्रॉल करने के लिए ।

मॉड्यूल स्थापित करें:

npm install --save react-native-invertible-scroll-view

फिर घटक आयात करें:

import InvertibleScrollView from 'react-native-invertible-scroll-view';

इसके बाद निम्न JSX का उपयोग करें ScrollView:

<InvertibleScrollView inverted
    ref={ref => { this.scrollView = ref; }}
    onContentSizeChange={() => {
        this.scrollView.scrollTo({y: 0, animated: true});
    }}
>
    { /* content */ }
</InvertibleScrollView>

यह काम करता है क्योंकि react-native-invertible-scroll-viewपूरे दृश्य की सामग्री को फ़्लिप करता है। ध्यान दें कि दृश्य के बच्चे एक सामान्य दृश्य के विपरीत क्रम में भी प्रस्तुत करेंगे - पहला बच्चा सबसे नीचे दिखाई देगा ।


3

दरअसल @ अनिरुद्ध जवाब मेरे लिए काम नहीं करता क्योंकि मैं उपयोग कर रहा हूं "react-native": "0.59.8"और this.scrollView.root.scrollToEndअपरिभाषित भी

लेकिन मुझे यह समझ में आया और यह काम करता है this.scrollView.scrollResponderScrollToEnd({animated: true});

यदि आप उपयोग कर रहे हैं 0.59.8 तो आप काम करेंगे या यदि आप बाद के संस्करण का उपयोग कर रहे हैं और यह आपके लिए काम करता है। कृपया इस उत्तर में संस्करण जोड़ें ताकि दूसरों को परेशानी न हो।

यहां पूरा कोड

<ScrollView
    ref={ref => this.scrollView = ref}
    onContentSizeChange={(contentWidth, contentHeight)=>{        
        this.scrollView.scrollResponderScrollToEnd({animated: true});
    }}>
</ScrollView>

1

यह तरीका थोड़ा आसान है, लेकिन मैं इससे बेहतर तरीका नहीं खोज सकता

  1. सबसे पहले अपने ScrollView में एक रेफरी जोड़ें।
  2. अपना स्क्रॉल दृश्य टैग बंद करने से पहले दूसरा एक डमी दृश्य जोड़ें
  3. उस डमी दृश्य की y स्थिति प्राप्त करें
  4. जब भी आप डमी व्यू की स्थिति तक नीचे स्क्रॉल करना चाहते हैं

var footerY; //Y position of the dummy view
render() {    
    return (
      <View>
          <ScrollView 
          ref='_scrollView'>
            // This is where all the things that you want to display in the scroll view goes
            
            // Below is the dummy View
            <View onLayout={(e)=> {
              footerY = e.nativeEvent.layout.y;
              }}/>
          </ScrollView>
              
          //Below is the button to scroll to the bottom    
          <TouchableHighlight
            onPress={() => { this.refs._scrollView.scrollTo(footerY); }}>
            <Text>Scroll to Bottom</Text>
          </TouchableHighlight>
        
      </View>
    );
  }


यह वह नहीं है जो मांगा गया था; यह स्क्रॉल को टैप पर नीचे की ओर स्क्रॉल करता है, बजाय स्क्रॉल स्क्रॉल किए हुए नीचे रखने के बजाय सामग्री को जोड़ा जाता है। वैसे भी, scrollToBottomप्रतिक्रियाशील मूल के नए संस्करणों में इस तरह के अप्रचलित बनाता है।
मार्क अमेरी

1

यह आपके प्रश्न का उत्तर देता है: https://stackoverflow.com/a/39563100/1917250

आपको अपने स्क्रॉलव्यू की ऊंचाई की सामग्री की ऊंचाई की गणना करके पृष्ठ के निचले भाग तक लगातार स्क्रॉल करने की आवश्यकता है।


यह प्रश्न का सही उत्तर है। आप स्क्रॉल करने के बारे में स्मार्ट हो सकते हैं, लिंक में उत्तर आपको दिखाता है कि आपको आवश्यक संख्या कैसे प्राप्त करनी है। विशेष रूप से, यदि आप सूची में घटकों को जोड़ रहे हैं, तो घटक की ऊँचाई को तब शामिल नहीं किया जाएगा जब घटकडिपडडेट कहा जाता है, इसलिए आप यह याद रखना चाहते हैं कि आप स्क्रॉल करना चाहते हैं और ऑन-कॉन्टेंटसाइजेज को बदले में स्क्रॉल करना चाहते हैं।
xixixao

1

यदि आप टाइपस्क्रिप्ट का उपयोग करते हैं तो आपको यह करने की आवश्यकता है

interface Props extends TextInputProps { 
     scrollRef?: any;
}

export class Input extends React.Component<Props, any> {
     scrollRef;
constructor(props) {
    this.scrollRef = React.createRef();
}
<ScrollView
    ref={ref => (this.scrollRef = ref)}
    onContentSizeChange={() => {
    this.scrollRef.scrollToEnd();
    }}
>
</ScrollView>

0

मैं इसके साथ कुछ समय तक लड़ता रहा और आखिरकार कुछ ऐसा हुआ जो मेरे लिए बहुत अच्छा और आसान काम था। कई की तरह, मैंने कोशिश की.scrollToEnd कोई फायदा नहीं उठाया। मेरे लिए जो समाधान काम करता था onContentSizeChange, उसका एक संयोजन था ,onLayout रंगमंच की सामग्री और "थोड़ा नीचे स्क्रॉल करने के लिए" वास्तव में क्या मतलब है के बारे में थोड़ा और अधिक सोच। आखिरी हिस्सा अब मुझे मामूली लगता है, लेकिन मुझे हमेशा के लिए पता लग गया।

यह देखते हुए कि ScrollViewएक निश्चित ऊँचाई है, जब सामग्री की ऊँचाई कंटेनर की ऊँचाई से अधिक हो जाती है, तो मैंने prevHeight(की निश्चित ऊँचाई) घटाकर ऑफसेट की गणना कीScrollViewcurrHeight (सामग्री की ऊंचाई) के ) । यदि आप नेत्रहीन रूप से इसकी कल्पना कर सकते हैं, तो y- अक्ष में उस अंतर तक स्क्रॉल करना, उस ऑफसेट द्वारा इसके कंटेनर पर सामग्री की ऊँचाई को स्लाइड करता है। मैंने अपने ऑफसेट को बढ़ाया और अपनी वर्तमान सामग्री को मेरी पिछली ऊंचाई से बनाया और एक नई ऑफसेट की गणना करता रहा।

यहाँ कोड है। आशा है कि यह किसी की मदद करता है।

class ChatRoomCorrespondence extends PureComponent {
  currHeight = 0;
  prevHeight = 0;
  scrollHeight = 0;

  scrollToBottom = () => {
    this.refs.scrollView.getScrollResponder().scrollResponderScrollTo({
      x: 0,
      y: this.scrollHeight,
      animated: true
    });
  };

  render() {
    return (
      <ScrollView
        style={Styles.container}
        ref="scrollView"
        onContentSizeChange={(w, h) => {
          this.currHeight = h;

          if (
            this.prevHeight > 0 &&
            this.currHeight - this.scrollHeight > this.prevHeight
          ) {
            this.scrollHeight += this.currHeight - this.prevHeight;
            console.log("--------------------------------------------");
            console.log("Curr: ", this.currHeight);
            console.log("Prev: ", this.prevHeight);
            console.log("Scroll: ", this.scrollHeight);
            this.prevHeight = this.currHeight;
            console.log("PREV: ", this.prevHeight);
            console.log("--------------------------------------------");

            this.scrollToBottom();
          }
        }}
        onLayout={ev => {
          // Fires once
          const fixedContentHeight = ev.nativeEvent.layout.height;
          this.prevHeight = fixedContentHeight;
        }}
      >
        <FlatList
          data={this.props.messages}
          renderItem={({ item }) => (
            <ChatMessage
              text={item.text}
              sender={item.sender}
              time={item.time}
              username={this.props.username}
            />
          )}
          keyExtractor={(item, index) => index.toString()}
        />
      </ScrollView>
    );
  }
}

0

मुझे लगता है कि उत्तर देने में बहुत देर हो चुकी है लेकिन मुझे एक हैक मिल गया है! यदि आप उपयोग करते हैं FlatListतो आप उस invertedसंपत्ति को सक्षम कर सकते हैं जो सेटिंग में वापस आती transform scaleहै -1(जो अन्य सूची घटकों जैसे ScrollView...) के लिए स्वीकार्य है । जब आप अपने FlatListडेटा के साथ प्रस्तुत करते हैं तो यह हमेशा तल पर होगा!


-1

सामग्री की वर्तमान ऊंचाई तक स्क्रॉल दृश्य की सामग्री को सेट करने का प्रयास करें ।

यह सुनिश्चित करने के लिए कि ऑनस्क्राॅल इवेंट के हिस्से के रूप में आपको क्या चाहिए। हालाँकि यह एक बुरे उपयोगकर्ता अनुभव के लिए हो सकता है इसलिए यह एक नया संदेश संलग्न होने पर केवल ऐसा करने के लिए अधिक उपयोगकर्ता के अनुकूल साबित हो सकता है।


-1; नहीं। यहां कई उत्तरों की तरह, इसमें स्क्रॉलिंग का प्रभाव हैScrollView करने के लिए नीचे नीचे इसकी समस्त सामग्री, बजाय सिर्फ निचले हिस्से तक स्क्रॉल।
मार्क अमेरी

-1

मुझे भी इसी तरह की समस्या थी, लेकिन इस पृष्ठ को पढ़ने के बाद (जो मुझे सिरदर्द देता है!) मुझे यह बहुत अच्छा npm पैकेज लगता है जो सिर्फ ListView को उल्टा करता है और एक चैट एप्लिकेशन के लिए सब कुछ आसान बनाता है !!


-1; यह यहां पहले से पोस्ट किए गए उत्तर को दोहराता है (और थोड़ा भ्रमित भी है; यह प्रश्न एक के बारे में है ScrollView, न कि `सूची दृश्य`)।
मार्क ऐमी

-3

थोड़ी देर ... लेकिन इस सवाल पर गौर करें। स्क्रॉल के शीर्ष पर स्क्रॉल करें

स्क्रॉलव्यू में एक "स्क्रोल्टो" विधि है।


1
हां स्क्रोलव्यू पर एक स्क्रॉलो विधि है, लेकिन सवाल विशेष रूप से नीचे तक स्क्रॉल करने के बारे में पूछ रहा है, जो सीधा नहीं है।
Southerneer
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.