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

لماذا تطبيقات الأجهزة الذكية؟ أول شاشة React Native

من واجهات الويب إلى تطبيقٍ في يدك يتفاعل مع مستشعراته. ⏱ نحو 35 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تشرح ما تطبيقات الأجهزة الذكية وكيف تختلف عن الويب.
  • تكتب أول شاشة React Native بـ View و Text و StyleSheet.
  • تضيف تفاعلًا باللمس والحالة، وتقرأ مستشعرًا بسيطًا.
  • تقارن React Native بـ Flutter وتعرف لماذا نبدأ بالأول.

١من الويب إلى الجهاز في يدك

في مقرر 242 بنيت واجهات ويب بـ React تعمل في المتصفّح. الآن ننقل المهارة نفسها إلى الهاتف الذكي: تطبيقٌ يُثبَّت على الجهاز، يتفاعل مع مستشعراته (الإمالة، الضوء، الموقع، الكاميرا)، ويعمل على Android و iOS من كودٍ واحد.

الأداة التي نستخدمها React Native: تكتب مكوّنات بالفكرة نفسها (JSX، حالة، خصائص)، لكن بدل <div> و<p> تستخدم مكوّناتٍ أصيلة: <View> و<Text>. يحوّلها الإطار إلى عناصر واجهة أصيلة حقيقية على الجهاز.

تطبيق ويب (242)تطبيق جهاز ذكيّ (251)
يعمل فيالمتصفّحالهاتف (Android/iOS)
لبنة الواجهة<div> <p> <button><View> <Text> <Pressable>
المستشعراتمحدودةإمالة، ضوء، موقع، كاميرا
الأداةReact + ViteReact Native (أو Flutter)

٢أول شاشة: View و Text

المكوّن في React Native دالةٌ تعيد JSX، لكن بمكوّنات الجهاز. View حاوية (مثل div)، وText لكل نصّ (لا يمكن كتابة نصّ خارج Text). جرّب — المعاينة تعمل فعلًا داخل الهاتف:

import { View, Text } from 'react-native'; export default function App() {  return (    <View style={{ padding: 20 }}>      <Text style={{ fontSize: 22, fontWeight: 'bold' }}>مرحبًا بالأجهزة الذكية 📱</Text>      <Text style={{ marginTop: 8, color: '#555' }}>        هذا أول تطبيق React Native تكتبه.      </Text>    </View>  );}

٣الأنماط: StyleSheet

بدل CSS، تُكتب الأنماط كائناتٍ JavaScript. نجمعها بـ StyleSheet.create لتنظيمها وتحسين الأداء. الأسماء بأسلوب camelCase (backgroundColor لا background-color)، والأرقام تعني وحداتٍ مستقلة عن الكثافة (لا بكسل):

import { View, Text, StyleSheet } from 'react-native'; export default function App() {  return (    <View style={styles.card}>      <Text style={styles.title}>بطاقة منتج</Text>      <Text style={styles.price}>٤٩٩ ريال</Text>    </View>  );} const styles = StyleSheet.create({  card: { backgroundColor: '#E8820C', padding: 16, borderRadius: 14, margin: 10 },  title: { color: 'white', fontSize: 20, fontWeight: 'bold' },  price: { color: '#FFE8CC', fontSize: 16, marginTop: 6 },});

٤تفاعل حيّ: اللمس والحالة

Pressable يستقبل اللمس، وuseState يحفظ الحالة — كما في React تمامًا. اضغط الزرّ في الهاتف:

import { useState } from 'react';import { View, Text, Pressable, StyleSheet } from 'react-native'; export default function App() {  const [count, setCount] = useState(0);  return (    <View style={styles.box}>      <Text style={styles.n}>{count}</Text>      <Pressable style={styles.btn} onPress={() => setCount(count + 1)}>        <Text style={styles.bt}>اضغط لزيادة العدّاد</Text>      </Pressable>    </View>  );} const styles = StyleSheet.create({  box: { alignItems: 'center', padding: 24 },  n: { fontSize: 48, fontWeight: 'bold', color: '#E8820C' },  btn: { backgroundColor: '#E8820C', paddingVertical: 12, paddingHorizontal: 18, borderRadius: 12, marginTop: 14 },  bt: { color: 'white', fontSize: 16 },});

٥لمحة: قراءة مستشعر

ما يميّز الأجهزة الذكية هو المستشعرات. سنتعمّق فيها لاحقًا، لكن إليك لمحة: نقرأ البطارية من محاكي SmartDevice ونعرضها. حرّك منزلق البطارية في لوحة المستشعرات أسفل الهاتف ولاحظ تحدّث الرقم واللون حيًّا:

import { View, Text, StyleSheet } from 'react-native';import { useBattery } from 'smartdevice'; export default function App() {  const bat = useBattery();                 // {level, saver}  const low = bat.level < 20;  return (    <View style={styles.box}>      <Text style={styles.lbl}>حالة البطارية</Text>      <Text style={[styles.pct, { color: low ? '#C62828' : '#2E7D32' }]}>        {bat.level}%      </Text>      <Text style={styles.hint}>        {low ? '🔴 بطارية منخفضة!' : '🟢 جيدة'}{bat.saver ? ' · وضع التوفير' : ''}      </Text>    </View>  );} const styles = StyleSheet.create({  box: { alignItems: 'center', padding: 24 },  lbl: { fontSize: 15, color: '#666' },  pct: { fontSize: 44, fontWeight: 'bold', marginVertical: 6 },  hint: { fontSize: 15 },});

هذا هو جوهر المقرر: كودك يستمع للمستشعر، والواجهة تستجيب. لاحظ أن القيمة تبدأ من 80% ثم تتبعك.

٦المنصّات: React Native و Flutter

تذكر الخطة أداتين لتطوير تطبيقٍ واحد يعمل على عدّة منصّات:

React NativeFlutter
اللغةJavaScript / JSXDart
منMetaGoogle
الفكرةمكوّنات تتحوّل لعناصر أصيلةWidgets تُرسَم على لوحة خاصة
نستخدمه هنانكتبه ونشغّلهنعرض كودَه ونشرحه (الوحدة 6)

نركّز على React Native لأنه امتداد مباشر لـ React الذي أتقنته، ونخصّص الوحدة السادسة لفهم Flutter ومقارنته. كلاهما يحقّق الهدف: كودٌ واحد، منصّتان.

توقّع وتحقّق

ما المكوّن الذي يقابل &lt;div&gt; في React Native؟

View حاوية عامة.

أين يجب أن يوضع كل نصّ؟

النصّ خارج Text خطأ.

كيف تُكتب الأنماط في React Native؟

StyleSheet.create.

لماذا نختار React Native امتدادًا لمهارتك؟

المفاهيم نفسها: JSX وحالة وخصائص.

الخلاصة

تحدٍّ برمجي: شاشة تعريف بتطبيق

سهل

اصنع شاشة ترحيبٍ بسيطة بمكوّنات React Native.

المطلوب:
  • استورد View وText من react-native.
  • أضف <Text testID="title"> نصّه «تطبيقي الذكي».
  • أضف <Text testID="sub"> نصّه «أول تطبيق أجهزة ذكية».
  • ضعهما داخل <View> واحدة، وصدّر App افتراضيًّا.
👀 اعرض الناتج المطلوب (وجرّبه)
✓ التحقق الآلي من حلّك:
  • الكود يعمل بلا أخطاء في Console
  • العنوان في testID=title
  • العنوان الفرعي في testID=sub
  • استُخدم مكوّن Text مرتين

💡 تلميح 1
كل نصّ داخل <Text testID="…">النص</Text>.
💡 تلميح 2
testID سمةٌ تساعد على التعرّف على العنصر؛ تُصبح data-testid في المعاينة.

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

import { View, Text } from 'react-native'; export default function App() {  return (    <View style={{ padding: 20 }}>      <Text testID="title" style={{ fontSize: 22, fontWeight: 'bold' }}>تطبيقي الذكي</Text>      <Text testID="sub" style={{ color: '#555', marginTop: 6 }}>أول تطبيق أجهزة ذكية</Text>    </View>  );}
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

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