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. 在芬兰和/或其他国家的商标。所有其他商标均为各自所有者的财产。