AnthonyDa
AnthonyDa

Reputation: 531

Expo React Native KeyboardAvoidingView not working on modal

I have the following modal :

export default class NewGameModal extends Component {
  constructor(props) {
    super(props);

    this.state = {
      playerList: [],
      characterSelectionModalVisible: false,
      selectedPlayerId: null,
      warningMessages: [
        {
          level: "error",
          message: "Votre Village est vide.",
          color: "#FF4444",
        },
      ],
    };
  }

  static contextType = ImageContext;
  render() {
    return (
      <Modal
        animationType="slide"
        transparent={true}
        visible={this.props.modalVisible}
        onRequestClose={() => {
          this.props.navigation.navigate("Home");
        }}
      >
        <KeyboardAvoidingView style={styles.centeredView}>
          <ImageBackground
            source={require("../assets/stain_pattern.png")}
            resizeMode="repeat"
            style={styles.modalYellowBackgroundImage}
          >
            <View style={styles.modalTitleView}>
              <Text style={styles.redText}>Nouveau Village</Text>
            </View>
            <ImageBackground
              source={require("../assets/stain_pattern.png")}
              resizeMode="repeat"
              style={styles.villageRepartitionBackgroundImage}
            >
              <ScrollView
                style={styles.villageRepartitionView}
                contentContainerStyle={styles.villageRepartitionContainerView}
                persistentScrollbar={true}
              >
                {this.getPlayerListGroupByCharacter().map((char, index) => (
                  <View
                    style={styles.characterRepartitionView}
                    key={"repartition-" + index}
                  >
                    <Text style={styles.sYellowText}>
                      {char.name} {char.count}/{char.max}
                    </Text>
                  </View>
                ))}
              </ScrollView>
            </ImageBackground>
            {this.state.warningMessages.length == 0 ? (
              ""
            ) : (
              <ImageBackground
                source={require("../assets/stain_pattern.png")}
                resizeMode="repeat"
                style={styles.warningBackgroundImage}
              >
                {this.state.warningMessages.slice(0, 3).map((m, index) => (
                  <Text
                    style={{ ...styles.message, color: m.color }}
                    key={"warning-" + index}
                  >
                    {m.message}
                  </Text>
                ))}
              </ImageBackground>
            )}
            <ImageBackground
              source={require("../assets/stain_pattern.png")}
              resizeMode="repeat"
              style={styles.playersListBackgroundImage}
            >
              <CharacterSelectionModal
                modalVisible={this.state.characterSelectionModalVisible}
                closeModal={(isVisible) => this.setModalVisible(isVisible)}
                playerId={this.state.selectedPlayerId}
                selectCharacter={(playerId, characterName) =>
                  this.selectCharacter(playerId, characterName)
                }
              />
              <ScrollView
                style={styles.playersListScrollView}
                contentContainerStyle={
                  this.state.playerList.length == 0
                    ? styles.playersListScrollViewContainer
                    : ""
                }
              >
                {this.state.playerList.length == 0 ? (
                  <View>
                    <Text style={styles.yellowText}>
                      Votre Village est vide.
                    </Text>
                    <Text style={styles.yellowText}>
                      Commencez par ajouter des joueurs
                    </Text>
                    <Text style={styles.yellowText}>
                      avec le bouton "+" ci dessous.
                    </Text>
                  </View>
                ) : (
                  this.state.playerList.map((player, index) => (
                    <View key={"player-" + index}>
                      <ImageBackground
                        source={require("../assets/stain_pattern.png")}
                        resizeMode="repeat"
                        style={{
                          ...styles.modalPlayerCardBackgroundImage,
                          backgroundColor: player.character
                            ? player.character.backgroundColor
                            : "#95A2C3",
                        }}
                      >
                        <View style={styles.playerCard}>
                          <Pressable
                            onPress={() => {
                              this.setSelectedPlayerId(player.playerId);
                              this.setModalVisible(true);
                            }}
                          >
                            <Image
                              style={styles.playerCardImage}
                              source={
                                player.character
                                  ? this.getImageByName(player.character.image)
                                  : require("../assets/cards_90_90/no_role2_90_90.png")
                              }
                              resizeMode="contain"
                            />
                          </Pressable>
                          <TextInput
                            style={styles.playerCardText}
                            placeholder="Nom Joueur"
                            value={player.name}
                            onChangeText={(value) =>
                              this.changePlayerName(player.playerId, value)
                            }
                            onBlur={() => this.checkVillage()}
                          />
                          <Pressable
                            style={styles.playerRemove}
                            onPress={() => this.removePlayer(player.playerId)}
                          >
                            <FontAwesomeIcon
                              name="close"
                              style={styles.playerRemoveIcon}
                            />
                          </Pressable>
                        </View>
                      </ImageBackground>
                    </View>
                  ))
                )}
              </ScrollView>
              <View style={styles.overlayButtonView}>
                <Pressable
                  style={styles.overlayButton}
                  onPress={() => this.addPlayer()}
                >
                  <Text style={styles.sBlueText}>Ajouter Joueur</Text>
                </Pressable>
                <Pressable
                  style={styles.overlayButton}
                  onPress={() => this.clearPlayerList()}
                >
                  <Text style={styles.sBlueText}>Vider le Village</Text>
                </Pressable>
                <Pressable
                  style={styles.overlayButton}
                  onPress={() => console.log("confirm")}
                >
                  <Text style={styles.sBlueText}>Créer Village</Text>
                </Pressable>
              </View>
            </ImageBackground>
          </ImageBackground>
        </KeyboardAvoidingView>
      </Modal>
    );
  }
}

const styles = StyleSheet.create({
      centeredView: {
        flex: 1,
        flexDirection: "column",
        justifyContent: "center",
        backgroundColor: "#FFEFBC",
        alignItems: "center",
        margin: 22,
        shadowColor: "#000",
        shadowOffset: {
          width: 0,
          height: 2,
        },
        shadowOpacity: 0.25,
        shadowRadius: 4,
        elevation: 5,
        borderRadius: 20,
      }
}

Here's the result :

[![react-native modal KeyboardAvoidingView issue][1]][1]

Everything is squished, I want the keyboard to go over the modal so nothing moves. I tried using KeyboardAvoidingView at multiple places in the modal. I also tried react-native-modal with the props avoidKeyboard and KeyboardAwareScrollView but nothing seems to work. I'm using react-navigation, I read on some posts that it can cause some issues. [1]: https://i.sstatic.net/Ifj02.jpg

Upvotes: 1

Views: 437

Answers (1)

Jatin Bhuva
Jatin Bhuva

Reputation: 1872

Try to change windowSoftInputMode on Manifest.xml file

from
android:windowSoftInputMode="adjustResize"

to
android:windowSoftInputMode="adjustPan"

Upvotes: 2

Related Questions