React Native Overflow Touchable在Android中不起作用 [英] React Native Overflow Touchable is Not Working in Android

查看:64
本文介绍了React Native Overflow Touchable在Android中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请看看我的世博小吃.

下拉菜单项在iOS中是可触摸的,但在Android中是不可触摸的.固定容器的高度(灰色框)会导致此问题,但我需要为工具栏保持固定高度.

Dropdown items are touchable in iOS but not in Android. Fixed container's height (grey box) causes this issue but I need to keep the fixed height for my toolbar.

我尝试使用react-native-view-overflow软件包,但是没有运气.它需要react-native link,同时我无法退出项目,因为我使用的是一些Expo软件包,如果我退出,这些软件包将被破坏.

I have tried using react-native-view-overflow package but no luck. It requires react-native link, meanwhile I can't eject my project because I'm using some Expo packages which will be broken if I eject.

有没有建议让下拉菜单在Android中可触摸?

Any suggestion to make the dropdown items touchable in Android?

推荐答案

我不会使用依赖项,而是由我自己来管理它.

I wouldn't use a dependency instead I would manage it myself.

  1. 创建一个名为DropDown的组件,该组件以绝对位置覆盖整个屏幕(这样就不会影响屏幕上其他元素的位置).处于非活动状态时,此组件不可见.
  2. 按下按钮时,将在视图中测量其位置,然后将其传递到DropDown组件.
  3. 更新其道具后,DropDown组件将重新渲染,并在与按下的原始按钮非常接近的位置显示小菜单.
  4. 在菜单中的某个项目上点击可调用主要组件,并将DropDown的可见性更改为不可见.
  5. 在后台点击还会调用主要组件,并将DropDown的可见性更改为不可见.
  1. Create a component called DropDown that covers the whole screen with an absolute position (so that it doesn't affect the position of other elements on the screen). This component is invisible when inactive.
  2. When the button is pressed its position is measured in the view and this is then passed to the DropDown component.
  3. With its props updated the DropDown component re-renders and a small menu is displayed in close proximity to the original button that was pressed.
  4. Tapping on an item in the menu calls back to the main component, and changes the visibility of the DropDown back to being invisible.
  5. Tapping on the background also calls back to the main component, and changes the visibility of the DropDown back to being invisible.

这是代码,但我也将其放在零食中,供您与 https一起玩://snack.expo.io/@andypandy/dropdownmenu

Here is the code, but I have also put it in a snack for you to play with https://snack.expo.io/@andypandy/dropdownmenu

您可以使用此方法进行多种操作.您可以将孩子作为道具传递,也可以将其挂接到redux并将其设置在应用程序的根目录,以便可以在任何地方使用.样式可以轻松更改.在使用它时,它确实非常灵活.我已经在两个应用程序商店中目前都存在的许多应用程序中使用了此功能.

There are lots of possibilities that you could do with this. You could pass in children as props, you could hook it in to redux and set it at the root of your app so that it can be used anywhere. The styles can easily be changed. It really is quite flexible in what you can do with it. I have used this in many applications that are currently live in both app stores.

import React from 'react';
import { 
  Text, 
  View, 
  StyleSheet,
  UIManager,
  findNodeHandle,
  TouchableOpacity
} from 'react-native';
// import components
import DropDown from './DropDown';
import MyButton from './MyButton';

export default class App extends React.Component {

  state = {
    show: false,
    position: {}
  }

  // handle showing the dropdown
  showDropDown = () => {
    if (this.button) {
      // use the uimanager to measure the button's position in the window
      UIManager.measure(findNodeHandle(this.button), (x, y, width, height, pageX, pageY) => {
        const position = { left: pageX, top: pageY, width: width, height: height };
        // setState, which updates the props that are passed to the DropDown component
        this.setState({show: true, position: { x: pageX + (width / 2), y: pageY + (2 * height / 3) }})
      });
    }
  }

  // hide the dropdown
  hideDropDown = (item) => {
    alert(item)
    this.setState({show: false, position: {}})
  }

  render() {
    return (
      <View style={styles.container}>
        <View style={{height: 100, width: 300, backgroundColor: 'yellow', alignItems: 'center', justifyContent: 'center'}}>
          <MyButton
            ref={ref => {this.button = ref}}
            onPress={this.showDropDown}
            title={'Menu'}
          />
        </View>
          {/* Anything to be rendered below the DropDown should appear before the DropDown. So for best performance all components should go here. */}
        <DropDown show={this.state.show} position={this.state.position} hide={this.hideDropDown}/>
          {/* If you place a component here, it will appear above the DropDown and may interfere with how the DropDown works. You should not put anything here. */}
      </View>
    )
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'white'
  }
});

DropDown.js

import React from 'react';
import { Text, View, StyleSheet, TouchableWithoutFeedback, TouchableOpacity} from 'react-native';

export default class DropDown extends React.Component {

  render() {

    if (this.props.show) {
      const { y: top, x: left } = this.props.position;
      const width = 100;
      return (
        <TouchableWithoutFeedback onPress={() => this.props.hide('background pressed')}>
          <View style={styles.container}>
              <View style={[styles.menu, { top, left: left - width/2, width}]}>

              <TouchableOpacity style={{width, alignItems: 'center', paddingTop: 5}} onPress={() => this.props.hide('Item 1')}>
                <Text>Item 1</Text>
              </TouchableOpacity>

              <TouchableOpacity style={{width, alignItems: 'center', paddingTop: 5}} onPress={() => this.props.hide('Item 2')}>
                <Text>Item 2</Text>
              </TouchableOpacity>

              <TouchableOpacity style={{width, alignItems: 'center', paddingTop: 5}} onPress={() => this.props.hide('Item 3')}>
                <Text>Item 3</Text>
              </TouchableOpacity>

              <TouchableOpacity style={{width, alignItems: 'center', paddingVertical: 5}} onPress={() => this.props.hide('Item 4')}>
                <Text>Item 4</Text>
              </TouchableOpacity>
              </View>
          </View>
        </TouchableWithoutFeedback>
      );
    } else {
      return null
    }
  }
}

const styles = StyleSheet.create({
  container: {
    position: 'absolute',
    top: 0,
    left: 0,
    right: 0,
    bottom: 0
  },
  menu: {
    position: 'absolute',
    backgroundColor: 'white',
    alignItems: 'center',
    shadowColor: "#000",
    shadowOffset: {
      width: 0,
      height: 5,
    },
    shadowOpacity: 0.36,
    shadowRadius: 6.68,
    elevation: 11,
  }
});

MyButton.js

import React from 'react';
import { 
  Text, 
  View, 
  StyleSheet,
  TouchableOpacity
} from 'react-native';

export default class App extends React.Component {

  render() {
    return (
      <TouchableOpacity onPress={this.props.onPress}>
        <View style={styles.button}>
          <Text style={{color: 'white'}}>{this.props.title}</Text>
        </View>
      </TouchableOpacity>
    )
  }
}

const styles = StyleSheet.create({
  button: {
    backgroundColor: '#336699', 
    padding: 10, 
    borderRadius: 5
  }
});

这篇关于React Native Overflow Touchable在Android中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆