الدرس 16 · الوحدة 8: التفاعل مع الحساسات والأجهزة الذكية باستخدام APIs
مستشعر الضوء وتبديل الثيم (نهار/ليل)
واجهةٌ تتكيّف مع إضاءة المحيط. ⏱ نحو 40 دقيقة.
بعد هذا الدرس ستستطيع أن:
- تقرأ مستشعر الضوء وتشتقّ منه قرارًا.
- تبني ثيمًا يتبدّل تلقائيًّا بالإضاءة.
- تمزج القراءة التلقائيّة بتفضيل المستخدم.
١الضوء يقود الواجهة
تطبيقٌ ذكيّ يتكيّف مع محيطه. مستشعر الضوء يقيس سطوع المكان (لَكس)؛ منه نقرّر الوضع الليليّ تلقائيًّا: خلفيّةٌ داكنة وراحةٌ للعين في الإضاءة المنخفضة.
٢ثيم يتبدّل بالضوء
نشتقّ كائن ثيمٍ من قراءة الضوء، ونطبّقه على الواجهة كلّها. حرّك منزلق الضوء وراقب التحوّل:
import { View, Text, StyleSheet } from 'react-native';import { useLight } from 'smartdevice'; export default function App() { const lux = useLight(); const dark = lux < 50; const theme = dark ? { bg: '#15202B', fg: '#E8F0F7', sub: '#9FB3C8', tag: '🌙 الوضع الليليّ' } : { bg: '#FFF8E1', fg: '#3A2E00', sub: '#8A6D00', tag: '☀️ الوضع النهاريّ' }; return ( <View style={[styles.box, { backgroundColor: theme.bg }]}> <Text style={[styles.tag, { color: theme.fg }]}>{theme.tag}</Text> <Text style={[styles.lux, { color: theme.sub }]}>الإضاءة: {lux} lux</Text> <View style={[styles.card, { borderColor: theme.sub }]}> <Text style={{ color: theme.fg }}>تتبدّل الألوان تلقائيًّا مع الإضاءة.</Text> </View> </View> );} const styles = StyleSheet.create({ box: { padding: 24, minHeight: 200, borderRadius: 14, margin: 10 }, tag: { fontSize: 22, fontWeight: 'bold' }, lux: { marginTop: 6, fontSize: 14 }, card: { marginTop: 14, padding: 14, borderWidth: 1, borderRadius: 10 },});
كائن theme واحد يغذّي كل الألوان — نمطٌ نظيف لإدارة الثيمات.
٣تجاوز يدويّ + تلقائيّ
أفضل تجربةٍ: تلقائيّ افتراضًا، مع سماحٍ للمستخدم بالتجاوز. نحفظ خيار المستخدم في حالة، ونعود للتلقائيّ عند «تلقائيّ»:
import { useState } from 'react';import { View, Text, Pressable, StyleSheet } from 'react-native';import { useLight } from 'smartdevice'; export default function App() { const lux = useLight(); const [mode, setMode] = useState('auto'); // auto | light | dark const dark = mode === 'auto' ? lux < 50 : mode === 'dark'; return ( <View style={[styles.box, { backgroundColor: dark ? '#15202B' : '#FFF8E1' }]}> <Text style={{ color: dark ? '#fff' : '#333', fontWeight: 'bold', fontSize: 18 }}> {dark ? '🌙 ليليّ' : '☀️ نهاريّ'} ({mode}) </Text> <View style={styles.row}> {['auto', 'light', 'dark'].map((m) => ( <Pressable key={m} style={[styles.btn, mode === m && styles.on]} onPress={() => setMode(m)}> <Text style={{ color: mode === m ? '#fff' : '#E8820C' }}>{m}</Text> </Pressable> ))} </View> </View> );} const styles = StyleSheet.create({ box: { padding: 20, minHeight: 170, borderRadius: 14, margin: 10 }, row: { flexDirection: 'row', gap: 8, marginTop: 16 }, btn: { borderWidth: 1, borderColor: '#E8820C', borderRadius: 8, paddingVertical: 6, paddingHorizontal: 12 }, on: { backgroundColor: '#E8820C' },});
«auto» يتبع المستشعر؛ «light/dark» يتجاوزانه. مزيجٌ من الحسّاس وتفضيل المستخدم.
توقّع وتحقّق
مستشعر الضوء يفيد في:
كيف نطبّق الثيم على الواجهة كلّها؟
أفضل تجربة ثيم:
قيمة الضوء المنخفضة تعني:
الخلاصة
- مستشعر الضوء يقيس السطوع (لَكس) فنقرّر الوضع الليليّ.
- نشتقّ كائن ثيمٍ واحدًا ونغذّي به كل الألوان.
- أفضل تجربة: تلقائيّ مع تجاوزٍ يدويّ.
تحدٍّ برمجي: شارة نهار/ليل
متوسطاقرأ الضوء واعرض الوضع المناسب.
المطلوب:
- استورد
useLight. <Text testID="mode">: إن كان الضوء أقلّ من 50 «ليل» وإلا «نهار».- غيّر خلفيّة
Viewبحسب الوضع.
👀 اعرض الناتج المطلوب (وجرّبه)
✓ التحقق الآلي من حلّك:
- الكود يعمل بلا أخطاء في Console
- يبدأ نهارًا (الضوء 70)
- استُخدم useLight
- شرط العتبة 50
💡 تلميح 1
القيمة الابتدائيّة 70 ≥ 50 فالوضع «نهار».
💡 تلميح 2
الشرط:
lux < 50.حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.
import { View, Text } from 'react-native';import { useLight } from 'smartdevice'; export default function App() { const lux = useLight(); const dark = lux < 50; return ( <View style={{ padding: 24, backgroundColor: dark ? '#15202B' : '#FFF8E1' }}> <Text testID="mode" style={{ color: dark ? '#fff' : '#333', fontSize: 22, fontWeight: 'bold' }}> {dark ? 'ليل' : 'نهار'} </Text> </View> );}