我正在使用一个转盘库(使用FlatList(在React Native中拖动东西。
我有这个旋转木马:
import * as React from "react";
import Carousel from "react-native-reanimated-carousel";
import Card from "components/cards/Card";
function CardCarousel(props) {
return (
<Carousel
scrollAnimationDuration={200}
width={300}
windowSize={9}
moveSize={5}
style={{
width: 2000,
height: 300,
}}
data={props.articleGroup.data}
renderItem={(article, index) => (
<Card
article={article.item}
key={index + "-main-" + props.articleGroup.category}
/>
)}
/>
);
}
export default CardCarousel;
然后我的卡片看起来是这样的:
const Card = (props) => {
const [bookmark, setBookmark] = useState(props.article.bookmark);
const cdnURL = wrapImgCDN(props.article.image, 400);
const routeChange = async (event) => {
... code to change route
};
const _bookmarkToggle = () => {
bookmarkToggle(props.article);
setBookmark(!bookmark);
};
return (
<Pressable
onPress={routeChange}
>
<WhiteCard
{...props}
_bookmarkToggle={_bookmarkToggle}
cdnURL={cdnURL}
bookmark={bookmark}
/>
</Pressable>
);
};
当我拖动平面列表时,如果我抓住其中一个<Card />
项目,它会点击并更改到给定卡片的路线,但我不想允许用户点击卡片,除非滚动停止/用户根本没有拖动。
我该怎么做?
由于您正在将carousel
的渲染项目包装到Pressable
中,并在其onPress
功能中激发routeChange
,因此只要您按下转盘中的其中一个项目,它就会更改路线。
我们可以使用react原生重新激活的转盘组件的onSnapToItem
回调函数。此函数作为道具传递给组件,一旦FlatList中的项目"捕捉",就会立即调用。它接收将被捕捉的项目的索引。我们可以将其与当前项进行比较,每当它发生变化时,我们都会向Card
组件传递一个布尔属性。
可以像往常一样通过getCurrentIndex
功能使用ref
来访问current index
。
请注意,这需要一个附加状态。但是,只有当项目实际发生了更改,即新项目snapped into position
时,我们才会更改状态。
布尔状态对于当前捕捉的项将为true,对于其他项将为false。我们对Card
组件中useEffect
中的fireRouteChange
道具变化作出反应。
function CardCarousel(props) {
const ref = React.useRef(null);
const [currentIndex, setCurrentIndex] = React.useState(0);
return (
<Carousel
ref={ref}
onSnapToItem={(index) => index !== ref.current.getCurrentIndex() && setCurrentIndex(index)}
scrollAnimationDuration={200}
width={300}
windowSize={9}
moveSize={5}
style={{
width: 2000,
height: 300,
}}
data={props.articleGroup.data}
renderItem={(article, index) => (
<Card
article={article.item}
fireRouteChange={currentIndex === index}
key={index + "-main-" + props.articleGroup.category}
/>
)}
/>
);
}
const Card = (props) => {
const [bookmark, setBookmark] = useState(props.article.bookmark);
const cdnURL = wrapImgCDN(props.article.image, 400);
React.useEffect(() => {
if(props.fireRouteChange) {
... code to change route
}
}, [props.fireRouteChange])
const _bookmarkToggle = () => {
bookmarkToggle(props.article);
setBookmark(!bookmark);
};
return (
<WhiteCard
{...props}
_bookmarkToggle={_bookmarkToggle}
cdnURL={cdnURL}
bookmark={bookmark}
/>
);
};
假设:routeChange
函数可以位于CardCarousel
如果我们假设routeChange
函数可以位于CardCarousel
中,则可以使这一点更简单。我无法访问此功能的实现细节,因此我通过做出此假设将其包含在此处。
function CardCarousel(props) {
const ref = React.useRef(null);
function routeChange(index) {
... code to change route of the current snapped index
};
return (
<Carousel
ref={ref}
onSnapToItem={(index) => index !== ref.current.getCurrentIndex() && fireRouteChange(index)}
scrollAnimationDuration={200}
width={300}
windowSize={9}
moveSize={5}
style={{
width: 2000,
height: 300,
}}
data={props.articleGroup.data}
renderItem={(article, index) => (
<Card
article={article.item}
fireRouteChange={currentIndex === index}
key={index + "-main-" + props.articleGroup.category}
/>
)}
/>
);
}
const Card = (props) => {
const [bookmark, setBookmark] = useState(props.article.bookmark);
const cdnURL = wrapImgCDN(props.article.image, 400);
const _bookmarkToggle = () => {
bookmarkToggle(props.article);
setBookmark(!bookmark);
};
return (
<WhiteCard
{...props}
_bookmarkToggle={_bookmarkToggle}
cdnURL={cdnURL}
bookmark={bookmark}
/>
);
};
在用户滚动时禁用onPress
功能
如果您想在用户滚动时禁用onPress
功能,而只在转盘捕捉到位时才允许使用,则可以使用状态以及onScrollBegin
和onScollEnd
功能。
function CardCarousel(props) {
const [allowRouteChange, setAllowRouteChange] = useState(true)
return (
<Carousel
scrollAnimationDuration={200}
width={300}
windowSize={9}
moveSize={5}
onScrollBegin={() => setAllowRouteChange(false)}
onScrollEnd={() => setAllowRouteChange(true)}
style={{
width: 2000,
height: 300,
}}
data={props.articleGroup.data}
renderItem={(article, index) => (
<Card
allowRouteChange={allowRouteChange}
article={article.item}
key={index + "-main-" + props.articleGroup.category}
/>
)}
/>
);
}
const Card = (props) => {
const [bookmark, setBookmark] = useState(props.article.bookmark);
const cdnURL = wrapImgCDN(props.article.image, 400);
const routeChange = async (event) => {
if (props.allowRouteChange) {
... code to change route
}
};
const _bookmarkToggle = () => {
bookmarkToggle(props.article);
setBookmark(!bookmark);
};
return (
<Pressable
onPress={routeChange}
>
<WhiteCard
{...props}
_bookmarkToggle={_bookmarkToggle}
cdnURL={cdnURL}
bookmark={bookmark}
/>
</Pressable>
);
};