วิธีสร้างเลย์เอาต์ที่ตอบสนองใน React Native

เผยแพร่แล้ว: 2019-10-10

นักพัฒนา Native Apps มักใช้ความพยายามอย่างมากในการสร้างแอปที่สวยงามด้วย UI ที่สมบูรณ์และมีความเสถียรในอุปกรณ์ที่รองรับทุกเครื่อง สำหรับ iOS นี่หมายถึงอุปกรณ์เพียงไม่กี่เครื่อง สำหรับ Android อาจมีมากกว่าหนึ่งโหล

เมื่อคุณพัฒนาแอปด้วย React Native คุณสามารถเพิ่มตัวเลขเหล่านี้แล้วคูณด้วยสอง เนื่องจากทุกอุปกรณ์สามารถหมุนได้ ในบทความสั้น ๆ นี้ ฉันจะพยายามแสดงให้คุณเห็นเครื่องมือและลูกเล่นสองสามอย่าง ซึ่งสามารถช่วยคุณจัดการกับอุปกรณ์หลากหลายประเภทโดยไม่ต้องคลั่งไคล้!

1. ก่อนอื่น FLEXBOX

ส่วนประกอบสามารถควบคุมเค้าโครงด้วยอัลกอริธึม flexbox สร้างขึ้นเพื่อรักษาสัดส่วนและความสอดคล้องของเลย์เอาต์ในขนาดหน้าจอต่างๆ

Flexbox ทำงานคล้ายกับ CSS บนเว็บมาก โดยมีข้อยกเว้นเพียงไม่กี่ข้อที่เรียนรู้ได้ง่ายมาก เมื่อ flex prop เป็นจำนวนบวก ส่วนประกอบจะมีความยืดหยุ่น และจะปรับให้เข้ากับหน้าจอตามลำดับค่า flex ของมัน นั่นหมายความว่า flex เท่ากับ flexGrow: [number], flexShrink: 1, flexBasis: 0

เมื่อ flex: 0 — มีขนาดตามความสูงและความกว้างและไม่ยืดหยุ่น
ถ้า flex เป็นจำนวนลบ จะใช้ความสูงและความกว้างด้วย แต่ถ้ามีพื้นที่ไม่เพียงพอ จะย่อขนาดเป็น minHeight และ minWidth

flexbox มีคุณสมบัติหลักสองสามอย่าง ดังนั้น มาทำความเข้าใจกัน!
Flex อธิบายว่าองค์ประกอบแบ่งช่องว่างระหว่างกันอย่างไร ดังที่ได้กล่าวไว้ข้างต้น จำกัด เฉพาะตัวเลขเดียว

หากองค์ประกอบทั้งหมดมีความยืดหยุ่น: 1 พวกมันจะมีความกว้างเท่ากัน
ในกรณีอื่นๆ พวกเขาจะแยกผลรวมของเฟล็กซ์ระหว่างกัน

องค์ประกอบทั้งหมดที่มีการดิ้น: 1
องค์ประกอบที่มีความโค้งงอ: 1 และโค้งงอ: 2

ทิศทางแบบยืดหยุ่น — เราสามารถเลือกแถวหรือคอลัมน์ (คุณยังสามารถตั้งค่าการกลับด้าน) เพื่อกำหนดแกนหลักของคุณตามตำแหน่งที่จะวางเนื้อหาของคุณ โดยค่าเริ่มต้น flexDirection ถูกตั้งค่าเป็นคอลัมน์แทนที่จะเป็นแถว ซึ่งเกิดจากลักษณะของหน้าจอบนอุปกรณ์เคลื่อนที่

justifyContent — พร็อพนี้ช่วยให้คุณจัดตำแหน่งเนื้อหาภายในคอนเทนเนอร์ตามแกนหลัก คุณสามารถตรวจสอบตำแหน่งที่เป็นไปได้บางส่วนด้านล่าง:

justifyContent - 3 ตำแหน่งที่เป็นไปได้

จัดแนวรายการ — ทำงานเหมือนกับ justifyContent แต่จัดตำแหน่งรายการบนแกนตั้งฉากกับแกนหลัก

Flex prop ทำงานได้ดีมากในการรักษาสัดส่วนระหว่างองค์ประกอบต่างๆ โดยไม่คำนึงถึงขนาดหน้าจอ FlexDirection และ justifyContent ทำให้ลักษณะการทำงานของเลย์เอาต์สอดคล้องกัน

มีอุปกรณ์ประกอบฉากเฟล็กซ์บ็อกซ์อีกมากมาย ฉันสัมผัสเพียงไม่กี่เพื่อแสดงให้เห็นว่าสิ่งเหล่านี้มีประโยชน์อย่างไร

2. อัตราส่วนภาพ

อุปกรณ์ประกอบฉากที่ยอดเยี่ยมอีกประการหนึ่งคืออัตราส่วนกว้างยาว (มีให้ใน React Native เท่านั้น) ซึ่งช่วยให้สัดส่วนขององค์ประกอบของคุณอยู่ภายใต้การควบคุม หากคุณรู้องค์ประกอบของคุณเพียงมิติเดียว (ความกว้างหรือความสูง) ก็จะรักษามิติที่สองให้สัมพันธ์กับมิติที่คุณทราบอยู่แล้ว

ตัวอย่างอัตราส่วนภาพ

3. ขนาดหน้าจอ

จะดีมากเมื่อการออกแบบของคุณเหมือนกันสำหรับทั้งสองแพลตฟอร์มและอุปกรณ์ทุกประเภท (มือถือ แท็บเล็ต iPad) อย่างไรก็ตาม บางครั้งเราต้องจัดการกับรูปแบบที่แตกต่างกันสำหรับขนาดหน้าจอหรือประเภทอุปกรณ์ที่เฉพาะเจาะจง

ตามค่าเริ่มต้น React Native ไม่ได้ให้คุณสมบัติที่ตอบได้ชัดเจนว่าอุปกรณ์ใดหรือขนาดหน้าจอใด แต่มีวิธีแก้ไขสำหรับเรื่องนี้

หากต้องการทราบว่าขนาดหน้าจอคืออะไร เราสามารถใช้ไดเมนชัน API

 import { Dimensions } from 'react-native'; const {width, height} = Dimensions.get('window');

ตั้งแต่ React Native 0.61 คุณสามารถใช้เบ็ดได้

 const {width, height} = useWindowDimensions();

เมื่อเราได้ความกว้างจากขนาดหน้าจอของช่วงที่รองรับแล้ว คุณสามารถเลือกจุดสั่งหยุดที่เลย์เอาต์ของคุณสามารถเปลี่ยนได้ คุณสามารถจัดเตรียมรูปแบบต่างๆ ให้กับส่วนประกอบหรือซ่อนบางส่วนของหน้าจอได้ ลักษณะการทำงานนี้คล้ายกับคิวรี สื่อ ที่ใช้ใน CSS

 import { Text, View, Dimensions } from 'react-native'; class App extends PureComponent { constructor(props) { super(props); this.state = { width: Dimensions.get('window').width }; } render() { return ( <View> {this.state.width < 320 ? <Text>width of the past</Text> : <Text>how big is big enough?</Text>} </View> ); } }

4. ตรวจจับแพลตฟอร์ม

นอกจากขนาดหน้าจอแล้ว คุณยังสามารถเปลี่ยนเลย์เอาต์ได้ขึ้นอยู่กับว่าแอพแพลตฟอร์มใดที่เปิดตัว เพื่อให้บรรลุสิ่งนี้ เราสามารถใช้โมดูลแพลตฟอร์ม

มีหลายกรณีที่สามารถใช้งานได้:
ในฟังก์ชันการแสดงผลคอมโพเนนต์:

 <View> {Platform.OS === 'ios' ? <Text>Hi Apple!</Text> : <Text>Hi Android!</Text>} </View>

ในรูปแบบ:

 cube: { width: Platform.OS === 'ios' ? 200 : 300, aspectRatio: 1 }

โมดูลแพลตฟอร์มมีวิธีการเลือกซึ่งสามารถยอมรับการโต้แย้งประเภทใดก็ได้ ด้วยความยืดหยุ่นนี้ เราสามารถบรรลุผลเช่นเดียวกับข้างต้น แต่โค้ดที่สะอาดกว่า:

 const Logo = Platform.select({ ios: () => require('Apple'), android: () => require('Android'), })(); <Logo />;

ในรูปแบบ:

 import {Platform, StyleSheet} from 'react-native'; const styles = StyleSheet.create({ container: { flex: 1, ...Platform.select({ ios: { backgroundColor: 'red', }, android: { backgroundColor: 'blue', }, }), }, });

5. การหมุนอุปกรณ์

แอพจำนวนมากสามารถทำงานในโหมดแนวตั้งและแนวนอน หากเป็นกรณีนี้สำหรับแอปของคุณ คุณต้องแน่ใจว่าเลย์เอาต์ไม่แตกเมื่อเปลี่ยนการวางแนว อย่างที่คุณคาดหวังได้ในบางครั้ง เลย์เอาต์สามารถเปลี่ยนแปลงได้อย่างมากเมื่อคุณพลิกอุปกรณ์ ส่วนประกอบของคุณอาจต้องการสไตล์ที่แตกต่างกันขึ้นอยู่กับการวางแนว ขออภัย โดยค่าเริ่มต้น การหมุนอุปกรณ์จะไม่ทริกเกอร์การเรนเดอร์ใหม่ จึงต้องจัดการด้วยตนเอง เรามีความรู้ที่จำเป็นในการสร้างของเราเองแล้วและค่อนข้างง่าย!

 class RotateComponent extends PureComponent { constructor(props) { super(props); this.state = { orientation: '' }; } getOrientation = () => { if (Dimensions.get('window').width < Dimensions.get('window').height) { this.setState({ orientation: 'portrait' }); } else { this.setState({ orientation: 'landscape' }); } }; componentDidMount() { Dimensions.addEventListener('change', this.getOrientation); } render() { return ( <Text>{this.state.orientation}</Text> ); } }

หากคุณต้องการสนับสนุนการเปลี่ยนการวางแนวในแอป ควรใช้ HOC เพื่อฉีดการวางแนว

const HOC = WrappedComponent => คลาสขยาย PureComponent { ตัวสร้าง (อุปกรณ์ประกอบฉาก) { สุดยอด (อุปกรณ์ประกอบฉาก); this.state = { ปฐมนิเทศ: ” }; } componentDidMount () { Dimensions.addEventListener ('เปลี่ยน', this.getOrientation); } getOrientation = () => { if (Dimensions.get('window').width ; } };

นั่นคือทั้งหมด! คุณยังสามารถส่งผ่าน getOrientation ไปยัง onLayout prop ที่เปิดเผยโดยองค์ประกอบ View มันมีผลกับการเปลี่ยนแปลงเลย์เอาต์ทุกครั้ง ดังนั้นควรใช้อย่างระมัดระวัง การตัดสินใจเป็นของคุณ!

ไอคอนแอพเนทีฟ

อยากรู้เกี่ยวกับ React Native?

เรียนรู้เพิ่มเติม

หากคุณต้องการใช้ประโยชน์จากการวางแนวในสไตล์ของคุณ จำไว้ว่าควรเป็นสไตล์อินไลน์ เรารู้วิธีทริกเกอร์การเรนเดอร์เลย์เอาต์ใหม่เมื่อหมุนอุปกรณ์แล้ว แต่สไตล์จะโหลดเพียงครั้งเดียว นั่นเป็นเหตุผลที่รูปแบบที่ส่งผลต่อการจัดวางในการหมุนควรอยู่ในบรรทัด

อย่างที่คุณคาดไว้ ชุมชน React Native ขนาดใหญ่มีแพ็คเกจที่แก้ปัญหามากมายที่กล่าวถึงในที่นี้แล้ว คุณสามารถตรวจสอบได้ที่นี่หรือที่นี่เพื่อระบุชื่อบางส่วน