Open Keyboard in list - React Native

Asked

Viewed 203 times

0

I’m trying to implement a chat in my app, but when I open the keyboard to start a conversation, the conversation is released from the display.

Here’s my code and a gif of what’s going on.

import React, { Component } from 'react';
import { View, Text, TextInput, TouchableOpacity, ListView, StyleSheet, Image, ScrollView, Dimensions } from 'react-native';
import { connect } from 'react-redux';
import { Container } from 'native-base';
import Conversation from '../services/conversation';
import Imagens from '../../../imagens';


class Chat extends Component {
  constructor() {
    super();
    this.state = {
      conversationHistory: [],
      mensagem: ''
    };

    this.sendMessage('oi');
  }

  sendMessage(text) {
    this.setState({
      mensagem: ''
    });

    Conversation.message({
      text
    }).then(r => {
      if (r != null && r !== undefined) {
        r.data_iteracao = new Date().getHours() + ':' + new Date().getMinutes();
        this.state.conversationHistory.push(r);
        this.setState({
          conversationHistory: this.state.conversationHistory
        });
      }
    });
  }

  renderRow(texto) {
    return (
      <View style={styles.item}>
        <View style={[{ alignItems: 'flex-end' }]}>
          <View style={[styles.balloon, { alignItems: 'flex-end', backgroundColor: '#dbf5b4', elevation: 1, padding: 5, borderRadius: 8 }]}>
            <Text style={{ fontSize: 14, color: '#000', }}>{texto.input.text}</Text>
            <View style={{ alignItems: 'flex-end', alignSelf: 'flex-end' }}>
              <Text style={{ fontSize: 10, color: '#000' }}>{texto.data_iteracao}</Text>
            </View>
          </View>
        </View>

        <View style={[{ alignItems: 'flex-start', borderRadius: 20 }]}>
          <View style={[styles.balloon, { alignItems: 'flex-start', backgroundColor: '#f7f7f7', elevation: 1, padding: 5, borderRadius: 8 }]}>
            <Text style={{ fontSize: 14, color: '#000' }}>{texto.output.text}</Text>
            <View style={{ alignItems: 'flex-end', alignSelf: 'flex-end' }}>
              <Text style={{ fontSize: 10, color: '#000' }}>{texto.data_iteracao}</Text>
            </View>
          </View>
        </View >
      </View >
    );
  }

  render() {
    const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });

    return (

      <View style={styles.container}>

        <ListView
          enableEmptySections
          dataSource={ds.cloneWithRows(this.state.conversationHistory)}
          renderRow={this.renderRow}
          renderScrollComponent={props => <ScrollView {...props} />}
          onEndReachedThreshold={10}
          ref={ref => this.listView = ref}
          onContentSizeChange={(contentWidth, contentHeight) => {
            this.listView.scrollToEnd({ animated: false });
          }} />


        <View style={styles.footer}>
          <View style={styles.inputContainer}>
            <TextInput style={styles.inputs}
              placeholder="digite a mensagem..."
              underlineColorAndroid='transparent'
              value={this.state.mensagem}
              onChangeText={(mensagem) => this.setState({ mensagem })} />
          </View>

          <TouchableOpacity style={styles.btnSend} onPress={() => this.sendMessage(this.state.mensagem)}>
            <Image source={Imagens.send} style={styles.iconSend} />
          </TouchableOpacity>
        </View>
      </View>

    );
  }

}

export default connect()(Chat);

const styles = StyleSheet.create({
  container: {
    flex: 1
  },
  list: {
    paddingHorizontal: 17,
  },
  footer: {
    flexDirection: 'row',
    height: 60,
    backgroundColor: '#eeeeee',
    paddingHorizontal: 10,
    padding: 5,
  },
  btnSend: {
    backgroundColor: '#00BFFF',
    width: 40,
    height: 40,
    borderRadius: 360,
    alignItems: 'center',
    justifyContent: 'center',
  },
  iconSend: {
    width: 30,
    height: 30,
    alignSelf: 'center',
  },
  inputContainer: {
    borderBottomColor: '#F5FCFF',
    backgroundColor: '#FFFFFF',
    borderRadius: 30,
    borderBottomWidth: 1,
    height: 40,
    flexDirection: 'row',
    alignItems: 'center',
    flex: 1,
    marginRight: 10,
  },
  inputs: {
    height: 40,
    marginLeft: 16,
    borderBottomColor: '#FFFFFF',
    flex: 1,
  },
  balloon: {
    maxWidth: 250,
    padding: 15,
    borderRadius: 20,
  },
  itemIn: {
    alignSelf: 'flex-start'
  },
  itemOut: {
    alignSelf: 'flex-end'
  },
  time: {
    alignSelf: 'flex-end',
    margin: 15,
    fontSize: 12,
    color: '#808080'
  },
  item: {
    backgroundColor: '#eeeeee',
    borderRadius: 300,
    marginHorizontal: 8,
    marginTop: 5
  },
});  
  • I believe that every time your component changes state, you automatically lose the input Focus. Try using: autofocus = true and see how it behaves, if it works you can implement your logic of how to save this in the state of the component manipulate it. I realized tbm is using value = state.... when you set the value of Component, this will not change, I recommend using defaultValue instead of this, maybe this tbm will help you when typing something and the value of the input will change.

  • @Caiokoiti thanks for the return, but I don’t need an initial value for my input and the value is changed in onChangeText. My problem is that the conversation is sent up with the Scroll, but there are not enough components below to behave this way. Thank you.

  • Then try to leave your view or input as position Absolute or on the conversation view.

No answers

Browser other questions tagged

You are not signed in. Login or sign up in order to post.