jetpack组件_如何使用基于组件的体系结构和jetpack compose处理用户交互

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只能放在屏幕上。 本文将介绍未处理的用户交互,例如单击事件。

什么是互动? (What Is Interaction?)

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处理。

我们正在建设什么? (What Are We Building?)

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.

我们有HomeScreenMovieDetailScreen 它们都包含电影( 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处理事件。

Image for post

让我们来构建它 (Let’s Build it)

  1. 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 。 这是MovieViewComposeActivity之间的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

结论 (Conclusion)

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组件

用户点击或长按按钮时,您可以使用 Jetpack Compose 的Clickable 组件。您可以将ClickEvent 和 LongPressEvent 传递给此组件,并在其中定义相应的操作。以下是示例代码: ``` import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material.Button import androidx.compose.material.Text import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp @Composable fun ButtonWithLongClick() { val buttonState = remember { mutableStateOf(0) } Column( horizontalAlignment = Alignment.CenterHorizontally, modifier = Modifier.fillMaxWidth() ) { Button( onClick = { buttonState.value = buttonState.value + 1 }, modifier = Modifier.clickable( onClick = { //add onClick event }, onLongClick = { //add onLongClick event } ), colors = ButtonDefaults.buttonColors(backgroundColor = Color.Gray) ) { Text( text = "Click & Long Click" ) } Text( text = "Button clicked " + buttonState.value + " times" ) } } ``` 在上面的示例代码中,使用Jetpack Compose 的 Column、Button 和 Text 组件,以及 clickable Modifier。使用 remember 可以创建可变状态,在 Button 中使用 onClick 和 onLongClick 传递 ClickEvent 和 LongPressEvent 以执行相应的操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值