كيفية بناء جسر رد فعل الأصلي والحصول على قوات الدفاع الشعبي عارض

يتيح React Native إنشاء تطبيقات أصلية باستخدام لغة JavaScript ولديه قدر كبير من المكونات والوظائف المتاحة. لكن بعض المكونات أو الميزات غير متوفرة بشكل افتراضي. وأحيانًا يكون من الضروري تحسين أداء بعض المكونات. في هذه الحالات ، يمكن استخدام التطبيق الأصلي.

توضح هذه المقالة كيفية إنشاء جسر بين JavaScript وتنفيذ أصلي ، وتقدم مثالًا على كيفية إنشاء PDF Viewer لـ React Native لتقديم مستندات PDF.

جميع المصادر متوفرة في gitlab أو كحزمة NPM:

  • حزمة NPM react-native-view-pdf (https://www.npmjs.com/package/react-native-view-pdf)
  • مصادر Gitlab rumax / react-native-PDFView (https://github.com/rumax/react-native-PDFView)

ابدء

اولا اعداد المشروع. فتح محطة وتشغيل:

$ create-react-native-app react-native-PDFView
$ cd رد فعل الأصلي - PDFView
إخراج الغزل $

تحقق من أن المشروع يعمل:

تشغيل الغزل $ android

وفتحه في IDE. أفضل Atom ، لذلك في المحطة يمكنني أن أفعل:

ذرة $.

افتح Android Studio للعمل مع مصادر Java.

تنفيذ جافا

في Android Studio:

  • إنشاء حزمة جديدة من المكتبة
  • إنشاء فصول Java جديدة PDFView و PDFViewManager و PDFViewPackage

PDFViewPackage

وفقًا للوثائق الرسمية ، يجب على PDFViewPackage تنفيذ ReactPackage والمفقود createNativeModules ويجب إضافة طرق createViewManagers:

الطبقة العامة PDFViewPackage تنفذ ReactPackage {
    @تجاوز
    قائمة عامة  createNativeModules (ReactApplicationContext reactContext) {
        إرجاع Collections.emptyList ()؛
    }
    قائمة عامة  createViewManagers (ReactApplicationContext reactContext) {
        return Arrays.  asList (PDFViewManager new (reactContext))؛
    }
}

سوف يقوم Android Studio بتسليط الضوء على خطأ لا يمكن تطبيق PDFViewManager على ... ، والذي يجب إصلاحه عن طريق تطبيق PDFViewManager.

PDFViewManager

يجب أن يقوم PDFViewManager بتمديد برنامج SimpleViewManager وتنفيذ الأساليب المفقودة:

  • getName والتي - يجب أن ترجع اسم فئة التفاعل
  • createViewInstanceis هو المكان الذي يجب أن يتم فيه تهيئة العارض

الكود هو:

PDFViewManager الطبقة العامة يمتد SimpleViewManager  {
    سلسلة ثابتة نهائية خاصة REACT_CLASS = "PDFView"؛
    PDFView الخاص pdfView = فارغ.
    سياق السياق الخاص ؛
    PDFViewManager العامة (سياق ReactApplicationContext) {
        this.context = سياق؛
    }
    @تجاوز
    سلسلة getName العامة () {
        إرجاع REACT_CLASS ؛
    }
    @تجاوز
    PDFView createViewInstance العامة (سياق ThemedReactContext) {
        if (pdfView == null) {
            pdfView = جديد PDFView (السياق) ؛
        }
        العودة pdfView.
    }
}

مع الخطأ الذي يجب أن يقوم PDFView بتوسيع طريقة العرض ، والذي يجب إصلاحه عن طريق تطبيق PDFView.

PDFView

يجب أن يمتد PDFView android.view.View والتنفيذ بسيط جدًا:

PDFView العام يمتد android.view.View {
    سياق ThemedReactContext الخاص ؛
    PDFView العامة (سياق ThemedReactContext) {
        السوبر (السياق).
        this.context = سياق؛
    }
}

في هذه اللحظة تكون جميع الفئات جاهزة وسيتم تسجيل ملف PDFViewPackagecan.

تسجيل PDFViewPackage

في MainApplication.java هناك طريقة getPackages. أسفل MainReactPackage ، يمكن تسجيل حزمة PDFViewPackage:

@تجاوز
قائمة محمية  getPackages () {
  إرجاع المصفوفات. قائمة  asList (
      MainReactPackage () الجديدة ،
      PDFViewPackage جديد ()
  )؛
}

تنفيذ جافا الأولي جاهز!

تطبيق جافا سكريبت

في Atom ، قم بإنشاء مجلد جديد PDFView وإنشاء ملفين:

  • index.js
  • RNPDFView.js

PDFView / RNPDFView.js

هذا هو الملف الرئيسي حيث يجب أن يكون المكون الأصلي لتفاعل PDFView مطلوبًا ويجب تعريف واجهة المكون:

استيراد {requireNativeComponent، ViewPropTypes} من 'react-native'؛
استيراد PropTypes من "أنواع prop" ؛
const componentInterface = {
  الاسم: "PDFView" ،
  propTypes: {
    ... ViewPropTypes،
  }،
}؛
default export exportNativeComponent ('PDFView'، componentInterface)؛

في هذه اللحظة ، يتم استخدام ViewPropTypes فقط للتحقق من تعريف المكون بشكل صحيح ويمكن استخدامه. سيتم إضافة جميع الخصائص الأخرى في وقت لاحق.

PDFView / index.js

هذا الملف اختياري ، ويمكن استخدامه كمكون مجمّع ، للتعامل مع حالات الخطأ / التحميل ، أو لاستخدام أنواع التدفق ، إلخ:

/* @يتدفق */
استيراد رد من "رد فعل" ؛
استيراد RNPDFView من './RNPDFView' ؛
اكتب Props = {}؛
فئة PDFView يمتد React.Component <الدعائم ، *> {
  defaultProps ثابت = {}؛
  مُنشئ (الدعائم: الدعائم) {
    السوبر (الدعائم)؛
  }
  يجعل() {
    return ؛
  }
}
تصدير الافتراضي PDFView.

App.js

الجسر جاهز ويمكن استيراده واستخدامه:

استيراد ملف PDFView من './PDFView/index' ؛
...
إرجاع (
  <عرض النمط = {styles.container}>
    
  

نظرًا لأنه ينفذ android.view.View في Java ، فيجب أن يتصرف أيضًا كمكون عرض للتفاعل الأصلي. يمكن التحقق من ذلك عن طريق تحديد الأنماط:

أنماط const = StyleSheet.create ({
  عرض pdf: {
    الارتفاع: 400
    العرض: 300
    backgroundColor: "الأخضر" ،
  }،
  ...

أعد تشغيل التطبيق وستحصل على مستطيل أخضر مثل هذا:

تصميم المكون

في الواقع ، هذا كل شيء بالنسبة للجسر ، باستثناء الخصائص وعمليات الاسترجاعات. وإذا لم تكن مطلوبة ، فمن الممكن بالفعل تنفيذ المكون في Java.

تنفيذ عارض PDF

لتنفيذ PDF Viewer ، من الضروري معرفة:

  • المورد - قيمة السلسلة لتعريف المورد المراد تقديمه. يمكن أن يكون عنوان url أو filePath أو بيانات base64
  • resourceType - قيمة السلسلة لتعريف نوع المورد

وبالطبع احصل على بعض الملاحظات من الجزء الأصلي إلى JavaScript:

  • onError - وظيفة رد الاتصال التي يجب استدعاؤها على خطأ
  • onLoad - وظيفة رد الاتصال التي يجب استدعاؤها عند اكتمال التحميل

تمرير الخصائص من JavaScript

في PDFView / RNPDFView.js ، قم بتوسيع componentInterface.propTypes بالخصائص الموضحة أعلاه:

const componentInterface = {
  الاسم: "PDFView" ،
  propTypes: {
    onError: PropTypes.func ،
    onLoad: PropTypes.func ،
    مورد: PropTypes.string ،
    resourceType: PropTypes.string ،
    ... ViewPropTypes،
  }،
}؛

قم بالشيء نفسه في PDFView / index.js ولكن باستخدام أنواع التدفق:

اكتب الدعائم = {
  onError: (خطأ) => باطل ،
  onLoad: () => باطل ،
  المورد: سلسلة ،
  resourceType: 'url' | 'base64' | 'ملف'،
}؛

وتعريف طريقة onError لتمرير الأصلي فقط من المكون:

onError: (error: Error) => void؛ / / تعريف نوع التدفق
onError (الحدث: أي) {
  this.props.onError (event && event.nativeEvent || new Error ())؛
}

لا تنسى ربط هذا في المنشئ:

مُنشئ (الدعائم: الدعائم) {
  السوبر (الدعائم)؛
  this.onError = this.onError.bind (this)؛
}

وإصلاح طريقة التجسيد:

يجعل() {
  const {onError، ... leftProps} = this.props؛
  إرجاع ؛
}

يمكن أيضًا تعريف الخصائص الافتراضية لتبسيط استخدام المكون:

defaultProps ثابت = {
  onError: () => {}،
  onLoad: () => {} ،
  resourceType: 'url' ،
}؛

تم الانتهاء من تطبيق JavaScript الآن.

الحصول على واستخدام الخصائص في جافا

قم بالتبديل إلى Android Studio وفتح فئة PDFViewManager. هذا هو المكان الذي يمكن فيه الوصول إلى جميع الخصائص ، المحددة في JavaScript. تحديد المورد:

ReactProp (name = "resource")
باطل setResource (PDFView pdfView ، سلسلة المورد) {
    pdfView.setResource (الموارد)؛
}

ونفس الشيء بالنسبة لـ resourceType (سيتم تطبيق عمليات الاسترجاعات لاحقًا):

ReactProp (name = "resourceType")
public void setResourceType (PDFView pdfView، String resourceType) {
    pdfView.setResourceType (resourceType)؛
}

التنفيذ في فئة PDFView سيكون:

نوع المورد الخاص
مورد سلسلة خاص
    
باطل setResource (مورد سلسلة) {
    this.resource = مورد ؛
}
public void setResourceType (String resourceType) {
    this.resourceType = resourceType؛
}

في PDFViewManager ، ابحث عن الطرق التالية:

  • onAfterUpdateTransaction ، هذا هو المكان الذي يجب تقديم المكون فيه بعد تعيين كل الخصائص:
@تجاوز
الفراغ العام onAfterUpdateTransaction (PDFView pdfView) {
    super.onAfterUpdateTransaction (pdfView)؛
    pdfView.render ()؛
}
  • onDropViewInstance هذا هو أسلوب آخر يتم استدعاء عندما يكون المكون React Native غير مثبت. يمكن أن يكون التنفيذ كما يلي:
@تجاوز
باطل onDropViewInstance (PDFView pdfView) {
    super.onDropViewInstance (pdfView)؛
    pdfView.onDrop ()؛
}

استخدم عمليات الاسترجاع JavaScript في Java

لاستخدام التحميل الكامل ، خطأ في عمليات الاسترجاعات ، من الضروري تمرير هذه الأحداث. افتح PDFView.java وحدد أساليب loadComplete و onError:

@تجاوز
تحميل void publicComplete (int numberOfPages) {
    reactNativeEvent ("onLoad"، null)؛
}
@تجاوز
باطل onError (استثناء السابقين) {
    reactNativeEvent ("onError"، "error:" + t.getMessage ())؛
}

وتنفيذ طريقة reactNativeEvent. وفقًا للوثائق الرسمية ، يجب أن يكون:

private void reactNativeEvent (اسم سلسلة الأحداث ، سلسلة الرسائل) {
    حدث WritableMap = Arguments.createMap () ؛
    event.putString ("message" ، الرسالة) ؛
    ReactContext reactContext = (ReactContext) this.getContext ()؛
    reactContext
            .getJSModule (RCTEventEmitter.class)
            .receiveEvent (this.getId ()، eventName، event)؛
}

وفي PDFViewManager

خريطة عامة getExportedCustomBubblingEventTypeConstants () {
    عودة MapBuilder
            .builder ()
            .وضع(
                    "ONLOAD"
                    MapBuilder.of ("phasedRegistrationNames"، MapBuilder.of ("bubbled"، "onLoad"))
            )
            .وضع(
                    "onError"
                    MapBuilder.of ("phasedRegistrationNames"، MapBuilder.of ("bubbled"، "onError"))
            )
            . البناء ()؛
}

تنفيذ الجسر جاهز! الشيء الوحيد المتبقي هو تطبيق PDFViewer.java. لقد استخدمت تطبيق AndroidPdfViewer والحل النهائي الذي يمكنك العثور عليه في gitlab (https://github.com/rumax/react-native-PDFView).

النتائج

تنفيذ الجسر و PDF Viewer جاهز. حدد المستند الذي تريد تقديمه:

<عرض النمط = {styles.container}>
   console.log ('onError' ، خطأ)}
    onLoad = {() => console.log ('onLoad')}
    مورد = "http://www.pdf995.com/samples/pdf.pdf" />

.. إعادة تحميل التطبيق وبدلاً من المستطيل الأخضر ستحصل على وثيقة PDF:

نتائج عارض PDF