الفرق بين المراجعتين ل"ReactNative/dimensions"

من موسوعة حسوب
اذهب إلى التنقل اذهب إلى البحث
(مراجعة)
سطر 1: سطر 1:
<noinclude>{{DISPLAYTITLE: Dimensions في React Native}}</noinclude>
+
<noinclude>{{DISPLAYTITLE:الواجهة Dimensions في React Native}}</noinclude>
 +
يفضل استعمال الواجهة [[ReactNative/usewindowdimensions|<code>useWindowDimensions</code>]] مع مكونات React خلافًا لهذه الواجهة التي تتحدث كلما تحدث أبعاد النافذة، وهذا مناسب لبعض الأنماط في React.<syntaxhighlight lang="js">
 +
import { Dimensions } from 'react-native';
 +
 
 +
</syntaxhighlight>يمكنك مثلًا جلب أبعاد النافذة، طولها وعرضها بالشكل التالي:<syntaxhighlight lang="js">
 +
const windowWidth = Dimensions.get('window').width;
 +
const windowHeight = Dimensions.get('window').height;
 +
 
 +
</syntaxhighlight>صحيح أن الأبعاد متاحة مباشرةً ولكن انتبه فقد تتغير (نتيجة قلب الجهاز مثلًا أو طيه إن كان قابلًا للطي)، لذا يجب على أي منطق عرض أو أنماط تنسيق تعتمد على هذه الثوابت أن تستدعي هذه الدوال قبل كل عملية عرض (تصيير)، بدلًا من تخزين القيم (مثل استعمال أنماط التنسيق السطرية inline styles بدلًا من ضبط قيمة في الكائن <code>StyleSheet</code>).
 +
 
 +
إن كنت تستهدف جهازًا قابلًا للطي أو جهازًا يمكن تغيير حجم شاشته أو حجم شاشة التطبيق، فيمكنك استخدام مستمع الحدث المتاح في الواجهة <code>Dimensions</code> كما موضح في المثال الآتي.
 +
 
 +
== مثال ==
 +
 
 +
* [https://snack.expo.dev/@hsoubwiki/dimensions-function-component استخدام مكون دالة (Function Component)]
 +
<syntaxhighlight lang="js">
 +
import React, { useState, useEffect } from "react";
 +
import { View, StyleSheet, Text, Dimensions } from "react-native";
 +
 
 +
const window = Dimensions.get("window");
 +
const screen = Dimensions.get("screen");
 +
 
 +
const App = () => {
 +
  const [dimensions, setDimensions] = useState({ window, screen });
 +
 
 +
  useEffect(() => {
 +
    const subscription = Dimensions.addEventListener(
 +
      "change",
 +
      ({ window, screen }) => {
 +
        setDimensions({ window, screen });
 +
      }
 +
    );
 +
    return () => subscription?.remove();
 +
  });
 +
 
 +
  return (
 +
    <View style={styles.container}>
 +
      <Text style={styles.header}>Window Dimensions</Text>
 +
      {Object.entries(dimensions.window).map(([key, value]) => (
 +
        <Text>{key} - {value}</Text>
 +
      ))}
 +
      <Text style={styles.header}>Screen Dimensions</Text>
 +
      {Object.entries(dimensions.screen).map(([key, value]) => (
 +
        <Text>{key} - {value}</Text>
 +
      ))}
 +
    </View>
 +
  );
 +
}
 +
 
 +
const styles = StyleSheet.create({
 +
  container: {
 +
    flex: 1,
 +
    justifyContent: "center",
 +
    alignItems: "center"
 +
  },
 +
  header: {
 +
    fontSize: 16,
 +
    marginVertical: 10
 +
  }
 +
});
 +
 
 +
export default App;
 +
</syntaxhighlight>
 +
 
 +
* [https://snack.expo.dev/@hsoubwiki/dimensions-class-component استخدام مكون صنف (Class Component)]
 +
<syntaxhighlight lang="js">
 +
import React, { Component } from "react";
 +
import { View, StyleSheet, Text, Dimensions } from "react-native";
 +
 
 +
const window = Dimensions.get("window");
 +
const screen = Dimensions.get("screen");
 +
 
 +
class App extends Component {
 +
  state = {
 +
    dimensions: {
 +
      window,
 +
      screen
 +
    }
 +
  };
 +
 
 +
  onChange = ({ window, screen }) => {
 +
    this.setState({ dimensions: { window, screen } });
 +
  };
 +
 
 +
  componentDidMount() {
 +
    this.dimensionsSubscription = Dimensions.addEventListener("change", this.onChange);
 +
  }
 +
 
 +
  componentWillUnmount() {
 +
    this.dimensionsSubscription?.remove();
 +
  }
 +
 
 +
  render() {
 +
    const { dimensions: { window, screen } } = this.state;
 +
 
 +
    return (
 +
      <View style={styles.container}>
 +
        <Text style={styles.header}>Window Dimensions</Text>
 +
        {Object.entries(window).map(([key, value]) => (
 +
          <Text>{key} - {value}</Text>
 +
        ))}
 +
        <Text style={styles.header}>Screen Dimensions</Text>
 +
        {Object.entries(screen).map(([key, value]) => (
 +
          <Text>{key} - {value}</Text>
 +
        ))}
 +
      </View>
 +
    );
 +
  }
 +
}
 +
 
 +
const styles = StyleSheet.create({
 +
  container: {
 +
    flex: 1,
 +
    justifyContent: "center",
 +
    alignItems: "center"
 +
  },
 +
  header: {
 +
    fontSize: 16,
 +
    marginVertical: 10
 +
  }
 +
});
 +
 
 +
export default App;
 +
</syntaxhighlight>
 +
 
 
==التوابع==
 
==التوابع==
 
===‎‎<code>addEventListener()</code>‎‎===
 
===‎‎<code>addEventListener()</code>‎‎===
سطر 6: سطر 130:
 
</syntaxhighlight>
 
</syntaxhighlight>
 
أضف معالج أحداث. الأحداث المدعومة:
 
أضف معالج أحداث. الأحداث المدعومة:
* ‎‎<code>change</code>‎: يُطلَق عند تغيّر خاصيةٍ داخل كائن ‎‎<code>Dimensions</code>‎‎. المعامل المُمرَّر لمعالج الحدث هو كائن ذو الخاصيتين ‎‎<code>window</code>‎‎، و‎‎<code>screen</code>‎‎ والتي تكون قيمتاهما نفسهما القيمتان المُعادتان من استدعاء كل من ‎‎<code>Dimensions.get('window')</code>‎‎، و‎‎<code>Dimensions.get('screen')</code>‎‎ على التوالي.
+
* ‎‎<code>change</code>‎: يُطلَق عند تغيّر خاصيةٍ داخل كائن ‎‎<code>Dimensions</code>‎‎. المعامل المُمرَّر لمعالج الحدث هو كائن من النوع DimensionsValue.
 
===‎‎<code>get()</code>‎‎===
 
===‎‎<code>get()</code>‎‎===
 
<syntaxhighlight lang="javascript">
 
<syntaxhighlight lang="javascript">
 
static get(dim)
 
static get(dim)
 
</syntaxhighlight>
 
</syntaxhighlight>
تُعيَّن الأبعاد الأولية قبل استدعاء‎‎<code>runApplication</code>‎‎، لذا من المفترض أن تكون متوفرة قبل تشغيل أي متطلبات (‎‎<code>require</code>‎‎) أخرى، ولكنها قد تُحدَّث لاحقًا.
+
يعيَّن الأبعاد الأولية قبل استدعاء ‎‎<code>runApplication</code>‎‎، لذا من المفترض أن تكون متوفرة قبل تشغيل أي متطلبات (‎‎<code>require</code>‎‎) أخرى، ولكنها قد تُحدَّث لاحقًا. يعيد التابع قيمةُ البُعد.
 
 
'''ملاحظة:''' على الرغم من توفر الأبعاد على الفور، إلا أنها قد تتغير (بسبب تدوير الجهاز مثلا)، لذلك ينبغي لأي منطق تصيير (rendering logic) أو أنماطٍ (styles) تعتمد على هذه الثوابت مُحاولةُ استدعاء هذه الدالة عند كل تصيير، بدلاً من التخزين المؤقت (caching) للقيمة (استخدام الأنماط السطرية [inline styles] عوضًا عن تعيين قيمة في ‎‎<code>StyleSheet</code>‎‎ مثلا).
 
  
====مثال====
+
إليك مثال:<syntaxhighlight lang="javascript">
<syntaxhighlight lang="javascript">
 
 
var {height, width} = Dimensions.get('window');
 
var {height, width} = Dimensions.get('window');
</syntaxhighlight>
+
</syntaxhighlight>المعاملات التي يأخذها التابع:
 
+
* ‎<code>dim</code>‎‎ (سلسلة نصيّة مطلوبة): اسم البعد كما هو محدد عند استدعاء ‎‎<code>set</code>‎‎.
====المعاملات====
 
* ‎<code>dim</code>‎‎ (سلسلة نصيّة): اسم البعد كما هو محدد عند استدعاء ‎‎<code>set</code>‎‎.
 
====القيمة المعادة====
 
قيمةُ البُعد.
 
 
 
 
'''ملاحظة:''' في Android، سيستبعد البُعد ‎‎<code>window</code>‎‎ الحجم المُستخدَم من طرف شريط الحالة (إن لم يكن شفافًا) وشريط التنقل السفلي.
 
'''ملاحظة:''' في Android، سيستبعد البُعد ‎‎<code>window</code>‎‎ الحجم المُستخدَم من طرف شريط الحالة (إن لم يكن شفافًا) وشريط التنقل السفلي.
  
سطر 32: سطر 148:
 
</syntaxhighlight>
 
</syntaxhighlight>
 
إزالة معالج الأحداث.
 
إزالة معالج الأحداث.
 +
 +
'''تنبيه''': هذا التابع مهمل، واستعمل التابع <code>remove()‎</code> مع قيمة اشتراك الحدث (event subscription) التي يعيدها التابع <code>addEventListener()‎</code>.
 
===‎‎<code>set()</code>‎‎===
 
===‎‎<code>set()</code>‎‎===
 
<syntaxhighlight lang="javascript">
 
<syntaxhighlight lang="javascript">
سطر 38: سطر 156:
 
يجب أن يُستدعى هذا فقط من طرف الشيفرة الأصيلة عن طريق إرسال الحدث ‎‎<code>didUpdateDimensions</code>‎‎.
 
يجب أن يُستدعى هذا فقط من طرف الشيفرة الأصيلة عن طريق إرسال الحدث ‎‎<code>didUpdateDimensions</code>‎‎.
  
====المعاملات====
+
المعاملات:
* ‎‎<code>dims</code>‎‎ (كائن): كائنٌ مفاتيحه نصيّة (string-keyed) يحتوي الأبعاد المراد ضبطها.
+
* ‎‎<code>dims</code>‎‎ (كائن مطلوب): كائنٌ مفاتيحه نصيّة (string-keyed) يحتوي الأبعاد المراد ضبطها.
 +
 
 +
== تعريفات النوع ==
 +
 
 +
=== <code>DimensionsValue</code> ===
 +
كائن ذو الخاصيتين ‎‎<code>window</code>‎‎، و‎‎<code>screen</code>‎‎ والتي تكون قيمتاهما نفسهما القيمتان المُعادتان من استدعاء كل من ‎‎<code>Dimensions.get('window')</code>‎‎، و‎‎<code>Dimensions.get('screen')</code>‎‎ على التوالي.
 +
 
 +
الخاصيات:
 +
{| class="wikitable"
 +
!الاسم
 +
!النوع
 +
!الوصف
 +
|-
 +
|<code>window</code>‎‎
 +
|<code>DisplayMetrics</code>
 +
|حجم نافذة التطبيق الظاهرة.
 +
|-
 +
|‎‎<code>screen</code>‎‎
 +
|<code>DisplayMetrics</code>
 +
|حجم نافذة الجهاز.
 +
|}
 +
 
 +
=== <code>DisplayMetrics</code> ===
 +
كائن له الخاصيات التالية:
 +
{| class="wikitable"
 +
!الاسم
 +
!النوع
 +
|-
 +
|<code>width</code>
 +
|عدد number
 +
|-
 +
|<code>height</code>
 +
|عدد number
 +
|-
 +
|<code>scale</code>
 +
|عدد number
 +
|-
 +
|<code>fontScale</code>
 +
|عدد number
 +
|}
 +
 
 
== مصادر ==
 
== مصادر ==
* [https://facebook.github.io/react-native/docs/dimensions صفحة Dimensions في توثيق React Native الرسمي.]
+
* [https://reactnative.dev/docs/dimensions صفحة Dimensions في توثيق React Native الرسمي.]
 
[[تصنيف:ReactNative]]
 
[[تصنيف:ReactNative]]

مراجعة 15:12، 4 أكتوبر 2021

يفضل استعمال الواجهة useWindowDimensions مع مكونات React خلافًا لهذه الواجهة التي تتحدث كلما تحدث أبعاد النافذة، وهذا مناسب لبعض الأنماط في React.

import { Dimensions } from 'react-native';

يمكنك مثلًا جلب أبعاد النافذة، طولها وعرضها بالشكل التالي:

const windowWidth = Dimensions.get('window').width;
const windowHeight = Dimensions.get('window').height;

صحيح أن الأبعاد متاحة مباشرةً ولكن انتبه فقد تتغير (نتيجة قلب الجهاز مثلًا أو طيه إن كان قابلًا للطي)، لذا يجب على أي منطق عرض أو أنماط تنسيق تعتمد على هذه الثوابت أن تستدعي هذه الدوال قبل كل عملية عرض (تصيير)، بدلًا من تخزين القيم (مثل استعمال أنماط التنسيق السطرية inline styles بدلًا من ضبط قيمة في الكائن StyleSheet).

إن كنت تستهدف جهازًا قابلًا للطي أو جهازًا يمكن تغيير حجم شاشته أو حجم شاشة التطبيق، فيمكنك استخدام مستمع الحدث المتاح في الواجهة Dimensions كما موضح في المثال الآتي.

مثال

import React, { useState, useEffect } from "react";
import { View, StyleSheet, Text, Dimensions } from "react-native";

const window = Dimensions.get("window");
const screen = Dimensions.get("screen");

const App = () => {
  const [dimensions, setDimensions] = useState({ window, screen });

  useEffect(() => {
    const subscription = Dimensions.addEventListener(
      "change",
      ({ window, screen }) => {
        setDimensions({ window, screen });
      }
    );
    return () => subscription?.remove();
  });

  return (
    <View style={styles.container}>
      <Text style={styles.header}>Window Dimensions</Text>
      {Object.entries(dimensions.window).map(([key, value]) => (
        <Text>{key} - {value}</Text>
      ))}
      <Text style={styles.header}>Screen Dimensions</Text>
      {Object.entries(dimensions.screen).map(([key, value]) => (
        <Text>{key} - {value}</Text>
      ))}
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center"
  },
  header: {
    fontSize: 16,
    marginVertical: 10
  }
});

export default App;
import React, { Component } from "react";
import { View, StyleSheet, Text, Dimensions } from "react-native";

const window = Dimensions.get("window");
const screen = Dimensions.get("screen");

class App extends Component {
  state = {
    dimensions: {
      window,
      screen
    }
  };

  onChange = ({ window, screen }) => {
    this.setState({ dimensions: { window, screen } });
  };

  componentDidMount() {
    this.dimensionsSubscription = Dimensions.addEventListener("change", this.onChange);
  }

  componentWillUnmount() {
    this.dimensionsSubscription?.remove();
  }

  render() {
    const { dimensions: { window, screen } } = this.state;

    return (
      <View style={styles.container}>
        <Text style={styles.header}>Window Dimensions</Text>
        {Object.entries(window).map(([key, value]) => (
          <Text>{key} - {value}</Text>
        ))}
        <Text style={styles.header}>Screen Dimensions</Text>
        {Object.entries(screen).map(([key, value]) => (
          <Text>{key} - {value}</Text>
        ))}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center"
  },
  header: {
    fontSize: 16,
    marginVertical: 10
  }
});

export default App;

التوابع

‎‎addEventListener()‎‎

static addEventListener(type, handler)

أضف معالج أحداث. الأحداث المدعومة:

  • ‎‎change‎: يُطلَق عند تغيّر خاصيةٍ داخل كائن ‎‎Dimensions‎‎. المعامل المُمرَّر لمعالج الحدث هو كائن من النوع DimensionsValue.

‎‎get()‎‎

static get(dim)

يعيَّن الأبعاد الأولية قبل استدعاء ‎‎runApplication‎‎، لذا من المفترض أن تكون متوفرة قبل تشغيل أي متطلبات (‎‎require‎‎) أخرى، ولكنها قد تُحدَّث لاحقًا. يعيد التابع قيمةُ البُعد.

إليك مثال:

var {height, width} = Dimensions.get('window');

المعاملات التي يأخذها التابع:

  • dim‎‎ (سلسلة نصيّة مطلوبة): اسم البعد كما هو محدد عند استدعاء ‎‎set‎‎.

ملاحظة: في Android، سيستبعد البُعد ‎‎window‎‎ الحجم المُستخدَم من طرف شريط الحالة (إن لم يكن شفافًا) وشريط التنقل السفلي.

‎‎removeEventListener()‎‎

static removeEventListener(type, handler)

إزالة معالج الأحداث.

تنبيه: هذا التابع مهمل، واستعمل التابع remove()‎ مع قيمة اشتراك الحدث (event subscription) التي يعيدها التابع addEventListener()‎.

‎‎set()‎‎

static set(dims)

يجب أن يُستدعى هذا فقط من طرف الشيفرة الأصيلة عن طريق إرسال الحدث ‎‎didUpdateDimensions‎‎.

المعاملات:

  • ‎‎dims‎‎ (كائن مطلوب): كائنٌ مفاتيحه نصيّة (string-keyed) يحتوي الأبعاد المراد ضبطها.

تعريفات النوع

DimensionsValue

كائن ذو الخاصيتين ‎‎window‎‎، و‎‎screen‎‎ والتي تكون قيمتاهما نفسهما القيمتان المُعادتان من استدعاء كل من ‎‎Dimensions.get('window')‎‎، و‎‎Dimensions.get('screen')‎‎ على التوالي.

الخاصيات:

الاسم النوع الوصف
window‎‎ DisplayMetrics حجم نافذة التطبيق الظاهرة.
‎‎screen‎‎ DisplayMetrics حجم نافذة الجهاز.

DisplayMetrics

كائن له الخاصيات التالية:

الاسم النوع
width عدد number
height عدد number
scale عدد number
fontScale عدد number

مصادر