طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 251 · برمجة الأجهزة الذكية
الدرس 19 · الوحدة 9: تكامل التفاعل مع المستشعرات في تطبيقات الأجهزة الذكية

تطبيق «الميزان»: يدمج الإمالة

أول تطبيقٍ متكامل يدمج مستشعر الإمالة. ⏱ نحو 40 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تدمج قراءة مستشعرٍ في تطبيقٍ كامل.
  • تحرّك عنصرًا بالإمالة ضمن حدود.
  • تفصل منطق القراءة عن العرض.

١من مستشعرٍ إلى تطبيق

تعلّمنا قراءة المستشعرات مفردة. الآن ندمجها في تطبيقٍ كامل. نبدأ بأداة «الميزان» (Level): تستخدم الإمالة لتخبرك هل السطح مستوٍ، بفقاعةٍ تتحرّك كالميزان الحقيقيّ.

٢الفقاعة تتحرّك

نضع فقاعةً داخل دائرة؛ موضعها يتبع الإمالة. حين تقترب من المركز تتحوّل للأخضر. حرّك المنزلقين:

import { View, Text, StyleSheet } from 'react-native';import { useTilt } from 'smartdevice'; export default function App() {  const { x, y } = useTilt();  const level = Math.abs(x) <= 3 && Math.abs(y) <= 3;  const bx = Math.max(-70, Math.min(70, x * 2));  const by = Math.max(-70, Math.min(70, y * 2));  return (    <View style={styles.wrap}>      <View style={styles.dial}>        <View style={styles.center} />        <View style={[styles.bubble,          { backgroundColor: level ? '#2E7D32' : '#E8820C',            transform: [{ translateX: bx }, { translateY: by }] }]} />      </View>      <Text testID="status" style={[styles.status, { color: level ? '#2E7D32' : '#E8820C' }]}>        {level ? '✅ مستوٍ' : '↕ مائل'}      </Text>      <Text style={styles.read}>x={x}°  y={y}°</Text>    </View>  );} const styles = StyleSheet.create({  wrap: { padding: 16, alignItems: 'center' },  dial: { width: 180, height: 180, borderRadius: 90, borderWidth: 2, borderColor: '#ccc',          alignItems: 'center', justifyContent: 'center', backgroundColor: '#FAFAFA' },  center: { position: 'absolute', width: 60, height: 60, borderRadius: 30, borderWidth: 1, borderColor: '#ddd' },  bubble: { width: 36, height: 36, borderRadius: 18 },  status: { fontSize: 22, fontWeight: 'bold', marginTop: 14 },  read: { color: '#777', marginTop: 4 },});

الفقاعة = عنصرٌ متحرّك بـ transform؛ القيود Math.max/min تبقيها داخل الدائرة.

٣إضافة تثبيت القراءة

تحسينٌ عمليّ: زرُّ «تثبيت» يحفظ آخر قراءةٍ ليقرأها المستخدم بعد رفع الجهاز:

import { useState } from 'react';import { View, Text, Pressable, StyleSheet } from 'react-native';import { useTilt } from 'smartdevice'; export default function App() {  const { x, y } = useTilt();  const [held, setHeld] = useState(null);  const shown = held || { x, y };  return (    <View style={styles.box}>      <Text style={styles.r}>x={shown.x}°  y={shown.y}°</Text>      <View style={styles.row}>        <Pressable style={styles.btn} onPress={() => setHeld({ x, y })}>          <Text style={styles.bt}>تثبيت</Text>        </Pressable>        <Pressable style={styles.btn} onPress={() => setHeld(null)}>          <Text style={styles.bt}>مباشر</Text>        </Pressable>      </View>    </View>  );} const styles = StyleSheet.create({  box: { padding: 20, alignItems: 'center' },  r: { fontSize: 22, fontWeight: 'bold', color: '#E8820C' },  row: { flexDirection: 'row', gap: 10, marginTop: 14 },  btn: { backgroundColor: '#E8820C', paddingVertical: 8, paddingHorizontal: 16, borderRadius: 8 },  bt: { color: 'white' },});

«تثبيت» يلتقط اللحظة؛ «مباشر» يعود للتتبّع الحيّ.

توقّع وتحقّق

أداة الميزان تعتمد على مستشعر:

لتقييد حركة الفقاعة داخل حدّ:

أفضل بنية للتطبيق:

«تثبيت القراءة» يعني:

الخلاصة

تحدٍّ برمجي: حالة الاستواء

متوسط

اعرض حالة الاستواء من الإمالة.

المطلوب:
  • استورد useTilt.
  • احسب level: صحيحٌ إذا كان |x|≤3 و|y|≤3.
  • <Text testID="status">: «مستوٍ» أو «مائل».
👀 اعرض الناتج المطلوب (وجرّبه)
✓ التحقق الآلي من حلّك:
  • الكود يعمل بلا أخطاء في Console
  • يبدأ «مستوٍ» (الإمالة 0)
  • استُخدم Math.abs
  • استُخدم useTilt

💡 تلميح 1
الإمالة الابتدائيّة 0 فالحالة «مستوٍ».
💡 تلميح 2
الشرط: Math.abs(x) <= 3 && Math.abs(y) <= 3.

حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.

import { View, Text } from 'react-native';import { useTilt } from 'smartdevice'; export default function App() {  const { x, y } = useTilt();  const level = Math.abs(x) <= 3 && Math.abs(y) <= 3;  return (    <View style={{ padding: 24, alignItems: 'center' }}>      <Text testID="status" style={{ fontSize: 24, fontWeight: 'bold', color: level ? '#2E7D32' : '#E8820C' }}>        {level ? 'مستوٍ' : 'مائل'}      </Text>    </View>  );}
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

📝 معلم؟ أرسل ملاحظة للمؤلف عن هذا الدرس