NativeView allows to instantiate and display platform-specific views and widgets. More...
Import Statement: | import Felgo 4.0 |
Since: | Felgo 3.3.0 |
Inherits: | |
Inherited By: |
This item allows to display widgets from native Android & iOS frameworks using QML code. It can display any native view object directly inside the QML scene graph. For example, you can add a native Button
,
ImageView
or WebView
to your Felgo app. This screenshot shows an example app with these three components on Android and iOS:
Displaying native views is only supported on Android and iOS. On desktop platforms, NativeView displays a dummy view that draws nothing.
Note: NativeView is rendered with OpenGL, and thus only works when enforcing OpenGL rendering. Add this code in your main.cpp
, before creating QApplication
(see also: Rendering Changes: Hardware Interface):
QQuickWindow::setGraphicsApi(QSGRendererInterface::OpenGLRhi);
NativeView allows specifying which view to instantiate on Android and iOS. On Android, it can display any instance of android.view.View
. On iOS, it can display any instance of UIView
. You
can specify which view class to instantiate on each platform. Use the androidBinding and iosBinding properties for
this.
You can then access the native view object as NativeObject instance. Use the property NativeViewBinding::view for this.
The view behaves exactly like it would in a native app. However, it is still rendered inside the QML scene graph. The native view's size gets set to the size of the QML item.
Most apps do not need to display native views. Instead, they can use the Felgo Apps Components. Certain advanced use cases might require to directly use native views and widgets.
NativeView is useful if you want to add native functionality to your Felgo app. For example, you can display a native Button
, ImageView
or WebView
.
This allows you to use the full power of QML, like animations and graphical effects, with any native view. See Usage Example for a full example of a QML component that shows a
native Button
.
You can also use this item to integrate native third-party SDKs with your Felgo app. These SDKs often offer widgets to display on Android and iOS. You can display those widgets directly within your QML scene with NativeView.
The following code shows an example implementation of a native button. It instantiates a native button on Android (android.widget.Button
) and on iOS (UIButton
). You could then use this QML type just
like AppButton within your QML scene.
The platform-specifics are defined with NativeViewBinding. The properties androidBinding and iosBinding each contain a component that defines behavior on the respective platforms.
The property viewClassName defines which view class to instantiate. Alternatively, you can customize the view initialization with onCreateView.
The view instance gets initialized via view in onViewCreated().
The example QML type has a text
property. It sets the native button's text to this value on creation and when its value changes. On Android it sets the text with TextView.setText() and On iOS with setTitle:forState:.
It adds a JavaScript function as listener to a button click event. On Android this works by calling setOnClickListener(). On iOS the function is added using addTarget:action:forControlEvents:. This function then emits a QML signal that application code can connect to.
import Felgo import QtQuick App { NativeView { id: dynamicNativeButton width: dp(170) height: dp(48) anchors.centerIn: parent property string text: qsTr("Native Button") signal clicked onTextChanged: if(binding) binding.updateText() androidBinding: NativeViewBinding { viewClassName: "android.widget.Button" onViewCreated: { updateText() // add OnClickListener: view.callMethod("setOnClickListener", function(v) { // call QML signal: dynamicNativeButton.clicked() }) } function updateText() { view.callMethod("setText", dynamicNativeButton.text, NativeObject.UiThread) } } iosBinding: NativeViewBinding { viewClassName: "UIButton" // imports readonly property NativeClass _UIColor: NativeObjectUtils.getClass("UIColor") // delegates - store strong reference here: readonly property NativeObject clickAction: NativeObjectUtils.wrap({ // note: selector name contains colon ':', so this key must also contain it "onClick:forEvent:": function(view, event) { dynamicNativeButton.clicked() } }) onViewCreated: { updateText() // configure button visuals: view.setProperty("backgroundColor", _UIColor.getProperty("grayColor")) view.callMethod("setTitleColor:forState:", [_UIColor.getProperty("blackColor"), 0]) view.callMethod("setTitleColor:forState:", [_UIColor.getProperty("whiteColor"), 1]) // add touchUpInside target: var _UIControlEventTouchUpInside = 1 << 6 view.callMethod("addTarget:action:forControlEvents:", [clickAction, "onClick:forEvent:", _UIControlEventTouchUpInside]) // target selectors can either be "doSomething", "doSomething:(id)sender" or "doSomething:(id)sender forEvent:(UIEvent*)event" // selector name must be exactly the same as the function's key in the JS object } function updateText() { view.callMethod("setTitle:forState:", [dynamicNativeButton.text, 0]) } } } }
Represents a platform-native class |
|
Represents a platform-native object |
|
Allows you to interact with objects native to the mobile platform |
|
Allows to instantiate and display platform-specific views and widgets |
|
Defines the platform specifics for NativeView |
androidBinding : Component |
This property defines how to instantiate the native view on Android. Set it to a Component of NativeViewBinding. It only creates an object of this component on Android builds.
The object specifies which native view class to instantiate via its NativeViewBinding::viewClassName property. This class should be derived from
android.view.View
. It should also have a constructor that takes a single android.content.Context
parameter.
You can then initialize the view object in NativeViewBinding::viewCreated(). You can access the instantiated view via NativeViewBinding::view.
If you do not set this property, the NativeView does not display any view on Android. Instead, it prints a warning message and behaves like an empty Item. The same happens if NativeViewBinding::viewClassName is not set to a class derived from
android.view.View
.
Example implementation to display a native android.widget.Button
:
import Felgo import QtQuick App { NativeView { id: dynamicNativeButton width: dp(170) height: dp(48) anchors.centerIn: parent property string text: qsTr("Native Button") signal clicked onTextChanged: if(binding) binding.updateText() androidBinding: NativeViewBinding { viewClassName: "android.widget.Button" onViewCreated: { updateText() // add OnClickListener: view.callMethod("setOnClickListener", function(v) { // call QML signal: dynamicNativeButton.clicked() }) } function updateText() { view.callMethod("setText", dynamicNativeButton.text, NativeObject.UiThread) } } iosBinding: NativeViewBinding {} // TODO } }
[read-only] binding : NativeViewBinding |
This property contains the currently active NativeViewBinding instance.
On Android, it contains an object created from the androidBinding component. On iOS, it contains an object created from the iosBinding component.
You can use the binding to access the native view instance via the NativeViewBinding::view property.
iosBinding : Component |
This property defines how to instantiate the native view on iOS. Set it to a Component of NativeViewBinding. It only creates an object of this component on iOS builds.
The object specifies which native view class to instantiate via its NativeViewBinding::viewClassName property. This class should be derived from
UIView
. It should also be initializable with [[viewClass alloc] initWithFrame:cgRect]
.
You can then initialize the view object in NativeViewBinding::viewCreated(). You can access the instantiated view via NativeViewBinding::view.
If you do not set this property, the NativeView does not display any view on iOS. Instead, it prints a warning message and behaves like an empty Item. The same happens if NativeViewBinding::viewClassName is not set to a class derived from
UIView
.
Example implementation to display a native UIButton
:
import Felgo import QtQuick App { NativeView { id: dynamicNativeButton width: dp(170) height: dp(48) anchors.centerIn: parent property string text: qsTr("Native Button") signal clicked onTextChanged: if(binding) binding.updateText() androidBinding: NativeViewBinding {} // TODO iosBinding: NativeViewBinding { viewClassName: "UIButton" readonly property NativeObject _UIColor: NativeObjectUtils.getClass("UIColor") onViewCreated: { updateText() // configure button visuals: view.setProperty("backgroundColor", _UIColor.getProperty("grayColor")) view.callMethod("setTitleColor:forState:", [_UIColor.getProperty("blackColor"), 0]) view.callMethod("setTitleColor:forState:", [_UIColor.getProperty("whiteColor"), 1]) // add touchUpInside target: var _UIControlEventTouchUpInside = 1 << 6 view.callMethod("addTarget:action:forControlEvents:", [{ // note: selector name contains colon ':', so this key must also contain it "onClick:forEvent:": function(view, event) { dynamicNativeButton.clicked() } }, "onClick:forEvent:", _UIControlEventTouchUpInside]) // target selectors can either be "doSomething", "doSomething:(id)sender" or "doSomething:(id)sender forEvent:(UIEvent*)event" // selector name must be exactly the same as the function's key in the JS object } function updateText() { view.callMethod("setTitle:forState:", [dynamicNativeButton.text, 0]) } } } }
updatesPerSecond : int |
This property controls at which rate the native view is drawn into the framebuffer. Higher values result in smoother views but might affect performance.
The default value of this property is 60
.