Áp dụng hiệu ứng bóng hộp trong React Native
Blog

Áp dụng hiệu ứng bóng hộp trong React Native

Áp dụng hiệu ứng bóng hộp trong ứng dụng React Native không phải lúc nào cũng đơn giản. Bởi vì phải xây dựng cho cả nền tảng Android và iOS, việc áp dụng bóng hộp một cách nhất quán trên cả hai nền tảng có thể khá phức tạp.

Trong bài viết này, chúng ta sẽ tìm hiểu cách triển khai hiệu ứng bóng hộp trong ứng dụng React Native trên cả nền tảng Android và iOS.

Sử dụng đặc tính tạo bóng cho bóng hộp iOS

Để tạo hiệu ứng bóng cho thành phần trên thiết bị iOS, chúng ta có thể sử dụng bốn đặc tính tạo bóng của React Native.

Đặc tính đầu tiên là shadowColor, xác định màu của bóng hộp. Lưu ý rằng đây là đặc tính chỉ hoạt động trên các thiết bị Android.

Đặc tính thứ hai là shadowOffset, chứa thuộc tính width và height với giá trị là một số:

{ width: số; height: số}

Vì được mô tả bằng hiệu số X và Y so với thành phần được áp dụng bóng, thuộc tính width xác định độ lệch X của bóng, trong khi thuộc tính height xác định bù phụ Y.

Cả width và height đều có thể nhận giá trị âm và dương.

Đặc tính thứ ba là shadowOpacity, xác định độ trong suốt của bóng hộp. Giá trị của thuộc tính nằm trong khoảng từ 0 đến 1, trong đó 0 tương đương với hoàn toàn trong suốt và 1 tương đương với hoàn toàn mờ.

Đặc tính thứ tư là shadowRadius, nhận một số làm giá trị để đặt bán kính mờ của thành phần. Giá trị càng lớn, độ mờ càng lớn, tạo nên hiệu ứng bóng lớn và nhẹ nhàng hơn. Đặc tính này không nhận giá trị âm.

Hãy sử dụng những đặc tính này bằng cách áp dụng hiệu ứng bóng hộp cho một thành phần div như sau:

<View style={[styles.card, styles.shadowProp]}>
  <View>
    <Text style={styles.heading}>React Native Field Shadow (Shadow Props)</Text>
  </View>
  <Text>Using the elevation style prop to apply box-shadow for iOS devices</Text>
</View>

Tiếp theo, nhập StyleSheet để áp dụng nhiều kiểu cho thành phần div:

import { StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  heading: {
    fontSize: 18,
    fontWeight: '600',
    marginBottom: 13,
  },
  card: {
    backgroundColor: 'white',
    borderRadius: 8,
    paddingVertical: 45,
    paddingHorizontal: 25,
    width: '100%',
    marginVertical: 10,
  },
  shadowProp: {
    shadowColor: '#171717',
    shadowOffset: { width: -2, height: 4 },
    shadowOpacity: 0.2,
    shadowRadius: 3,
  },
});

Với mã này, ứng dụng của bạn sẽ hiển thị một thành phần div có hiệu ứng bóng hộp.

Áp dụng hiệu ứng bóng hộp trong React Native

Thêm hỗ trợ bóng cho Android

Để thêm hiệu ứng bóng cho Android, chúng ta có thể sử dụng đặc tính elevation, sử dụng API độ cao của Android.

Để tìm hiểu cách áp dụng hiệu ứng bóng với phương pháp này, hãy áp dụng hiệu ứng bóng hộp cho một thành phần div. Lưu ý rằng đặc tính elevation chỉ hoạt động khi được áp dụng cho một thành phần div:

<View style={[styles.card, styles.elevation]}>
  <View>
    <Text style={styles.heading}>React Native Field Shadow (Elevation)</Text>
  </View>
  <Text>Using the elevation style prop to apply box-shadow for Android devices</Text>
</View>

Tiếp theo, nhập StyleSheet một lần nữa để tạo kiểu cho thành phần div:

import { StyleSheet } from 'react-native';

const styles = StyleSheet.create({
  heading: {
    fontSize: 18,
    fontWeight: '600',
    marginBottom: 13,
  },
  card: {
    backgroundColor: 'white',
    borderRadius: 8,
    paddingVertical: 45,
    paddingHorizontal: 25,
    width: '100%',
    marginVertical: 10,
  },
  elevation: {
    elevation: 20,
    shadowColor: '#52006A',
  },
});

Bằng cách đặt elevation thành 20 với một shadowColor, chúng ta có thể áp dụng hiệu ứng bóng hộp cho thành phần div Android của chúng ta.

Lưu ý rằng chúng ta không có quyền kiểm soát bán kính mờ, độ mờ và độ lệch của hiệu ứng bóng hộp; chúng ta chỉ có thể kiểm soát màu của bóng đổ.

Hiệu ứng bóng hộp đa nền tảng React Native

Trong phần này, chúng ta sẽ kết hợp đặc tính elevation và đặc tính shadow để triển khai hiệu ứng bóng hộp cho cả thiết bị Android và iOS thay vì sử dụng hai phương pháp riêng biệt.

Sử dụng API nền tảng từ React Native, hãy tạo một hàm mà chúng ta có thể gọi để hiển thị hiệu ứng bóng hộp có điều kiện cho thành phần div dựa trên thiết bị của người dùng.

Chúng ta sẽ bắt đầu bằng cách tạo thành phần div:

<View style={[styles.card, styles.boxShadow]}>
  <View>
    <Text style={styles.heading}>React Native cross-platform field shadow</Text>
  </View>
  <Text>Using the Platform API to conditionally render field shadow</Text>
</View>

Tiếp theo, dưới đối tượng styles của chúng ta, hãy tạo một hàm generateBoxShadowStyle áp dụng hiệu ứng bóng hộp dựa trên hệ điều hành của người dùng:

const generateBoxShadowStyle = (
  xOffset,
  yOffset,
  shadowColorIos,
  shadowOpacity,
  shadowRadius,
  elevation,
  shadowColorAndroid,
) => {
  if (Platform.OS === 'ios') {
    styles.boxShadow = {
      shadowColor: shadowColorIos,
      shadowOffset: { width: xOffset, height: yOffset },
      shadowOpacity,
      shadowRadius,
    };
  } else if (Platform.OS === 'android') {
    styles.boxShadow = {
      elevation,
      shadowColor: shadowColorAndroid,
    };
  }
};

Với đoạn mã chúng ta vừa triển khai, ứng dụng của chúng ta đã có thể kiểm tra nền tảng thiết bị của người dùng và áp dụng các đặc tính tạo bóng hộp thích hợp.

Tiếp theo, hãy gọi hàm generateBoxShadowStyle và truyền giá trị của các đặc tính tạo bóng và elevation của chúng ta làm đối số:

generateBoxShadowStyle(-2, 4, '#171717', 0.2, 3, 4, '#171717');

Sau đó, nó sẽ hiển thị những điều sau cho cả hai nền tảng:

Sử dụng API nền tảng để hiển thị hiệu ứng bóng hộp trong cả iOS và Android

Để đơn giản hóa quy trình làm việc của chúng ta, hãy sử dụng công cụ React Native Shadow Generator để tạo mã cho hiệu ứng bóng hộp và xem trước kết quả hiệu ứng bóng hộp trên cả Android và iOS.

Giới hạn của hiệu ứng bóng hộp đa nền tảng

Mặc dù chúng ta áp dụng hiệu ứng bóng hộp tiêu chuẩn, có những trường hợp sử dụng khi chúng ta có thể cần mức độ kiểm soát cao hơn đối với độ lệch, độ mờ và bán kính mờ của hiệu ứng bóng hộp. Điều này có thể bao gồm:

  • Áp dụng hiệu ứng bóng hộp cho thành phần FlatList hoặc Pressable với kiểu tùy chỉnh
  • Thêm thiết kế hiệu ứng bóng hộp tùy chỉnh nhất quán trên cả Android và iOS

Với cách triển khai hiện tại, tính linh hoạt trong thiết kế này không thể. Tuy nhiên, chúng ta có thể vượt qua những hạn chế này với react-native-drop-shadow.

Áp dụng hiệu ứng bóng hộp với react-native-drop-shadow

Gói react-native-drop-shadow là một thành phần View lấy thành phần con của nó, tạo một biểu diễn bitmap, sau đó làm mờ và tô màu nó với giá trị bóng của loại, tương tự như việc áp dụng hiệu ứng bóng trong iOS với các đặc tính tạo bóng.

Để bắt đầu, hãy cài đặt gói react-native-drop-shadow bằng một trong các lệnh sau:

yarn add react-native-drop-shadow #hoặc npm i react-native-drop-shadow

Sau khi quá trình cài đặt hoàn tất, hãy đồng bộ lại công cụ xây dựng Gradle của Android hoặc khởi động lại máy chủ phát triển.

Tiếp theo, chúng ta có thể nhập gói:

import DropShadow from "react-native-drop-shadow";

Bây giờ, hãy tạo một nút tùy chỉnh bằng cách sử dụng thành phần Pressable và bao nó bằng thành phần DropShadow chúng ta vừa nhập.

Hiệu ứng bóng trên nút trong ảnh chụp màn hình dưới đây là những gì chúng ta muốn tạo ra. Hãy để ý tính nhất quán trên cả nền tảng Android và iOS:

//wherever your return statement is
// Don't forget to import the Pressable element from react-native
<DropShadow style={styles.shadowProp}>
  <Pressable style={styles.button} onPress={() => console.log('pressed')}>
    <Text style={(styles.text, styles.buttonText)}>See more</Text>
  </Pressable>
</DropShadow>

Để làm cho thành phần Pressable trông giống một nút và thêm hiệu ứng bóng vào thành phần DropShadow, thêm các quy tắc kiểu sau:

const styles = StyleSheet.create({
  shadowProp: {
    shadowColor: '#171717',
    shadowOffset: { width: 0, height: 3 },
    shadowOpacity: 0.4,
    shadowRadius: 2,
  },
  button: {
    backgroundColor: '#4830D3',
    alignItems: 'center',
    justifyContent: 'center',
    height: 42,
    borderRadius: 4,
    marginTop: 30,
  },
  buttonText: {
    color: '#fff',
  },
  text: {
    fontSize: 16,
    lineHeight: 21,
    fontWeight: 'bold',
    letterSpacing: 0.25,
  },
});

Sử dụng react-native-shadow-2

Gói react-native-shadow-2 là một phiên bản nâng cấp của react-native-shadow bằng cách cung cấp nhiều tính năng hơn, hỗ trợ Typecript và được viết lại từ đầu để giảm sự phụ thuộc và tối ưu hiệu suất.

Khác với việc triển khai hiệu ứng bóng với react-native-drop-shadow, tạo ra một biểu diễn bitmap của các thành phần con của nó, react-native-shadow-2 sử dụng plugin shadow react-native-svg để triển khai nhất quán trên cả nền tảng Android và iOS.

Để bắt đầu, hãy cài đặt cả hai gói này trong thư mục gốc của dự án:

yarn add react-native-svg react-native-shadow-2 #hoặc npm i react-native-svg react-native-shadow-2

Để đảm bảo điều này chạy trên iOS, di chuyển vào thư mục ios và chạy lệnh pod install để đồng bộ hóa các gói chúng tôi vừa cài đặt:

cd ios
pod install

Import gói ở đầu tập tin:

import { Shadow } from 'react-native-shadow-2';

Ở bất kỳ nơi nào có lệnh return của bạn:

<Shadow distance={5} startColor={'#00000010'} containerViewStyle={{ marginVertical: 20 }} radius={8}>
  <View style={[styles.card, { marginVertical: 0 }]}>
    <View>
      <Text style={styles.heading}>React Native cross-platform field shadow</Text>
    </View>
    <Text style={styles.boxShadow}>Using the Platform API to conditionally render field shadow</Text>
    <DropShadow style={styles.shadowProp}>
      <Pressable style={styles.button} onPress={() => console.log('pressed')}>
        <Text style={(styles.text, styles.buttonText)}>See more</Text>
      </Pressable>
    </DropShadow>
  </View>
</Shadow>

Mã sẽ tạo ra kết quả như sau:

Sử dụng React-Native-Shadow-2 để áp dụng Box Shadow bên dưới thẻ trong iOS và Android

Kết luận

Vấn đề chính với các đặc tính tạo bóng trong React Native là chúng không thể sử dụng trong các ứng dụng Android.

Tuy nhiên, bằng cách sử dụng react-native-drop-shadow và react-native-shadow-2, chúng ta có thể dễ dàng triển khai hiệu ứng bóng hộp nhất quán vào các ứng dụng React Native của mình cho cả nền tảng Android và iOS.

Mã đầy đủ được sử dụng trong hướng dẫn này có sẵn trên GitHub. Hãy để lại một bình luận để cho tôi biết suy nghĩ của bạn về bài viết này. Bạn cũng có thể tìm thấy tôi trên Twitter và GitHub. Cảm ơn bạn đã đọc!

Rate this post