讓安卓實現push動畫
之前我群里的討論怎么讓安卓實現類似iOS的push動畫,后來翻看官方issues的時候,真的發現了實現push動畫的代碼,在這里共享下
// 先引入這個方法
import CardStackStyleInterpolator from 'react-navigation/src/views/CardStackStyleInterpolator';
// 在StackNavigator配置headerMode的地方,使用transitionConfig添加
{
headerMode: 'screen',
transitionConfig:()=>({
screenInterpolator:CardStackStyleInterpolator.forHorizontal,
})
}
修改頁面的跳轉動畫
如何將安卓的跳轉動畫改成iOS那樣,react-navigation一共提供了4種跳轉動畫:
1、從右向左: forHorizontal;
2、從下向上: forVertical;
3、安卓那種的從下向上: forFadeFromBottomAndroid;
4、無動畫: forInitial。
但因為庫的限制,想實現某些頁面使用某種動畫還是很難的,只能通過Demo中提供的笨方法來實現。
首先還是導入react-navigation中的方法
import CardStackStyleInterpolator from 'react-navigation/src/views/CardStack/CardStackStyleInterpolator';
如果要改變跳轉動畫只能在StackNavigator中實現transitionConfig方法
const MainStack = StackNavigator({
Main:{
screen:Main,
},
},{
// mode:'modal',
headerMode: 'screen',
transitionConfig:()=>({
// 只要修改最后的forVertical就可以實現不同的動畫了。
screenInterpolator:CardStackStyleInterpolator.forVertical,
})
});
goBack返回指定頁面
react-navigation目錄下src/routers/StackRouter.js
iif (action.type === NavigationActions.BACK) {
let backRouteIndex = null;
if (action.key) {
const backRoute = state.routes.find(
/* $FlowFixMe */
/* 修改源碼 */
route => route.routeName === action.key
/* (route: *) => route.key === action.key */
);
/* $FlowFixMe */
console.log('backRoute =====',backRoute);
backRouteIndex = state.routes.indexOf(backRoute);
console.log('backRoute =====',backRouteIndex);
}
if (backRouteIndex == null) {
return StateUtils.pop(state);
}
if (backRouteIndex >= 0) {
return {
...state,
routes: state.routes.slice(0, backRouteIndex+1),
index: backRouteIndex - 1 + 1,
};
}
}
注意:這樣的修改源碼之后,如果項目中使用Redux,并且啟用了滑動返回,很會很大幾率導致app卡死,所以并不太推薦這種方式,最好使用下面的方式
關于快速點擊重復跳轉的解決辦法
如果想解決快速點擊跳轉的問題,需要修改部分源碼。
修改react-navigation目錄下,scr文件夾中的addNavigationHelpers.js文件
,可以直接替換成下面的文本
export default function<S: *>(navigation: NavigationProp<S, NavigationAction>) {
// 添加點擊判斷
let debounce = true;
return {
...navigation,
goBack: (key?: ?string): boolean =>
navigation.dispatch(
NavigationActions.back({
key: key === undefined ? navigation.state.key : key,
}),
),
navigate: (routeName: string,
params?: NavigationParams,
action?: NavigationAction,): boolean => {
if (debounce) {
debounce = false;
navigation.dispatch(
NavigationActions.navigate({
routeName,
params,
action,
}),
);
setTimeout(
() => {
debounce = true;
},
500,
);
return true;
}
return false;
},
/**
* For updating current route params. For example the nav bar title and
* buttons are based on the route params.
* This means `setParams` can be used to update nav bar for example.
*/
setParams: (params: NavigationParams): boolean =>
navigation.dispatch(
NavigationActions.setParams({
params,
key: navigation.state.key,
}),
),
};
}
安卓上,使用TextInput的時候會讓TabBar頂起來的解決辦法
最簡單的解決辦法就是在android目錄中,添加一句話
目錄:android/app/src/main/AndroidManifest.xml中,添加
android:windowSoftInputMode="stateAlwaysHidden|adjustPan|adjustResize"
安卓返回鍵在react-navigation中的正常監聽
之前使用Navigator的時候,可以通過下面的方法實現監聽安卓的返回鍵,但使用了react-navigation后,會很迷茫,不知該怎么監聽了。
Navigator的方法
componentWillMount() {
if (Platform.OS === 'android') {
BackAndroid.addEventListener('hardwareBackPress', this.onBackAndroid);
}
}
componentWillUnmount() {
if (Platform.OS === 'android') {
BackAndroid.removeEventListener('hardwareBackPress', this.onBackAndroid);
}
}
onBackAndroid = () => {
const nav = this.navigator;
const routers = nav.getCurrentRoutes();
if (routers.length > 1) {
nav.pop();
return true;
}
return false;
};
……
}
react-navigation的方式
componentWillMount() {
if (Platform.OS === 'android') {
BackHandler.addEventListener('handwareBackPress',this.onBackAndroid)
}
}
componentWillUnmount() {
if (Platform.OS === 'android') {
BackHandler.addEventListener('handwareBackPress',this.onBackAndroid)
}
}
onBackAndroid = () => {
const routers = nav.getCurrentRoutes();
if (routers.length > 1) {
return true;
}
return false;
};
……
}
// 在跳轉之后的頁面中
onBackAndroid = ()=> {
const {routes} = this.props;
console.log(routes);
// alert(routes)
if (routes.length > 1) {
// 因為其他頁面獲得不到this.props,所以只能每個頁面都寫這個方法。
this.props.navigation.goBack();
return true;
}
}