Khóa học react-native

Animated trong React Native

0 phút đọc

Animated là một module mạnh mẽ trong React Native, cho phép bạn tạo ra các hiệu ứng hoạt hình mượt mà và hiệu quả. Animated cung cấp một API linh hoạt để tạo ra các hoạt hình phức tạp, từ các chuyển động đơn giản đến các hiệu ứng phức tạp hơn. Bằng cách sử dụng Animated, bạn có thể cải thiện trải nghiệm người dùng và làm cho ứng dụng của bạn trở nên sống động hơn.

Cú Pháp Cơ Bản

Để sử dụng Animated trong React Native, bạn cần import nó từ thư viện react-native và sử dụng các thành phần và phương thức của nó để tạo ra các hoạt hình.

javascript Copy
import React, { useRef, useEffect } from "react";
import { View, Animated, StyleSheet } from "react-native";

const App = () => {
  const fadeAnim = useRef(new Animated.Value(0)).current;

  useEffect(() => {
    Animated.timing(fadeAnim, {
      toValue: 1,
      duration: 2000,
      useNativeDriver: true,
    }).start();
  }, [fadeAnim]);

  return (
    <View style={styles.container}>
      <Animated.View style={[styles.fadingContainer, { opacity: fadeAnim }]}>
        <View style={styles.box} />
      </Animated.View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
  fadingContainer: {
    width: 100,
    height: 100,
  },
  box: {
    width: 100,
    height: 100,
    backgroundColor: "blue",
  },
});

export default App;

Các Thành Phần và Phương Thức Quan Trọng của Animated

Animated.Value

Animated.Value là một lớp cơ bản được sử dụng để lưu trữ giá trị của hoạt hình. Bạn có thể khởi tạo một Animated.Value với một giá trị ban đầu và sau đó thay đổi giá trị này trong quá trình hoạt hình.

Ví dụ:

javascript Copy
const fadeAnim = useRef(new Animated.Value(0)).current;

Animated.timing

Animated.timing là một phương thức được sử dụng để tạo ra các hoạt hình tuyến tính. Nó nhận vào một đối tượng cấu hình để xác định các thuộc tính của hoạt hình, chẳng hạn như giá trị đích (toValue), thời gian (duration), và sử dụng useNativeDriver để tối ưu hóa hiệu suất.

Ví dụ:

javascript Copy
Animated.timing(fadeAnim, {
  toValue: 1,
  duration: 2000,
  useNativeDriver: true,
}).start();

Animated.spring

Animated.spring là một phương thức được sử dụng để tạo ra các hoạt hình lò xo. Nó nhận vào một đối tượng cấu hình để xác định các thuộc tính của hoạt hình, chẳng hạn như giá trị đích (toValue), độ cứng (stiffness), và độ giảm chấn (damping).

Ví dụ:

javascript Copy
Animated.spring(fadeAnim, {
  toValue: 1,
  useNativeDriver: true,
}).start();

Animated.sequence

Animated.sequence là một phương thức được sử dụng để chạy các hoạt hình theo thứ tự. Nó nhận vào một mảng các hoạt hình và chạy chúng lần lượt.

Ví dụ:

javascript Copy
Animated.sequence([
  Animated.timing(fadeAnim, {
    toValue: 1,
    duration: 1000,
    useNativeDriver: true,
  }),
  Animated.timing(fadeAnim, {
    toValue: 0,
    duration: 1000,
    useNativeDriver: true,
  }),
]).start();

Animated.parallel

Animated.parallel là một phương thức được sử dụng để chạy các hoạt hình song song. Nó nhận vào một mảng các hoạt hình và chạy chúng đồng thời.

Ví dụ:

javascript Copy
Animated.parallel([
  Animated.timing(fadeAnim, {
    toValue: 1,
    duration: 1000,
    useNativeDriver: true,
  }),
  Animated.timing(translateAnim, {
    toValue: 100,
    duration: 1000,
    useNativeDriver: true,
  }),
]).start();

Ví Dụ Chi Tiết về Animated

Ví Dụ 1: Hoạt Hình Mờ Dần (Fade In)

javascript Copy
import React, { useRef, useEffect } from "react";
import { View, Animated, StyleSheet } from "react-native";

const FadeInExample = () => {
  const fadeAnim = useRef(new Animated.Value(0)).current;

  useEffect(() => {
    Animated.timing(fadeAnim, {
      toValue: 1,
      duration: 2000,
      useNativeDriver: true,
    }).start();
  }, [fadeAnim]);

  return (
    <View style={styles.container}>
      <Animated.View style={[styles.fadingContainer, { opacity: fadeAnim }]}>
        <View style={styles.box} />
      </Animated.View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
  fadingContainer: {
    width: 100,
    height: 100,
  },
  box: {
    width: 100,
    height: 100,
    backgroundColor: "blue",
  },
});

export default FadeInExample;

Ví Dụ 2: Hoạt Hình Trượt (Slide In)

javascript Copy
import React, { useRef, useEffect } from "react";
import { View, Animated, StyleSheet } from "react-native";

const SlideInExample = () => {
  const slideAnim = useRef(new Animated.Value(-200)).current;

  useEffect(() => {
    Animated.timing(slideAnim, {
      toValue: 0,
      duration: 2000,
      useNativeDriver: true,
    }).start();
  }, [slideAnim]);

  return (
    <View style={styles.container}>
      <Animated.View
        style={[
          styles.slidingContainer,
          { transform: [{ translateX: slideAnim }] },
        ]}
      >
        <View style={styles.box} />
      </Animated.View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
  slidingContainer: {
    width: 100,
    height: 100,
  },
  box: {
    width: 100,
    height: 100,
    backgroundColor: "green",
  },
});

export default SlideInExample;

Ví Dụ 3: Hoạt Hình Lò Xo (Spring)

javascript Copy
import React, { useRef, useEffect } from "react";
import { View, Animated, StyleSheet } from "react-native";

const SpringExample = () => {
  const springAnim = useRef(new Animated.Value(0.5)).current;

  useEffect(() => {
    Animated.spring(springAnim, {
      toValue: 1,
      friction: 2,
      tension: 160,
      useNativeDriver: true,
    }).start();
  }, [springAnim]);

  return (
    <View style={styles.container}>
      <Animated.View
        style={[styles.springContainer, { transform: [{ scale: springAnim }] }]}
      >
        <View style={styles.box} />
      </Animated.View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
  springContainer: {
    width: 100,
    height: 100,
  },
  box: {
    width: 100,
    height: 100,
    backgroundColor: "red",
  },
});

export default SpringExample;

Tùy Chỉnh Animated

Sử Dụng Animated.sequence

Bạn có thể sử dụng Animated.sequence để chạy các hoạt hình theo thứ tự.

Ví dụ:

javascript Copy
import React, { useRef, useEffect } from "react";
import { View, Animated, StyleSheet } from "react-native";

const SequenceExample = () => {
  const fadeAnim = useRef(new Animated.Value(0)).current;
  const slideAnim = useRef(new Animated.Value(-200)).current;

  useEffect(() => {
    Animated.sequence([
      Animated.timing(fadeAnim, {
        toValue: 1,
        duration: 1000,
        useNativeDriver: true,
      }),
      Animated.timing(slideAnim, {
        toValue: 0,
        duration: 1000,
        useNativeDriver: true,
      }),
    ]).start();
  }, [fadeAnim, slideAnim]);

  return (
    <View style={styles.container}>
      <Animated.View
        style={[
          styles.fadingContainer,
          { opacity: fadeAnim, transform: [{ translateX: slideAnim }] },
        ]}
      >
        <View style={styles.box} />
      </Animated.View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
  fadingContainer: {
    width: 100,
    height: 100,
  },
  box: {
    width: 100,
    height: 100,
    backgroundColor: "blue",
  },
});

export default SequenceExample;

Sử Dụng Animated.parallel

Bạn có thể sử dụng Animated.parallel để chạy các hoạt hình song song.

Ví dụ:

javascript Copy
import React, { useRef, useEffect } from "react";
import { View, Animated, StyleSheet } from "react-native";

const ParallelExample = () => {
  const fadeAnim = useRef(new Animated.Value(0)).current;
  const slideAnim = useRef(new Animated.Value(-200)).current;

  useEffect(() => {
    Animated.parallel([
      Animated.timing(fadeAnim, {
        toValue: 1,
        duration: 1000,
        useNativeDriver: true,
      }),
      Animated.timing(slideAnim, {
        toValue: 0,
        duration: 1000,
        useNativeDriver: true,
      }),
    ]).start();
  }, [fadeAnim, slideAnim]);

  return (
    <View style={styles.container}>
      <Animated.View
        style={[
          styles.fadingContainer,
          { opacity: fadeAnim, transform: [{ translateX: slideAnim }] },
        ]}
      >
        <View style={styles.box} />
      </Animated.View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
  fadingContainer: {
    width: 100,
    height: 100,
  },
  box: {
    width: 100,
    height: 100,
    backgroundColor: "blue",
  },
});

export default ParallelExample;

Sử Dụng Thư Viện Bên Ngoài

Nếu bạn cần các hoạt hình phức tạp hơn, bạn có thể sử dụng các thư viện bên ngoài như react-native-reanimated hoặc react-native-animatable.

Sử Dụng react-native-reanimated

Cài Đặt Thư Viện

bash Copy
npm install react-native-reanimated

Sử Dụng Thư Viện

javascript Copy
import React from "react";
import { View, StyleSheet } from "react-native";
import Animated, { Easing } from "react-native-reanimated";

const { Value, timing } = Animated;

const ReanimatedExample = () => {
  const opacity = new Value(0);

  const animate = () => {
    timing(opacity, {
      toValue: 1,
      duration: 2000,
      easing: Easing.inOut(Easing.ease),
    }).start();
  };

  return (
    <View style={styles.container} onLayout={animate}>
      <Animated.View style={[styles.box, { opacity }]} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
  box: {
    width: 100,
    height: 100,
    backgroundColor: "blue",
  },
});

export default ReanimatedExample;

Sử Dụng react-native-animatable

Cài Đặt Thư Viện

bash Copy
npm install react-native-animatable

Sử Dụng Thư Viện

javascript Copy
import React from "react";
import { View, StyleSheet } from "react-native";
import * as Animatable from "react-native-animatable";

const AnimatableExample = () => {
  return (
    <View style={styles.container}>
      <Animatable.View animation="fadeIn" duration={2000} style={styles.box} />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
  box: {
    width: 100,
    height: 100,
    backgroundColor: "blue",
  },
});

export default AnimatableExample;

Các Kỹ Thuật Tối Ưu Hóa Sử Dụng Animated

Sử Dụng useNativeDriver

Sử dụng useNativeDriver để tối ưu hóa hiệu suất của hoạt hình bằng cách chuyển các tính toán hoạt hình sang native thread.

Ví dụ:

javascript Copy
Animated.timing(fadeAnim, {
  toValue: 1,
  duration: 2000,
  useNativeDriver: true,
}).start();

Sử Dụng StyleSheet để Tối Ưu Hóa Hiệu Suất

Sử dụng StyleSheet.create để định nghĩa các style giúp tối ưu hóa hiệu suất vì các style được tạo ra chỉ một lần và được tham chiếu lại nhiều lần.

Ví dụ:

javascript Copy
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
});

Các Hạn Chế của Animated Component

Mặc dù Animated component trong React Native rất mạnh mẽ, nhưng nó cũng có một số hạn chế:

  1. Độ Phức Tạp: Khi tạo ra các hoạt hình phức tạp, mã nguồn có thể trở nên khó đọc và bảo trì.
  2. Hiệu Suất: Khi sử dụng quá nhiều hoạt hình lồng nhau, hiệu suất của ứng dụng có thể bị ảnh hưởng.
  3. Tùy Chỉnh Giao Diện: Animated không hỗ trợ nhiều tùy chỉnh giao diện như thay đổi font chữ, thêm biểu tượng, hoặc tạo nền gradient.

Kết Luận

Animated là một thành phần cơ bản và quan trọng trong React Native, giúp bạn tạo ra các giao diện người dùng mượt mà và hiệu quả. Bằng cách hiểu rõ các thuộc tính và cách sử dụng Animated, bạn có thể tạo ra các giao diện người dùng mượt mà và hiệu quả. Hy vọng qua bài viết này, bạn đã có thể nắm bắt được cách sử dụng Animated trong React Native và áp dụng vào các dự án của mình.

Avatar
Được viết bởi

Admin Team

Gợi ý câu hỏi phỏng vấn

Không có dữ liệu

Không có dữ liệu

Gợi ý bài viết
Không có dữ liệu

Không có dữ liệu

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào