Problem with Picker in android (text of the selected item) - android

I am having a problem with the picker (only in android). In the iPhone, I don't have any problem.
When I select an item, in android doesn’t update the text in the Combobox (but the object is selected ok).
I attach the code:
<View style={[Styles.PickerSelect, { width: “70%” }]}>
<Picker
headerBackButtonText="Atras"
iosHeader="Seleccionar"
selectedValue={this.state.articulo}
placeholder={this.state.articulo}
onValueChange={this.getDatosLineas.bind(this)>
{this.state.articulos && this.state.articulos.map((item, i) => {
return (
<Picker.Item
key={i}
value={i}
label={item.nom_articulo}/>
);
})}
</Picker>
</View>
I attach the photo of the example:
In 1- When I enter to the section, I have the picker with this text and value.
In 2- I select the picker, and I select another item (for example “ORUJO DE UVAS BLANCAS”)
In 3- In android, the text isn’t be updated. But the object is the selected…
I repeat, in ios, I don't have this problem.
Expo SDK: 36.0.0
Thanks!

You need to set selected value in articulo variable with setState() method in onValueChange() callback inside picker tag.
<View style={[Styles.PickerSelect, { width: “70%” }]}>
<Picker
headerBackButtonText="Atras"
iosHeader="Seleccionar"
selectedValue={this.state.articulo}
placeholder={this.state.articulo}
onValueChange={(itemValue, itemPosition) =>
this.setState({articulo: itemValue, choosenIndex: itemPosition})}>
{this.state.articulos && this.state.articulos.map((item, i) => {
return (
<Picker.Item
key={i}
value={i}
label={item.nom_articulo}/>
);
})}

Related

How to keep the value of textinput when going from screen B to screen A in React-Native

I have 2 screens A and B, in screen A I have a TextInput, it's value is taken from another screen to this screen, its code looks like this
const ScreenA = (props) => {
const { position, suffix } = props;
const navigation = useNavigation();
const [textValue, setTextValue] = useState(props.name || '');
const navigationScreen = () => {
navigation.navigate('screenB');
};
return (
<>
<View>
<View>
<TextInput
value={textValue}
onChangeText={(text) => {
setTextValue(text);
}}
/>
</View>
<TouchableOpacity onPress={navigationScreen}>
<View>
<View style={styles.rectangle} />
</View>
</TouchableOpacity>
</View>
</>
);
};
export default ScreenA;
And after I press the button in screen A it moves to screen B, but after I go back from screen B to screen A, how can I keep my changed value at screen A,
The example is as follows: initially I go to screen A, the value of textValue will be "Abcd", then I edit the value of TextInput to be "A913" then I press submit button, and when in screen B rotates about screen A, i want the value of TextInput to be "A913" not "Abcd"
Can someone help me to solve this problem?
You should store your textinput value in Global state. and you can do so by using React Context or Redux

Keyboard is not opening automatically though autoFocus={true}

I have a TextInput inside a Modal with autoFocus={true}. As soon as Modal is opened TextInput is focused automatically but keyboard is not opening automatically.And surprisingly this is happening randomly. sometimes keyboard opens and sometimes not. This is happening in both emulator and real device.
Any suggestions to overcome this behavior? Thank You.
you can pass focus to TextInput using reference whenever a Modal is visible
<Modal onShow={() => {this.textInput.focus()}} >
<TextInput ref={input => {this.textInput = input}} />
</Modal>
I'm having the same problem currently. I used the solution suggestes by saumil and others previously; but adjusted for functional components:
import React, { useRef } from 'react';
...
let textInput = useRef(null);
<Modal onShow={() => { textInput.focus(); }} ...>
<TextInput ref={(input) => { textInput = input; }} ... />
</Modal>
It works, but I don't quite know what I'm doing (explanations welcomed). It's important to delete the autoFocus={true} to get consistent results.
Need to check though,
// Keyboard IpM
InputMethodManager imm = (InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE);
// input is TextInputEditText in here.
// adding a listener
input.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean isFocused) {
if (isFocused) {
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}
}
});
You can try focus method. Like this;
focus() {
this.textInputRef.focus();
}
render() {
return (
<TextInput
ref={ref => {
this.textInputRef = ref;
}}
/>
);
}
Now you can call focus function whenever you want. It will focus on the textinput and open the keyboard immediately.
This code is working for me. Use android:focusedByDefault="true"
<com.google.android.material.textfield.TextInputLayout
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Email">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:focusedByDefault="true" />
</com.google.android.material.textfield.TextInputLayout>

Create app bar for android

Imagine I have an application with StackNavigator, that is when user clicks something on Page 1 he/she is redirected to Page 2 (using Stack Navigator), etc.
I want to have an app bar, which is global per the application, that is, each page (Page 1, Page2, etc.) should show this app bar.
This is what is meant by app bar.
[![enter image description here][1]][1]
I found a component on documentation which looks like this:
<ToolbarAndroid
logo={require('./app_logo.png')}
title="AwesomeApp"
actions={[{title: 'Settings', icon: require('./icon_settings.png'), show: 'always'}]}
onActionSelected={this.onActionSelected} />
Does it mean I need to put this component inside render of each page separately? (Page 1, Page2). Like I said I want only a single toolbar for whole app.
Can someone show me some code example how to achieve this?
You could create a separate component called MyHeader.js and import to a file you want to use it. Give props to customize it. Example that used NativeBase:
MyHeader.js
import React from 'react';
import { Text, View, Image } from 'react-native';
import { Container, Header, Left, Body, Right, Title, Button, Icon } from 'native-base';
import styles from '../assets/style';
export default class MyHeader extends React.Component {
render() {
const goBack = this.props.goBackProp;
return (
<Container>
<Header>
<Left>
<Button
transparent
onPress={() => goBack()}
>
<Icon name="ios-arrow-back" />
</Button>
</Left>
<Body>
<Title> {this.props.title} </Title>
</Body>
<Right />
</Header>
</Container>
);
}
}
Now I could import it to any component like this:
import MyHeader from '../components/MyHeader';
export default class BlogScreen extends React.Component {
render() {
const {goBack} = this.props.navigation;
return (
<MyHeader goBackProp={goBack} title={'Blog'}/>
);
}
}

FlatList scroll after adding new element

I am using FlatList component of ReactNative and it is working perfectly. Now i want to scroll it to bottom whenever user enters new element/comment.
<FlatList style={styles.commentList}
data={commentList}
keyExtractor={(item, index) => index}
renderItem={this.renderRow.bind(this)}
/>
Now whenever user enters new comment, commentList will be updated and FlatList also gets refresh, but i want to be scroll to the bottom so that user can read latest comment posted.
Check this out:
Its not my solution, but i got working using this method.
https://exp.host/#xavieramoros/snack-SyN4FJikz
source code:
https://github.com/xavieramoros/flatlist-initialScrollIndexIssue/blob/master/App.js
Expo 22 - RN 0.49
A great thanks to https://expo.io/#xavieramoros
Edited: If you just want to scroll to bottom then scrollToEnd (https://facebook.github.io/react-native/docs/flatlist.html#scrolltoend) is available in new RN.
use it like
<FlatList
ref={ (ref) => { this.flatList = ref; }}
data={this.data}
renderItem={ this.renderItem }
keyExtractor={ this.keyExtractor}
onScroll={ this.scrollToEnd}
/>
......
and in your method
scrollToEnd = () => {
const wait = new Promise((resolve) => setTimeout(resolve, 0));
wait.then( () => {
this.flatList.scrollToEnd({ animated: true });
});
}
Try FlatList with inverted prop as true. (might as well reverse the data array)
Since flatlist is inverted, the new data is added on the first position, and because of this update flatlist automatically scrolls to first position, which in your case is the bottom location

onTouchstart event not fire in Listview(Alloy) only Android

view xml(List view template)
<Alloy>
<ItemTemplate id="test">
<View onTouchstart="touch" width="Ti.UI.SIZE" height="Ti.UI.SIZE">
<Label>test</Label>
</View>
</ItemTemplate>
</Alloy>
controller js
function touch(e){
Ti.API.debug('touch!!');
};
not fire only android..(iOS is good)
and under don't use ListView code, no problem android(and iOS).
<Alloy>
<Window class="container">
<View onTouchstart="touch" width="Ti.UI.SIZE" height="Ti.UI.SIZE">
<Label>test</Label>
</View>
</Window>
</Alloy>
I do not know anyone solution?
There are no 'touchstart' method for ListViews, you could use 'dragstart' and 'scrollstart' as alternative.
Check out the available events:
http://docs.appcelerator.com/platform/latest/#!/api/Titanium.UI.ListView
I've tried once to add the 'change' event to a TextField inside the ItemTemplace, but I've to create an workaround:
Change event on TextField inside ListView Template
If it's not possible, you have to use the 'itemclick' and get the selected row:
$.list.addEventListener('itemclick',function(list) {
var row = $.list.sections[0].getItemAt(list.itemIndex);
if(row && row.title) {
row.title.text = 'hello world';
//when you click the View with 'cancel' bindId
if(list.bindId == 'cancel') yourCancelAction();
//when you click the View with 'save' bindId
//(if you need to pass the row index to the function,
//in order to update something on the clicked row with a external function)
if(list.bindId == 'save') yourSaveAction(list.itemIndex);
$.list.sections[0].updateItemAt(list.itemIndex,row);
}
list = row = null;
});

Categories

Resources