React Native Overflow Touchable не работает в Android - PullRequest
0 голосов
/ 04 февраля 2019

Пожалуйста, взгляните на мою Expo Snack .

Выпадающие элементы доступны в iOS, но не в Android.Фиксированная высота контейнера (серая рамка) вызывает эту проблему, но мне нужно сохранить фиксированную высоту для моей панели инструментов.

Я пытался использовать пакет react-native-view-overflow, но безуспешно.Для этого требуется react-native link, в то время как я не могу удалить свой проект, потому что я использую некоторые пакеты Экспо, которые будут разбиты, если я извлечу.

Есть ли какие-либо предложения, чтобы сделать выпадающие элементы сенсорными в Android?

enter image description here

Ответы [ 3 ]

0 голосов
/ 09 февраля 2019

Я бы не использовал зависимость вместо того, чтобы управлять ею сам.

  1. Создайте компонент с именем DropDown, который покрывает весь экран с абсолютной позицией (чтобы он не влиял на положение других элементов на экране).Этот компонент невидим, когда неактивен.
  2. Когда кнопка нажата, ее положение измеряется в представлении, а затем передается компоненту DropDown.
  3. С обновленными реквизитами компонент DropDown выполняет рендеринг и маленькое меню отображается в непосредственной близости от исходной кнопки, которая была нажата.
  4. Нажатие на элемент в меню вызывает возврат к основному компоненту и изменяет видимость DropDown на то, что он становится невидимым.
  5. Нажатие на фон также вызывает возврат к основному компоненту,и изменяет видимость DropDown обратно на невидимость.

Вот код, но я также положил его в закуску, чтобы вы могли поиграть с https://snack.expo.io/@andypandy/dropdownmenu

ТамЕсть много возможностей, которые вы могли бы сделать с этим.Вы можете передать детей в качестве реквизита, вы можете подключить его к редуксу и установить его в корне вашего приложения, чтобы его можно было использовать где угодно.Стили могут быть легко изменены.Это действительно довольно гибко в том, что вы можете сделать с нимЯ использовал это во многих приложениях, которые в настоящее время живут в обоих магазинах приложений.

App.js

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
  }
});
0 голосов
/ 11 февраля 2019

Кажется, что когда раскрывающийся список расширяется, он выходит за пределы поля зрения, потому что вы задали фиксированную высоту.

, поэтому для обхода проблемы можно использовать свойство minHeight вместо height.

это гарантирует, что по крайней мере вы получите минимальную высоту и, если необходимо, можете использовать большую высоту, как при раскрытии раскрывающегося списка.

поправка приведена ниже,

dropdownContainer: {
    width:340,
    minHeight:115,// changed this from height:115
    ...
    ...
  },
0 голосов
/ 09 февраля 2019

Я изменил ваш код, отметьте это: Закусочная ссылка

Это решит вашу проблему, но вы можете обновить свою собственную версию реакции, чтобы включить эту фиксацию , которая добавляетподдержка свойства стиля overflow в React Native для Android.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...