【问题标题】:Custom drawer navigation isn't animating, just getting snapped to final size自定义抽屉导航没有动画,只是被捕捉到最终大小
【发布时间】:2022-08-09 19:11:06
【问题描述】:

我正在尝试在滑动(打开、关闭)时使用动画效果实现这个自定义抽屉,在切换抽屉时 MainLayout 应该使用缩小/增长动画来调整大小,但它所做的只是在它之后改变它的大小到达右端或左端,事实上,如果我使用拉/推触摸的关闭按钮,返回时它不会在全屏中增长。

抽屉代码:

import \'react-native-gesture-handler\';
import React, {useState} from \'react\';
import {StyleSheet, TouchableOpacity, Image, Text, View} from \'react-native\';
import LinearGradient from \'react-native-linear-gradient\';
import Animated from \'react-native-reanimated\';
import {
  createDrawerNavigator,
  DrawerContentScrollView,
  useDrawerProgress,
} from \'@react-navigation/drawer\';
import {icons} from \'../constants\';

// screens import
import MainLayout from \'../screens/MainLayout\';

const Drawer = createDrawerNavigator();

const CustomDrawerItem = ({icon, label}) => {
  return (
    <TouchableOpacity // drawer item button
      style={[styles.drawerItem]}
      onPress={() => console.log(\'drawer item\')}>
      <Image // drawer item icon
        source={icon}
        style={styles.drawerItemIcon}
      />
      <Text // drawer item label
        style={styles.drawerItemLabel}>
        {label}
      </Text>
    </TouchableOpacity>
  );
};

const CustomDrawerContent = ({navigation}) => {
  return (
    <DrawerContentScrollView
      scrollEnabled={true}
      contentContainerStyle={{flex: 1}}>
      <View style={{flex: 1, paddingHorizontal: 20}}>
        <View // close button container
          style={styles.closeBtnContainer}>
          <TouchableOpacity // close button
            style={styles.closeBtn}
            onPress={() => navigation.closeDrawer()}>
            <Image // close button icon
              source={icons.close}
              style={styles.closeBtnIcon}
              resizeMode=\"contain\"
            />
          </TouchableOpacity>
        </View>

        <TouchableOpacity // profile button
          style={styles.profileButton}
          onPress={() => console.log(\'profile\')}>
          <Image // profile image
            source={icons.avatar}
            style={styles.profileImage}
            resizeMode=\"cover\"
          />
          <View // profile text container
            style={{marginLeft: 10}}>
            <Text // profile name
              style={styles.commonTxt}>
              John Doe
            </Text>
            <Text // profile email
              style={[styles.commonTxt, {fontSize: 15}]}>
              john@xyz.com
            </Text>
          </View>
        </TouchableOpacity>

        <View // drawer items container
          style={styles.drawerItmContainer}>
          <CustomDrawerItem // qr code
            icon={icons.qr_code}
            label=\"QR Code\"
          />

          <CustomDrawerItem // resource
            icon={icons.resource}
            label=\"Resource\"
          />

          <CustomDrawerItem // collection report
            icon={icons.collection_report}
            label=\"Collection Report\"
          />

          <CustomDrawerItem // change pin
            icon={icons.change_pin}
            label=\"Change Pin\"
          />
          <View // separator
            style={styles.separator}
          />
        </View>
        <View // logout button container
          style={{marginBottom: 20}}>
          <CustomDrawerItem // logout
            icon={icons.logout}
            label=\"Logout\"
          />
        </View>
      </View>
    </DrawerContentScrollView>
  );
};

const CustomDrawer = () => {
  return (
    <LinearGradient
      colors={[\'#ff9933\', \'#3b5998\', \'#192f6a\']}
      style={styles.container}>
      <Drawer.Navigator
        screenOptions={{
          headerShown: false,
          drawerType: \'slide\',
          overlayColor: \'transparent\',
          drawerStyle: {flex: 1, width: \'65%\', backgroundColor: \'transparent\'},
          sceneContainerStyle: {backgroundColor: \'transparent\'},
        }}
        drawerContent={props => {
          return <CustomDrawerContent navigation={props.navigation} />;
        }}
        initialRouteName=\"MainLayout\">
        <Drawer.Screen name=\"MainLayout\">
          {props => <MainLayout {...props} />}
        </Drawer.Screen>
      </Drawer.Navigator>
    </LinearGradient>
  );
};

export default CustomDrawer;

const styles = StyleSheet.create({
  drawerItem: {
    flexDirection: \'row\',
    alignItems: \'center\',
    marginBottom: 20,
    alignItems: \'center\',
    borderRadius: 10,
  },
  drawerItemIcon: {width: 20, height: 20, tintColor: \'#fff\'},
  drawerItemLabel: {fontSize: 18, color: \'#fff\', marginLeft: 15},
  profileButton: {flexDirection: \'row\', alignItems: \'center\', marginTop: 20},
  profileImage: {width: 50, height: 50, borderRadius: 10},
  closeBtnContainer: {alignItems: \'flex-start\', justifyContent: \'center\'},
  closeBtn: {alignItems: \'center\', justifyContent: \'center\'},
  closeBtnIcon: {width: 30, height: 30, tintColor: \'#fff\'},
  commonTxt: {fontSize: 18, color: \'#fff\'},
  drawerItmContainer: {flex: 1, marginTop: 20},
  separator: {height: 1, backgroundColor: \'#fff\', marginVertical: 10},
  container: {flex: 1, backgroundColor: \'#ff9f1c\'},
});


MainLayout 的代码:

import \'react-native-gesture-handler\';
import {StyleSheet, Text, View, SafeAreaView} from \'react-native\';
import React from \'react\';
import Animated from \'react-native-reanimated\';
import {useDrawerProgress} from \'@react-navigation/drawer\';

const MainLayout = props => {
  const progress = useDrawerProgress();

  const scale = Animated.interpolateNode(progress.value, {
    inputRange: [0, 1],
    outputRange: [1, 0.75],
  });
  const borderRadius = Animated.interpolateNode(progress.value, {
    inputRange: [0, 1],
    outputRange: [0, 30],
  });

  const animatedStyle = {
    borderRadius,
    transform: [{scale}],
  };

  return (
    <Animated.View
      style={{
        flex: 1,
        alignItems: \'center\',
        justifyContent: \'center\',
        backgroundColor: \'#fff\',
        ...animatedStyle,
      }}>
      <Text>MainLayout</Text>
    </Animated.View>
  );
};

export default MainLayout;

const styles = StyleSheet.create({});

动画问题:

结束问题:

包.json

{
  \"name\": \"Dhananjaya\",
  \"version\": \"0.0.1\",
  \"private\": true,
  \"scripts\": {
    \"android\": \"react-native run-android\",
    \"ios\": \"react-native run-ios\",
    \"start\": \"react-native start\",
    \"test\": \"jest\",
    \"lint\": \"eslint .\"
  },
  \"dependencies\": {
    \"@react-native-masked-view/masked-view\": \"^0.2.6\",
    \"@react-navigation/drawer\": \"^6.4.1\",
    \"@react-navigation/native\": \"^6.0.10\",
    \"@react-navigation/stack\": \"^6.2.1\",
    \"axios\": \"^0.27.2\",
    \"native-base\": \"^3.4.5\",
    \"react\": \"17.0.2\",
    \"react-native\": \"0.68.2\",
    \"react-native-gesture-handler\": \"^2.4.2\",
    \"react-native-linear-gradient\": \"^2.5.6\",
    \"react-native-reanimated\": \"^2.8.0\",
    \"react-native-safe-area-context\": \"^4.2.5\",
    \"react-native-screens\": \"^3.13.1\",
    \"react-native-svg\": \"^12.3.0\"
  },
  \"devDependencies\": {
    \"@babel/core\": \"7.18.2\",
    \"@babel/runtime\": \"7.18.3\",
    \"@react-native-community/eslint-config\": \"2.0.0\",
    \"babel-jest\": \"26.6.3\",
    \"eslint\": \"7.32.0\",
    \"jest\": \"26.6.3\",
    \"metro-react-native-babel-preset\": \"0.67.0\",
    \"react-test-renderer\": \"17.0.2\"
  },
  \"jest\": {
    \"preset\": \"react-native\"
  }
}

babel.config.js (供参考重生配置)

module.exports = {
  presets: [\'module:metro-react-native-babel-preset\'],
  plugins: [\'react-native-reanimated/plugin\'],
};

    标签: react-native-navigation react-native-reanimated react-native-reanimated-v2 react-native-navigation-v2 react-native-drawer


    【解决方案1】:

    https://github.com/thepeaklab/react-navigation-6-scaling-drawer 看看这个 repo 它可能会回答你的问题

    【讨论】:

      猜你喜欢
      • 2014-06-08
      • 1970-01-01
      • 2023-03-08
      • 1970-01-01
      • 1970-01-01
      • 2020-06-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多