Я надеюсь, что это известная проблема, так как я не могу предоставить многое для go, чтобы получить помощь в ее решении.
Я использую реагирующую навигацию для своего приложения со следующей настройкой :
- AppContainer
- Spla sh Экран
- Экран настройки (Навигатор стека)
- Главный экран (Навигатор стека)
Когда мое приложение запускается, оно переходит к экрану spla sh, который решает, запущен ли он впервые или нет, и в зависимости от этого решения вызывает this.props.navigation.navigate()
на любом из главных экранов. или экран настройки.
Пока все это работает и является довольно стандартным.
Когда мое приложение запускается в первый раз, пользователь отправляется на экран настройки, где он перемещается по серии экранов, вводя данные и выбирая следующую кнопку, чтобы перейти к следующему экрану. Вот где проблема возникает. Мой первый экран просто содержит некоторый текст и следующую кнопку (которая является обычным компонентом кнопки), которая при нажатии вызывает this.props.navigation.push('nextviewname', {data: data})
для перехода к следующему представлению.
Следующее представление содержит ввод текста, а также назад и Следующие кнопки, где у меня проблемы. Когда я попадаю на этот экран после новой установки версии приложения на мой телефон Android X, ни один из входов не работает. Я не могу:
- Нажмите следующий из спины
- Нажмите стрелку назад в левом верхнем углу, которая является частью заголовка
- Нажмите ввод текста ( курсор ненадолго появляется при вводе текста, но клавиатура не появляется)
- Нажмите аппаратную клавишу возврата
В очень редких случаях некоторые из вышеперечисленных работают (например, ввод текста) иногда будет работать), а иногда я даже сделаю это на следующем шаге моей настройки, но редко, что я делаю все это через
Странно, все это работает, когда я отлаживаю свое приложение на своем телефоне .
Обновление: Я только что проверил на эмуляторе Android 9 и получаю ту же проблему.
Обновление 2: Это становится странным, когда приложение находится в нерабочем состоянии, я все равно могу вызвать меню реакции отладки, однако, когда я нажимаю Toggle Inspector, ничего не происходит (т.е. я не получаю интерфейс инспектора). Похоже, что это как-то ломает все.
Кто-нибудь видел / решил эту проблему раньше? На данный момент оно фактически сделало мое приложение бесполезным.
Обновление 3: Некоторый код, который, как мы надеемся, прояснит ситуацию:
const SetupUser = createStackNavigator(
{
SetupUser: WelcomeScreen,
SetupName: UserName,
SetupCurrentWeight: CurrentWeight,
SetupGoalWeight: GoalWeight,
SetupGoalDate: GoalDate,
Summary: Summary,
LogWeight: LogWeight,
},
{
defaultNavigationOptions: {
headerStyle: {
backgroundColor: '#001830',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
},
},
);
const MainApp = createStackNavigator(
{
LogWeight: LogWeight,
LogWeightSummary: LogWeightSummary,
},
{
defaultNavigationOptions: {
headerStyle: {
backgroundColor: '#001830',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
},
},
);
export default createAppContainer(
createSwitchNavigator(
{
MainApp: MainApp,
SplashScreen: SplashScreen,
SetupUser: SetupUser,
},
{
initialRouteName: 'SplashScreen',
},
),
);
При получении этого фрагмента кода (я Я удалил навигатор вкладок, так как ошибка все еще существует, даже без нее) Я думаю, что мне удалось отследить источник проблемы, но я все еще не уверен, как ее исправить. Первое загруженное представление - это экран spla sh, который выглядит следующим образом:
export default class SplashScreen extends React.Component {
constructor(props) {
super(props);
GoBinder.verifyDatabase()
.then(GoBinder.getLastUser())
.then(user => {
this.props.navigation.navigate(
user.user == null ? 'SetupUser' : 'MainApp',
);
})
.catch(error => {
GoBinder.toast('Error while checking initial user state: ' + error);
});
}
render() {
return (
<View style={styles.container}>
<ActivityIndicator />
<StatusBar barStyle="default" />
</View>
);
}
}
В приведенном выше коде GoBinder.verifyDatabase () и GoBinder.getLastUser () являются вызовами собственного кода, который выполняет некоторую базу данных. Операция, чтобы настроить вещи и проверить, есть ли какие-либо существующие пользователи. Я полагаю, что проблема в том, что this.props.navigation.navigate
срабатывает слишком быстро, из-за чего реактивная навигация загружает следующий экран, но в процессе запутывается.
Я пытался следовать рекомендациям в этом посте https://www.novemberfive.co/blog/react-performance-navigation-animations о перемещении кода блокировки в InteractionManager.runAfterInteractions
в componentDidMount
, однако это не имеет значения. Тем не менее, я вручную запускаю переход на новый экран с помощью кнопки, и все работает правильно, поэтому его действительно похоже на то, что процесс программно меняющихся экранов портит все.
Обновление 4: Выглядит как будто я немного подпрыгнул, он все еще довольно сильно зависает, перенося мой ответ в обновление:
Так что я не уверен, что это лучшее решение, но я нашел обходной путь. Сейчас я вызываю код своей базы данных в InteractionManager.runArfetInteraction()
, как предложено в https://www.novemberfive.co/blog/react-performance-navigation-animations. Затем я вызываю setState
с результатом функций БД для сохранения результата. Наконец, я использую обратный вызов на setState
, чтобы вызвать фактическую навигацию. Мой полный рабочий код:
componentDidMount() {
InteractionManager.runAfterInteractions(() => {
GoBinder.verifyDatabase()
.then(
GoBinder.getLastUser().then(user => {
this.setState(
{
user: user.user,
},
() => {
this.props.navigation.navigate(
this.state.user == null ? 'SetupUser' : 'MainApp',
);
},
);
}),
)
.catch(error => {
GoBinder.toast('Error while checking initial user state: ' + error);
});
});
}
Спасибо за вашу помощь