web-dev-qa-db-fra.com

Réagissez aux événements Touch natifs en passant par la vue absolue

J'utilise react-navigation et j'ai une vue que je veux montrer quand une icône est appuyée dans la barre d'outils, je l'ai déjà faite en utilisant un autre composant et en configurant le composant pour qu'il soit affiché en absolu, le fait est que tous les événements tactiles sont en passant par la vue de superposition, j'ai essayé de définir zIndex et élévation à la fois sur headerRightStyle, la vue absolue, même dans une autre vue d'enfants . J'ai également essayé d'utiliser TouchableWithoutFeedback comme wrapper mais cela n'a pas résolu le problème non plus.

C'est ma composante

import React, { Component } from 'react';
import {
  View,
  Text,
  UIManager,
  LayoutAnimation,
  Dimensions,
  TouchableWithoutFeedback,
} from 'react-native';
import Icon from 'react-native-vector-icons/MaterialIcons';

const styles = {
  movieFilterListContainerStyle: {
    position: 'absolute',
    bottom: -300,
    right: -10,
    height: 300,
  },
};

class MovieFilter extends Component {
  constructor(props) {
    super(props);
    this.state = {
      showFilterList: false,
      filterListWidth: 0,
    };
    this.renderFilterList = this.renderFilterList.bind(this);
    this.onShowFilterList = this.onShowFilterList.bind(this);
    this.calculateFilterListWidth = this.calculateFilterListWidth.bind(this);
  }

  componentWillMount() {
    UIManager.setLayoutAnimationEnabledExperimental(true);
    this.calculateFilterListWidth();
    Dimensions.addEventListener('change', this.calculateFilterListWidth);
  }

  componentWillUpdate() {
    LayoutAnimation.spring();
  }

  componentWillUnmount() {
    Dimensions.removeEventListener('change', () => {});
  }

  onShowFilterList() {
    const { showFilterList } = this.state;
    this.setState({ showFilterList: !showFilterList });
  }

  calculateFilterListWidth() {
    this.setState({ filterListWidth: Dimensions.get('window').width });
  }

  renderFilterList() {
    const { showFilterList, filterListWidth } = this.state;
    const { movieFilterListContainerStyle } = styles;
    if (showFilterList === true) {
      return (
        <View
          style={[
            movieFilterListContainerStyle,
            {
              width: filterListWidth,
            },
          ]}
        >
          <TouchableWithoutFeedback onPress={() => {}}>
            <View
              style={{
                flex: 1,
                backgroundColor: '#FFFFFF',
                elevation: 10,
                zIndex: 999999,
                paddingRight: 10,
                paddingLeft: 10,
                paddingTop: 10,
                paddingBottom: 10,
              }}
            >
              <View
                style={{
                  flexDirection: 'row',
                  position: 'relative',
                  justifyContent: 'space-between',
                }}
              >
                <Text>Year</Text>
                <Text>Test</Text>
              </View>
              <View style={{ flexDirection: 'row', position: 'relative' }}>
                <Text>Rating</Text>
                <Text>Test</Text>
              </View>
              <View style={{ flexDirection: 'row', position: 'relative' }}>
                <Text>Categories</Text>
                <Text>Test</Text>
              </View>
            </View>
          </TouchableWithoutFeedback>
        </View>
      );
    }
    return null;
  }

  render() {
    return (
      <View style={{ flex: 1 }}>
        <Icon name="filter-list" size={30} onPress={this.onShowFilterList} />
        {this.renderFilterList()}
      </View>
    );
  }
}

export default MovieFilter;

Ceci est mon navigateur:

const MoviesTab = createStackNavigator(
  {
    MovieList: MoviesScreen,
  },
  {
    navigationOptions: ({ navigation }) => ({
      headerRight: (
        <View
          style={{
            marginLeft: 10,
            marginRight: 10,
            flexDirection: 'row',
            flex: 1,
          }}
        >
          <Icon
            onPress={navigation.getParam('logout')}
            size={30}
            name="logout-variant"
            color="#000000"
          />
          <MovieFilter />
        </View>
      ),
      headerRightContainerStyle: {
        zIndex: 20,
        elevation: 20,
      },
      headerLeft: (
        <View style={{ flex: 1, flexDirection: 'row' }}>
          <SearchBar />
        </View>
      ),
    }),
  },
);
7
Cristian Gomez

Ajouter un attribut pointerEvents. La documentation peut être trouvée ici http://facebook.github.io/react-native/docs/0.50/view#pointerevents Ajoutez le pointerEvents à cette vue dans la méthode renderFilterList

<View
          style={[
            movieFilterListContainerStyle,
            {
              width: filterListWidth,
            },
          ]}
          pointerEvents={'box-only'}
        >
3
Kranthi

Cela s'est avéré être le problème/correctif de notre application (voir les premiers et derniers commentaires): déplacez l'élément absolu vers le dernier élément dans la vue de dessus

zIndex/question Touch sur Android

0
John kendall