إدارة لوحة المفاتيح القابلة للفصل

رمز التقييم بثلاث نجوم

يساعد توفّر الدعم للوحات المفاتيح القابلة للفصل في زيادة إنتاجية المستخدمين إلى أقصى حد على الأجهزة ذات الشاشات الكبيرة. يُشغِّل نظام Android تغييرًا في الإعدادات في كل مرة يتم فيها توصيل لوحة مفاتيح بجهاز أو فصلها عنه، ما قد يؤدي إلى فقدان حالة واجهة المستخدم. يمكن لتطبيقك إما حفظ حالته واستعادتها، ما يسمح للنظام بالتعامل مع إعادة إنشاء النشاط، أو تقييد إعادة إنشاء النشاط عند إجراء تغييرات في إعدادات لوحة المفاتيح.

في جميع الحالات، يتم تخزين جميع البيانات ذات الصلة بلوحة المفاتيح في عنصر Configuration. يحتوي الحقلان keyboard وkeyboardHidden في عنصر الإعدادات على معلومات عن نوع لوحة المفاتيح ومدى توفّرها.

أفضل الممارسات

تتوافق التطبيقات المحسّنة للشاشات الكبيرة مع كل أنواع أجهزة الإدخال، بدءًا من لوحات المفاتيح البرمجية والمادية وصولاً إلى القلم والماوس ولوحة التتبّع والأجهزة الطرفية الأخرى.

يتطلّب توفّر الدعم للوحات المفاتيح الخارجية إجراء تغييرات في الإعدادات، ويمكنك إدارة هذه التغييرات بإحدى الطريقتَين التاليتَين:

  1. السماح للنظام بإعادة إنشاء النشاط قيد التشغيل، مع تولّيك مسؤولية إدارة حالة تطبيقك
  2. إدارة تغيير الإعدادات بنفسك (لن تتم إعادة إنشاء النشاط):
    • الإعلان عن جميع قيم الإعدادات ذات الصلة بلوحة المفاتيح
    • إنشاء معالج لتغيير الإعدادات

يمكن أن تستفيد تطبيقات الإنتاجية، التي تتطلّب غالبًا تحكّمًا دقيقًا في واجهة المستخدم لإدخال النصوص وغيرها من البيانات، من طريقة التعامل مع تغييرات الإعدادات بنفسك.

في حالات خاصة، قد تحتاج إلى تغيير تنسيق تطبيقك عند توصيل لوحة مفاتيح مادية أو فصلها، مثلاً لتوفير مساحة أكبر للأدوات أو نوافذ التعديل.

في Jetpack Compose، يمكنك الاستجابة لتغييرات إعدادات لوحة المفاتيح بإحدى الطريقتَين التاليتَين:

  1. واجهة مستخدم تفاعلية: يمكنك قراءة حالة الإعدادات الحالية مباشرةً في العناصر القابلة للإنشاء باستخدام LocalConfiguration.current. تتم إعادة إنشاء واجهة المستخدم تلقائيًا لتتكيّف مع الحالة الجديدة عند توصيل لوحة مفاتيح أو فصلها.
  2. دالة ردّ الاتصال للآثار الجانبية: يمكنك استخدام DisposableEffect التي تراعي مراحل النشاط لتسجيل مستمع لتغييرات الإعدادات في النشاط المضيف، ما يتيح لك تشغيل أحداث غير مرتبطة بواجهة المستخدم (مثل التسجيل أو الإحصاءات) بدون إعادة إنشاء النشاط أو إنشاء أي عناصر عرض وهمية.

المكوّنات

  • android:configChanges: سمة عنصر <activity> في بيان التطبيق تُعلم هذه السمة النظام بالتغييرات في الإعدادات التي يديرها التطبيق.
  • LocalConfiguration: موفِّر محلي قابل للإنشاء يعرض الجهاز Configuration الحالي
  • DisposableEffect: واجهة برمجة تطبيقات للآثار الجانبية في Compose تُشغِّل مجموعة من الرموز البرمجية عندما يدخل عنصر قابل للإنشاء في التركيبة، وتزيلها عند خروجه منها

الخطوات

عليك الإعلان عن السمة configChanges وإضافة القيم ذات الصلة بلوحة المفاتيح لمنع إعادة إنشاء النشاط. بعد ذلك، يمكنك استخدام LocalConfiguration.current لتكييف تنسيق العنصر القابل للإنشاء ديناميكيًا، أو تسجيل مستمع للإعدادات باستخدام DisposableEffect.

‫1. الإعلان عن السمة configChanges

عليك تعديل العنصر <activity> في بيان التطبيق من خلال إضافة القيمتَين keyboard|keyboardHidden إلى قائمة تغييرات الإعدادات التي تتم إدارتها حاليًا:

<activity
            android:configChanges="...|keyboard|keyboardHidden">

‫2. الاستجابة لتغييرات إعدادات لوحة المفاتيح

للتعامل مع تغييرات الإعدادات في Jetpack Compose، استخدِم أحد الخيارَين التاليَين بناءً على ما إذا كنت تعدِّل واجهة المستخدم أو تنفِّذ دالة ردّ اتصال للآثار الجانبية:

  • الخيار أ: واجهة مستخدم تفاعلية (مُقترَح)

    يمكنك قراءة نوع لوحة المفاتيح مباشرةً من LocalConfiguration.current. عند توصيل لوحة مفاتيح مادية أو فصلها، تتغيّر هذه القيمة، ويعيد Compose تلقائيًا إنشاء واجهة المستخدم.

    val configuration = LocalConfiguration.current
    val isPhysicalKeyboardAttached = configuration.keyboard == Configuration.KEYBOARD_QWERTY
    
    if (isPhysicalKeyboardAttached) {
        // Render layout optimized for physical keyboard
    } else {
        // Render default layout
    }

  • الخيار ب: مستمع الآثار الجانبية

    إذا كنت بحاجة إلى تشغيل تأثير جانبي (مثل التسجيل أو تعديل قاعدة بيانات محلية أو تشغيل الإحصاءات) عند تغيير الإعدادات، استخدِم DisposableEffect لتسجيل مستمع لتغييرات الإعدادات في ComponentActivity المضيف.

    val context = LocalActivity.current
    DisposableEffect(context) {
        val activity = context as? ComponentActivity
        val listener = Consumer<Configuration> { newConfig ->
            val hasKeyboard = newConfig.keyboard == Configuration.KEYBOARD_QWERTY
            // Trigger non-UI actions, analytics, etc.
        }
        activity?.addOnConfigurationChangedListener(listener)
        onDispose {
            activity?.removeOnConfigurationChangedListener(listener)
        }
    }

النتائج

سيستجيب تطبيقك الآن عند توصيل لوحة مفاتيح خارجية أو فصلها بدون إعادة إنشاء النشاط قيد التشغيل.

مراجع إضافية

للتعرّف على كيفية حفظ حالة واجهة مستخدم تطبيقك أثناء تغييرات الإعدادات، مثل توصيل لوحة المفاتيح أو فصلها، اطّلِع على مقالة حفظ حالات واجهة المستخدم.