jetpack组件
In my previous article, we created reusable UIComponents using Jetpack Compose:
在上一篇文章中,我们使用Jetpack Compose创建了可重用的UIComponent:
It had limited capability, as UIComponents could only be laid out on the screen. This article will cover user interactions, like click events, that were not handled.
它的功能有限,因为UIComponents只能放在屏幕上。 本文将介绍未处理的用户交互,例如单击事件。
It is an event on the UIComponents (e.g. a click event on the MovieUI component).
这是UIComponents上的一个事件(例如, MovieUI组件上的click事件)。
The interaction on the UIComponent will be handled by the ComposeActivity class that includes UIComponents. For example, a click event on the MovieView in the HomeScreen is handled by HomeScreen Activity.
UIComponent上的交互将由包含UIComponent的ComposeActivity类处理。 例如, MovieView上的click事件 在HomeScreen中,由HomeScreen Activity处理。
We have HomeScreen and MovieDetailScreen. Both of them contain movies (MovieView). A click on MovieView should result in navigation to the MovieDetailScreen of the clicked movie.
我们有HomeScreen和MovieDetailScreen 。 它们都包含电影( MovieView ) 。 单击MovieView应该可以导航到MovieDetailScreen 点击的电影
This calls for following the changes in the Architecture(in red):
这要求遵循体系结构中的更改(红色):
Our ViewModel (presentation) layer remains the same. 我们的ViewModel(表示)层保持不变。UIComponent propagates the events to the ComposeActivity through an interface (UIDelegate — explained below).
UIComponent通过接口将事件传播到ComposeActivity ( UIDelegate ,在下面进行解释)。
ComposeActivity handles the events by implementing the interface above.
ComposeActivity通过实现上述接口ComposeActivity处理事件。
First, we need to change the UIComponent. We convert it to a generic interface of type UIDelegate. The composableView() function now takes in the generic UIDelegate.
首先,我们需要更改UIComponent。 我们将其转换为UIDelegate类型的通用接口。 现在, composableView()函数接受通用UIDelegate 。
interface UIDelegate interface UIComponent<T: UIDelegate> { @Composable fun composableView(delegate: T): ComposableView }What is UIDelegate? It’s an interface responsible for sending the UI events/interactions from UIComponent to View (activity). This is explained with an example below.
什么是UIDelegate ? 它是一个接口,负责将UI事件/交互从UIComponent发送到View (活动)。 下面通过一个示例对此进行说明。
MovieView should now be able to send the click events. As pointed out above, the interactions are handled through the UIDelegate. For this, the MovieUIDelegate interface is created with the capability of receiving the clicks on the movie.
电影浏览 现在应该能够发送点击事件。 如上所述,交互是通过UIDelegate处理的。 为此,创建了MovieUIDelegate接口,它具有接收电影点击的功能。
This UIDelegate is passed as an argument to the Composable function.
该UIDelegate作为参数传递给Composable函数。
interface MovieUIDelegate: UIDelegate { fun movieClick(movie: Movie) } /** * MovieUIDelegate is the extra argument added for handling the interaction. */ @Composable fun MovieView(movie: Movie, delegate: MovieUIDelegate) { val state = ImageState() Clickable(onClick = { // Notifies the UIDelegate that click event has occured on the movie. delegate.movieClick(movie) }) { .... // Everything remains the same .... } }2. Consequently, MovieListUIComponent is responsible for passing the MovieUIDelegate to the MovieView. This is a middle man between the MovieView and ComposeActivity.
2 。 因此, MovieListUIComponent负责将MovieUIDelegate传递给MovieView 。 这是MovieView和ComposeActivity之间的ComposeActivity 。
class MovieListUIComponent( private val subHeader: String, private val movieList: List<Movie> ) : UIComponent<MovieUIDelegate> { /** * MovieUIDelegate is an argument passed, * which is then passed on to the MovieView for handling the interaction */ override fun composableView(delegate: MovieUIDelegate): ComposableView = { HMovieListView(header = subHeader, movieList = movieList, delegate = delegate) } }3.View (Jetpack Compose activity) should implement MovieUIDelegate to handle the events. A click on the movie opens the MovieDetailScreen of that movie.
3. View (Jetpack Compose活动)应实现MovieUIDelegate来处理事件。 单击电影即可打开MovieDetailScreen 那部电影。
class MovieDetailActivity : AppCompatActivity(), MovieUIDelegate { fun onCreate() { ... ... setContent { // Passes the movieUIDelegate MovieDetailPageView(vm.pageData, delegate = this) } } // Implements the MovieUIDelegate function override fun onMovieClick(movie: Movie) { /** * Launches the new MovieDetailActivity for the clicked movie */ startActivity(getIntent(this, movieId = movie.id)) } }The UIDelegate implemented by the ComposeActivity is passed to the component while rendering it out on the screen.
由ComposeActivity实现的UIDelegate在传递到屏幕上时传递给该组件。
@Composable fun MovieDetailPageView(data: LiveData<MovieDetailPageUiModel>, delegate: MovieUIDelegate) { val pageUiModel = observe(data = data) VStack { pageUiModel?.components()?.forEach { /** Additionally UIDelegate is passed to the UIComponent so that * the activity can handle the interaction **/ it.composableView(delegate = delegate).render() } } }You can get the complete code here:
您可以在此处获取完整的代码:
In the case of ComposeActivity handling multiple components, which usually is the case, it needs to implement all the UIDelegates of all the UIComponents that it incorporates in its view.
在通常情况下处理ComposeActivity的情况下,它需要实现其视图中合并的所有UIComponent的所有UIDelegates 。
That’s it! We have created a UIComponent that sends events to the outside world. For now, these events are sent to the ComposeActivity. In the following article, we’ll see how the UIComponent interacts with the presentation layer. Also, we’ll see the inter-communication between UIComponents.
而已! 我们创建了一个UIComponent来将事件发送到外界。 目前,这些事件已发送到ComposeActivity 。 在下面的文章中,我们将看到UIComponent如何与表示层交互。 另外,我们将看到UIComponent之间的相互通信。
翻译自: https://medium.com/better-programming/how-to-handle-user-interactions-with-component-based-architecture-and-jetpack-compose-196e8cdd1aee
jetpack组件
相关资源:jdk-8u281-windows-x64.exe