Sohbet benzeri bir uygulama için, bir ScrollViewbileşeni en alta kaydırmak istiyorum çünkü en yeni mesajlar eski mesajların altında görünüyor. A'nın kaydırma konumunu ayarlayabilir miyiz ScrollView?
Sohbet benzeri bir uygulama için, bir ScrollViewbileşeni en alta kaydırmak istiyorum çünkü en yeni mesajlar eski mesajların altında görünüyor. A'nın kaydırma konumunu ayarlayabilir miyiz ScrollView?
Yanıtlar:
For Native 0,41 Tepki ve daha sonra , sen ile yapabilirsiniz yerleşik scrollToEndyöntemiyle:
<ScrollView
ref={ref => {this.scrollView = ref}}
onContentSizeChange={() => this.scrollView.scrollToEnd({animated: true})}>
</ScrollView>
rootbaşka türlü kullanmak zorunda kaldım , scrollToEnd tanımsız. yanithis.scrollView.root.scrollToEnd
rootaslında tanımsız bir hata veriyor .
ref={ref => {this.scrollView = ref}}, ödevi geri vermek istemediğiniz için mi olmalı?
Kaydırma görünümünün (yükseklik) alt Y'sini takip etmek için onContentSizeChange'i kullanın
https://facebook.github.io/react-native/docs/scrollview.html#oncontentsizechange
var _scrollToBottomY
<ScrollView
onContentSizeChange={(contentWidth, contentHeight)=>{
_scrollToBottomY = contentHeight;
}}>
</ScrollView>
sonra kaydırma görünümünün ref adını kullanın
this.refs.scrollView.scrollTo(_scrollToBottomY);
İşte toplayabileceğim en basit çözüm:
<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
});
}}
/>;
Hook kullanabilen işlev bileşeni yazan herkes için,
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 })}
/>
);
};
2020 veya daha sonraki bir tarihte herhangi birinin bunu işlevsel bileşenlerle nasıl başaracağını merak etmesi durumunda. Ben böyle yaptım:
ref={ref => scrollView = ref }
onContentSizeChange={() => scrollView.scrollToEnd({ animated: true })}>
bu çözümü dene
xcode 10.0
RN: 56.0.0
<ScrollView ref="scrollView"
onContentSizeChange={(width,height) => this.refs.scrollView.scrollTo({y:height})}> </ScrollView> // OR height - width
ref=? bir web geliştiricisi kalıntısı gibi görünüyor
react-native-invertible-scroll-viewModülü kullanarak kaydırma / liste görünümünü tersine çevirebilir , ardından aşağı ref.scrollTo(0)kaydırmak için aramanız yeterlidir .
Modülü kurun:
npm install --save react-native-invertible-scroll-view
Ardından bileşeni içe aktarın:
import InvertibleScrollView from 'react-native-invertible-scroll-view';
Ardından, a yerine aşağıdaki JSX'i kullanın ScrollView:
<InvertibleScrollView inverted
ref={ref => { this.scrollView = ref; }}
onContentSizeChange={() => {
this.scrollView.scrollTo({y: 0, animated: true});
}}
>
{ /* content */ }
</InvertibleScrollView>
Bu işe react-native-invertible-scroll-viewyarar çünkü tüm görünümün içeriğini çevirir. Görünümün çocuklarının da normal görünümün tersi sırada işleyeceğini unutmayın - ilk çocuk altta görünecektir .
Aslında @Aniruddha cevabı benim için işe yaramadı çünkü kullanıyorum "react-native": "0.59.8"ve this.scrollView.root.scrollToEndtanımsız
ama anladım ve bu işe yarıyor this.scrollView.scrollResponderScrollToEnd({animated: true});
Bunu kullanıyorsanız 0.59.8VEYA daha sonraki sürümü kullanıyorsanız çalışacaktır ve bu sizin için çalışır. Başkalarının sorun yaşamaması için lütfen bu yanıta sürümler ekleyin.
Tam Kod burada
<ScrollView
ref={ref => this.scrollView = ref}
onContentSizeChange={(contentWidth, contentHeight)=>{
this.scrollView.scrollResponderScrollToEnd({animated: true});
}}>
</ScrollView>
Bu yöntem biraz karmaşık ama daha iyi bir yol bulamadım
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>
);
}
scrollToBottomReact Native'in yeni sürümlerinde bu gibi yaklaşımları geçersiz kılar.
Sorunuzun cevabı budur: https://stackoverflow.com/a/39563100/1917250
İçeriğin yüksekliği eksi kaydırma Görünümünün yüksekliğini hesaplayarak sürekli olarak sayfanın altına kaydırmaya devam etmeniz gerekir.
TypeScript kullanıyorsanız Bunu yapmanız gerekir
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>
Bir süre bununla savaştım ve sonunda benim için gerçekten iyi çalışan ve sorunsuz bir şey buldum. Birçokları gibi ben de .scrollToEndboşuna uğraştım. Benim için çalıştı çözüm bir arada oldu onContentSizeChange,onLayout sahne donanımı ve biraz daha görsel olarak "aşağıya kaydırmanın" gerçekte ne anlama geldiğini düşünmekti. Son kısım şimdi benim için önemsiz görünüyor, ama anlamam sonsuza kadar sürdü.
ScrollViewSabit bir yüksekliğe sahip olduğu göz önüne alındığında , içerik yüksekliği konteynerin yüksekliğini aştığında, ofseti için prevHeight(sabit yüksekliğini ScrollView) çıkararak hesapladım .currHeight (içerik yükseklik). Görsel olarak hayal edebiliyorsanız, y eksenindeki bu farka kaydırarak, içerik yüksekliğini bu uzaklık kadar kapsayıcı üzerinde kaydırır. Ofsetimi artırdım ve şimdi mevcut içerik yüksekliğimi önceki boyum haline getirdim ve yeni bir ofset hesaplamaya devam ettim.
İşte kod. Umarım birine yardımcı olur.
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>
);
}
}
Sanırım cevap vermek için çok geç ama bir hack'im var! Eğer kullanırsanız FlatListetkinleştirebilir invertedayarı geri düşer özelliği transform scaleiçin -1(gibi diğer liste bileşenleri için kabul edilebilir olan ScrollView...). Eğer render zaman FlatListverilerle her zaman altta olacak!
Kaydırma görünümünün contentOffset özelliğini içeriğin mevcut yüksekliğine ayarlamayı deneyin .
İhtiyaç duyduğunuz şeyi başarmak için bunu onScroll etkinliğinin bir parçası olarak yapabilirsiniz. Ancak bu, kötü bir kullanıcı deneyimine neden olabilir, bu nedenle bunu yalnızca yeni bir mesaj eklendiğinde yapmak daha kullanıcı dostu olabilir.
ScrollViewiçin aşağı aşağıda içeriğinin tümü yerine sadece altına kaydırma.
Benzer bir sorun yaşadım, ancak bu sayfayı okuduktan sonra (ki bu bana bir baş ağrısı veriyor!) ListView'ı tersine çeviren ve bir sohbet uygulaması için her şeyi kolaylaştıran bu çok güzel npm paketini buldum !!
ScrollView"ListView" ile ilgili değildir).
Biraz geç ... ama şu soruya bir bakın. ScrollView'ın üstüne kaydırın
ScrollView bir "scrollTo" yöntemine sahiptir.