Android Studio 项目中的 QML
概览
本示例包含一个可导入到 Android Studio 的 QML 项目,您可以使用 Qt Tools for Android Studio 插件将其导入,并使用 Java 和 Kotlin 项目,这些项目利用了 QtQuickView API。
有关 QML 的工作方式更多信息,请参阅 Qt Qml。本文档将重点介绍如何将 QML 组件嵌入基于 Java 和 Kotlin 的 Android 应用程序中。

首先,我们来查看 Java 和 Kotlin 项目中 MainActivity 的 onCreate() 方法。
对于基于 Java 的项目
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
m_mainLinear = findViewById(R.id.mainLinear);
m_getPropertyValueText = findViewById(R.id.getPropertyValueText);
m_qmlStatus = findViewById(R.id.qmlStatus);
m_androidControlsLayout = findViewById(R.id.javaLinear);
m_box = findViewById(R.id.box);
m_switch = findViewById(R.id.switch1);
m_switch.setOnClickListener(view -> switchListener());
m_qmlView = new QtQuickView(this, "qrc:/qt/qml/qml_in_android_view/main.qml",
"qml_in_android_view");
// Set status change listener for m_qmlView
// listener implemented below in OnStatusChanged
m_qmlView.setStatusChangeListener(this);
ViewGroup.LayoutParams params = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
m_qmlFrameLayout = findViewById(R.id.qmlFrame);
m_qmlFrameLayout.addView(m_qmlView, params);
Button button = findViewById(R.id.button);
button.setOnClickListener(view -> onClickListener());
// Check target device orientation on launch
handleOrientationChanges();
}对于基于 Kotlin 的项目
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
m_binding = ActivityMainBinding.inflate(layoutInflater)
val view = m_binding.root
setContentView(view)
m_binding.signalSwitch.setOnClickListener { switchListener() }
m_qmlView = QtQuickView(
this, "qrc:/qt/qml/qml_in_android_view/main.qml",
"qml_in_android_view"
)
// Set status change listener for m_qmlView
// listener implemented below in OnStatusChanged
m_qmlView!!.setStatusChangeListener(this)
val params: ViewGroup.LayoutParams = FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
)
m_binding.qmlFrame.addView(m_qmlView, params)
m_binding.changeColorButton.setOnClickListener { onClickListener() }
// Check target device orientation on launch
handleOrientationChanges()
}注意:在 Kotlin 项目中,我们使用 View binding 来访问应用程序的 UI 组件
m_binding = ActivityMainBinding.inflate(layoutInflater) val view = m_binding.root setContentView(view)
在 onCreate() 方法内,通过给 QtQuickView 参数提供 Java/Kotlin 应用程序 Context、QML 项目 main.qml 文件的 URI 以及 QML 项目的库名作为参数,创建了一个名为 m_qmlView 的 QtQuickView 实例。
对于基于 Java 的项目
m_qmlView = new QtQuickView(this, "qrc:/qt/qml/qml_in_android_view/main.qml",
"qml_in_android_view");对于基于 Kotlin 的项目
m_qmlView = QtQuickView(
this, "qrc:/qt/qml/qml_in_android_view/main.qml",
"qml_in_android_view"
)m_qmlView 然后被添加到具有适当布局参数的 Android FrameLayout ViewGroup 中。
对于基于 Java 的项目
ViewGroup.LayoutParams params = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
m_qmlFrameLayout = findViewById(R.id.qmlFrame);
m_qmlFrameLayout.addView(m_qmlView, params);对于基于 Kotlin 的项目
val params: ViewGroup.LayoutParams = FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT
)
m_binding.qmlFrame.addView(m_qmlView, params)与 QML 组件交互
为了与嵌入的 QML 组件进行交互,我们首先需要实现 QtQuickView 的公共接口 StatusChangeListener。
对于基于 Java 的项目
public class MainActivity extends AppCompatActivity implements QtQuickView.StatusChangeListener{ ... }
对于基于 Kotlin 的项目
class MainActivity : AppCompatActivity(), QtQuickView.StatusChangeListener{ ... }
然后,定义一个对 StatusChangeListener 回调函数 onStatusChanged() 的重写。
对于基于 Java 的项目
@Override
public void onStatusChanged(int status) {
Log.i(TAG, "Status of QtQuickView: " + status);
final String qmlStatus = getResources().getString(R.string.qml_view_status)
+ m_statusNames.get(status);
// Show current QML View status in a textview
m_qmlStatus.setText(qmlStatus);
// Connect signal listener to "onClicked" signal from main.qml
// addSignalListener returns int which can be used later to identify the listener
if (status == QtQuickView.STATUS_READY && !m_switch.isChecked()) {
m_qmlButtonSignalListenerId = m_qmlView.connectSignalListener("onClicked", Object.class,
(String signal, Object o) -> {
Log.i(TAG, "QML button clicked");
m_androidControlsLayout.setBackgroundColor(Color.parseColor(m_colors.getColor()));
});
}
}对于基于 Kotlin 的项目
override fun onStatusChanged(status: Int) {
Log.v(TAG, "Status of QtQuickView: $status")
val qmlStatus = (resources.getString(R.string.qml_view_status)
+ m_statusNames[status])
// Show current QML View status in a textview
m_binding.qmlStatus.text = qmlStatus
// Connect signal listener to "onClicked" signal from main.qml
// addSignalListener returns int which can be used later to identify the listener
if (status == QtQuickView.STATUS_READY && !m_binding.signalSwitch.isChecked) {
m_qmlButtonSignalListenerId = m_qmlView!!.connectSignalListener(
"onClicked", Any::class.java
) { _: String?, _: Any? ->
Log.v(TAG, "QML button clicked")
m_binding.kotlinLinear.setBackgroundColor(Color.parseColor(m_colors.getColor()))
}
}
}然后,使用 setStatusChangeListener() 将该监听器设为监听 m_qmlView 的状态变化。
对于基于 Java 的项目
m_qmlView.setStatusChangeListener(this);
对于基于 Kotlin 的项目
m_qmlView!!.setStatusChangeListener(this)
重写的回调函数 onStatusChanged() 接收包含当前 m_qmlView 的 状态值 的 StatusChanged() 信号。如果这个 状态值 被确认是 STATUS_READY,我们就可以开始与 QML 视图进行交互了。
获取和设置 QML 视图属性值
获取和设置 QML 视图属性值是通过 QtQuickView.getProperty() 和 QtQuickView.setProperty() 方法来完成的。
当 Android 按钮的点击事件发生时,设置了 QML 组件背景颜色的根对象。
对于基于 Java 的项目
public void onClickListener() {
// Set the QML view root object property "colorStringFormat" value to
// color from Colors.getColor()
m_qmlView.setProperty("colorStringFormat", m_colors.getColor());
String qmlBackgroundColor = m_qmlView.getProperty("colorStringFormat");
// Display the QML View background color code
m_getPropertyValueText.setText(qmlBackgroundColor);
// Display the QML View background color in a view
m_box.setBackgroundColor(Color.parseColor(qmlBackgroundColor));
}对于基于 Kotlin 的项目
private fun onClickListener() {
// Set the QML view root object property "colorStringFormat" value to
// color from Colors.getColor()
m_qmlView!!.setProperty("colorStringFormat", m_colors.getColor())
val qmlBackgroundColor = m_qmlView!!.getProperty<String>("colorStringFormat")
// Display the QML View background color code
m_binding.getPropertyValueText.text = qmlBackgroundColor
// Display the QML View background color in a view
m_binding.colorBox.setBackgroundColor(Color.parseColor(qmlBackgroundColor))
}使用 QtQuickView.setProperty() 方法,我们将 "colorStringFormat" 属性值设置为从项目的 Colors.java 类中获取的随机颜色值。
此处使用 QtQuickView.getProperty(){QtQuickView.getProperty()} 方法来获取 QML 组件根对象的当前背景颜色,并在应用的 Android 端显示。
信号监听器
QtQuickView 类提供了 connectSignalListener() 和 disconnectSignalListener() 方法,用于连接和断开信号监听器到 QML 组件根对象中声明的信号。
在此,我们将信号监听器连接到 QML 组件的 onClicked() 信号。
对于基于 Java 的项目
if (status == QtQuickView.STATUS_READY && !m_switch.isChecked()) {
m_qmlButtonSignalListenerId = m_qmlView.connectSignalListener("onClicked", Object.class,
(String signal, Object o) -> {
Log.i(TAG, "QML button clicked");
m_androidControlsLayout.setBackgroundColor(Color.parseColor(m_colors.getColor()));
});
}对于基于 Kotlin 的项目
if (status == QtQuickView.STATUS_READY && !m_binding.signalSwitch.isChecked) {
m_qmlButtonSignalListenerId = m_qmlView!!.connectSignalListener(
"onClicked", Any::class.java
) { _: String?, _: Any? ->
Log.v(TAG, "QML button clicked")
m_binding.kotlinLinear.setBackgroundColor(Color.parseColor(m_colors.getColor()))
}
}onClicked() 信号在 QML UI 中的按钮每次被点击时都会发出。该信号随后被此监听器接收,并将持有应用 Android 端的布局的背景颜色设置为从项目的 Colors.java 类中获取的随机颜色值。
QtQuickView.connectSignalListener() 返回一个唯一的信号监听器 ID,我们将其存储并用于后来的标识和断开监听器。
对于基于 Java 的项目
m_qmlView.disconnectSignalListener(m_qmlButtonSignalListenerId);
对于基于 Kotlin 的项目
m_qmlView!!.disconnectSignalListener(m_qmlButtonSignalListenerId)
在此,我们使用 QtQuickView.disconnectSignalListener() 方法通过提供一个唯一的信号监听器 ID 来断开之前连接的信号监听器。
© 2024 The Qt Company Ltd. 本文档中包含的贡献的文档版权为各自所有者的版权。本提供的文档是根据自由软件基金会发布的 GNU 自由文档许可版 1.3 的条款许可的。Qt 及其相关标志是 The Qt Company Ltd. 在芬兰和/或其他国家的商标。所有其他商标均为各自所有者的财产。