[英]react native - how to play sound on scroll
I am using pure js scrolling picker in React native and it works great on ios and on android:)我在 React native 中使用纯 js 滚动选择器,它在 ios 和 android 上运行良好:)
I want to add some sound or vibration to each scroll so it will be more user friendly我想为每个滚动添加一些声音或振动,这样会更加用户友好
I did not find a way to do it anyone knows how it can be done and if you have any recommendation for a sound and source to download from?我没有找到一种方法来做到这一点,任何人都知道如何做到这一点,如果您对声音和来源有什么建议可以下载?
import React from "react";
import styled from "styled-components";
import {
View,
Text,
ScrollView,
Dimensions,
Platform,
StyleSheet,
} from "react-native";
import PropTypes from "prop-types";
import Responsive from "../responsive";
const Container = styled.View`
height: ${(props) => props.wrapperHeight}px;
flex: 1;
overflow: hidden;
align-self: center;
width: ${(props) => props.wrapperWidth}px;
background-color: ${(props) => props.wrapperBackground};
`;
export const HighLightView = styled.View`
position: absolute;
top: ${(props) => (props.wrapperHeight - props.itemHeight).toFixed(0) / 2}px;
height: ${(props) => props.itemHeight}px;
width: ${(props) => props.highlightWidth}px;
border-top-color: ${(props) => props.highlightColor};
border-bottom-color: ${(props) => props.highlightColor};
border-top-width: ${(props) => props.highlightBorderWidth}px;
border-bottom-width: ${(props) => props.highlightBorderWidth}px;
`;
export const SelectedItem = styled.View`
height: 30px;
justify-content: center;
align-items: center;
height: ${(props) => props.itemHeight}px;
`;
const deviceWidth = Dimensions.get("window").width;
export default class ScrollPicker extends React.Component {
constructor() {
super();
this.onMomentumScrollBegin = this.onMomentumScrollBegin.bind(this);
this.onMomentumScrollEnd = this.onMomentumScrollEnd.bind(this);
this.onScrollBeginDrag = this.onScrollBeginDrag.bind(this);
this.onScrollEndDrag = this.onScrollEndDrag.bind(this);
this.state = {
selectedIndex: 1,
};
}
componentDidMount() {
if (typeof this.props.selectedIndex !== "undefined") {
this.scrollToIndex(this.props.selectedIndex);
}
}
componentWillUnmount() {
if (this.timer) {
clearTimeout(this.timer);
}
}
componentDidUpdate(prevProps) {
// Typical usage (don't forget to compare props):
if (this.props.selectedIndex !== prevProps.selectedIndex) {
this.scrollToIndex(this.props.selectedIndex);
}
}
render() {
const { header, footer } = this.renderPlaceHolder();
return (
<Container
wrapperHeight={this.props.wrapperHeight}
wrapperWidth={this.props.wrapperWidth}
wrapperBackground={this.props.wrapperBackground}
>
<HighLightView
highlightColor={this.props.highlightColor}
highlightWidth={this.props.highlightWidth}
wrapperHeight={this.props.wrapperHeight}
itemHeight={this.props.itemHeight}
highlightBorderWidth={this.props.highlightBorderWidth}
/>
<ScrollView
ref={(sview) => {
this.sview = sview;
}}
bounces={true}
showsVerticalScrollIndicator={false}
onTouchStart={this.props.onTouchStart}
onMomentumScrollBegin={this.onMomentumScrollBegin}
onMomentumScrollEnd={this.onMomentumScrollEnd}
onScrollBeginDrag={this.onScrollBeginDrag}
onScrollEndDrag={this.onScrollEndDrag}
>
{header}
{this.props.dataSource.map(this.renderItem.bind(this))}
{footer}
</ScrollView>
</Container>
);
}
renderPlaceHolder() {
const height = (this.props.wrapperHeight - this.props.itemHeight) / 2;
const header = <View style={{ height, flex: 1 }}></View>;
const footer = <View style={{ height, flex: 1 }}></View>;
return { header, footer };
}
renderItem(data, index) {
const isSelected = index === this.state.selectedIndex;
const item = (
<Text
style={
isSelected ? this.props.activeItemTextStyle : this.props.itemTextStyle
}
>
{data}
</Text>
);
return (
<SelectedItem key={index} itemHeight={this.props.itemHeight}>
{item}
</SelectedItem>
);
}
scrollFix(e) {
let verticalY = 0;
const h = this.props.itemHeight;
if (e.nativeEvent.contentOffset) {
verticalY = e.nativeEvent.contentOffset.y;
}
const selectedIndex = Math.round(verticalY / h);
const verticalElem = selectedIndex * h;
if (verticalElem !== verticalY) {
// using scrollTo in ios, onMomentumScrollEnd will be invoked
if (Platform.OS === "ios") {
this.isScrollTo = true;
}
if (this.sview) {
this.sview.scrollTo({ y: verticalElem });
}
}
if (this.state.selectedIndex === selectedIndex) {
return;
}
this.setState({
selectedIndex,
});
// onValueChange
if (this.props.onValueChange) {
const selectedValue = this.props.dataSource[selectedIndex];
this.props.onValueChange(selectedValue, selectedIndex);
}
}
onScrollBeginDrag() {
this.dragStarted = true;
if (Platform.OS === "ios") {
this.isScrollTo = false;
}
if (this.timer) {
clearTimeout(this.timer);
}
}
onScrollEndDrag(e) {
this.props.onScrollEndDrag();
this.dragStarted = false;
// if not used, event will be garbaged
const element = {
nativeEvent: {
contentOffset: {
y: e.nativeEvent.contentOffset.y,
},
},
};
if (this.timer) {
clearTimeout(this.timer);
}
this.timer = setTimeout(() => {
if (!this.momentumStarted && !this.dragStarted) {
this.scrollFix(element, "timeout");
}
}, 10);
}
onMomentumScrollBegin() {
this.momentumStarted = true;
if (this.timer) {
clearTimeout(this.timer);
}
}
onMomentumScrollEnd(e) {
this.props.onMomentumScrollEnd();
this.momentumStarted = false;
if (!this.isScrollTo && !this.momentumStarted && !this.dragStarted) {
this.scrollFix(e);
}
}
scrollToIndex(ind) {
this.setState({
selectedIndex: ind,
});
const y = this.props.itemHeight * ind;
setTimeout(() => {
if (this.sview) {
this.sview.scrollTo({ y });
}
}, 0);
}
}
ScrollPicker.propTypes = {
style: PropTypes.object,
dataSource: PropTypes.array,
selectedIndex: PropTypes.number,
onValueChange: PropTypes.func,
renderItem: PropTypes.func,
highlightColor: PropTypes.string,
itemHeight: PropTypes.number,
wrapperBackground: PropTypes.string,
wrapperWidth: PropTypes.number,
wrapperHeight: PropTypes.number,
highlightWidth: PropTypes.number,
highlightBorderWidth: PropTypes.number,
itemTextStyle: PropTypes.object,
activeItemTextStyle: PropTypes.object,
onMomentumScrollEnd: PropTypes.func,
onScrollEndDrag: PropTypes.func,
};
ScrollPicker.defaultProps = {
dataSource: [1, 2, 3],
itemHeight: 60,
wrapperBackground: "#fff",
wrapperHeight: 180,
wrapperWidth: 150,
highlightWidth: deviceWidth,
highlightBorderWidth: 2,
highlightColor: "#fff",
onMomentumScrollEnd: () => {},
onScrollEndDrag: () => {},
itemTextStyle: {
fontSize: Responsive.font(20),
lineHeight: 26,
textAlign: "center",
color: "#fff",
fontWeight: "bold",
opacity: 0.1,
},
activeItemTextStyle: {
fontSize: Responsive.font(20),
lineHeight: 26,
textAlign: "center",
color: "#fff",
fontWeight: "bold",
},
};
To play sound on scroll you just need to use a library called react-native-sound https://www.npmjs.com/package/react-native-sound要在滚动上播放声音,您只需要使用一个名为 react-native-sound https://www.npmjs.com/package/react-native-sound的库
in this library there are several actions available like在这个库中,有几个可用的操作,例如
you just need to trigger required actions from above, when user scroll the page, for that you can simply use ScrollView's props like当用户滚动页面时,您只需要从上面触发所需的操作,因为您可以简单地使用 ScrollView 的道具,例如
I hope you can get your desired result我希望你能得到你想要的结果
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.