React Native中的自定义形状按钮

时间:2019-01-15 16:35:07

标签: react-native

我正在尝试在React Native中创建一个自定义形状的按钮。它们大部分是四边形,但是它们是从自定义路径渲染的。为了生成它们,我目前使用React Native Art模块并传递自定义路径:

import React, { Component } from 'react'
import { ScrollView, Text, TouchableOpacity, View, Alert, Dimensions, ART, StyleSheet } from 'react-native'
import { connect } from 'react-redux'
import { Images } from '../Themes'
import Video from 'react-native-video';

type Props = {
  behind: React.Component,
  front: React.Component,
  under: React.Component
}

const {
  Surface,
  Group,
  Shape,
  Path,
} = ART;
// Add Actions - replace 'Your' with whatever your reducer is called :)
// import YourActions from '../Redux/YourRedux'

//receive paths from server
//draw these paths

// Styles

var b1 = [[123,110],[380,110],[480,232],[22,232]]
var b2 = [[123,109],[163,63],[340,63],[380,109]]

let b1Path = makePath(b1)
let b2Path = makePath(b2)

function makePath(coords){
  let path = new Path();
  path.moveTo(coords[0][0],coords[0][1])
  path.lineTo(coords[0][0],coords[0][1]);
  path.lineTo(coords[1][0],coords[1][1]);
  path.lineTo(coords[2][0],coords[2][1]);
  path.lineTo(coords[3][0],coords[3][1]);
  path.close();
  return path;
}

class GameScreen extends Component {
  _onPressHighlight() {
    Alert.alert('You tapped the button!')
  }
  render() {
    const { behind, front, under } = this.props

    return (
      <View style={styles.container}>
        <View style={styles.behind}>
          <Video source={require('./DGE.mp4')}   // Can be a URL or a local file.
          ref={(ref) => { this.player = ref }}
          resizeMode="cover"
          style={{width: 500, height: 300}}                                   // Store reference
          />
        </View>
        <View style={styles.behind}>
          <Surface width={500} height={300}>
            <Group>
              <Shape
                d={ b1Path}
                stroke="white"
                strokeWidth={1}
                fill='yellow'
                opacity='0.3'
              />
              <Shape
                d={ b2Path}
                stroke="white"
                strokeWidth={1}
                fill='blue'
                opacity='0.3'
              />
            </Group>
          </Surface>
        </View>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    height: 100,
    justifyContent: 'center',
  },
  behind: {
    alignItems: 'center',
    justifyContent: 'center',
    position: 'absolute',
    left: 0,
    top: 0,
    width: '100%',
    height: '100%'
  }
})

const mapStateToProps = (state) => {
  return {
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(GameScreen)

我并不特别在意使用React Native Art模块,这只是我发现使用自定义形状的唯一方法。我自然希望将它们包装在一个TouchableOpacity对象中,但这是不允许的,如果将TouchableOpacity对象放在其中,则会完全崩溃xcode。

我知道您可以使用css hacks来制作自定义四边形,但是这样做的问题是透明区域也会触发onPress,这意味着按钮形状不准确。同样,如果将TouchableOpactiy放在整个组件周围。

理想情况下,我想这样做,但这是无效的:

      <Surface width={500} height={300}>
        <Group>
          <TouchableOpacity>
            <Shape
              d={ b1Path}
              stroke="white"
              strokeWidth={1}
              fill='yellow'
              opacity='0.3'
            />
          </TouchableOpacity>
          <TouchableOpacity>
            <Shape
              d={ b2Path}
              stroke="white"
              strokeWidth={1}
              fill='blue'
              opacity='0.3'
            />
          </TouchableOpacity>
        </Group>
      </Surface>

0 个答案:

没有答案