Interoperabilidad de Jetpack Compose and View

prefacio


Para Compose, al menos la combinación con View es perfecta.

La flexibilidad de construir la interfaz de usuario aún está garantizada:

  • Si desea utilizar Compose para la nueva interfaz, puede hacerlo.
  • Si Compose no lo admite, use View.
  • Si no desea mover la interfaz existente, puede dejarla intacta.
  • Si desea utilizar Compose para parte de la interfaz existente, puede hacerlo.
  • Algunos efectos de la interfaz de usuario quieren reutilizar los anteriores, sí, se pueden incrustar directamente.

Este artículo son algunas demostraciones simples que se llaman entre sí. Se pueden copiar y pegar en el uso inicial, lo cual es muy útil.

Documentación oficial:
https://developer.android.com/jetpack/compose/interop/interop-apis

Utilice Redactar en Actividad o Fragmento para crear una interfaz de usuario

Usar Redactar en Actividad

class ExampleActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
 
        setContent { // In here, we can call composables!
            MaterialTheme {
                Greeting(name = "compose")
            }
        }
    }
}
 
@Composable
fun Greeting(name: String) {
    Text(text = "Hello $name!")
}

 

Usar Componer en Fragmento

class PureComposeFragment : Fragment() {
    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        return ComposeView(requireContext()).apply {
            setContent {
                MaterialTheme {
                    Text("Hello Compose!")
                }
            }
        }
    }
}

 

Uso de Componer en vista

ComposeView está incrustado en Xml:

Agregado a un archivo de diseño xml sin complicacionesComposeView

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
 
    <TextView
        android:id="@+id/hello_world"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Hello from XML layout" />
 
    <androidx.compose.ui.platform.ComposeView
        android:id="@+id/compose_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
 
</LinearLayout>

Al usarlo, primero encuéntrelo de acuerdo con la identificación y luego configure el contenido:

class ComposeViewInXmlActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_compose_view_in_xml)
 
        findViewById<ComposeView>(R.id.compose_view).setContent {
            // In Compose world
            MaterialTheme {
                Text("Hello Compose!")
            }
        }
    }
}
Agregar dinámicamente ComposeView

El uso en el código addView()para agregar Vista ComposeViewtambién se aplica a

class ComposeViewInViewActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
 
        setContentView(LinearLayout(this).apply {
            orientation = VERTICAL
            addView(ComposeView(this@ComposeViewInViewActivity).apply {
                id = R.id.compose_view_x
                setContent {
                    MaterialTheme {
                        Text("Hello Compose View 1")
                    }
                }
            })
            addView(TextView(context).apply {
                text = "I'm am old TextView"
            })
            addView(ComposeView(context).apply {
                id = R.id.compose_view_y
                setContent {
                    MaterialTheme {
                        Text("Hello Compose View 2")
                    }
                }
            })
        })
    }
}

 

Aquí LinearLayoutse suman tres hijos: dos ComposeViewy uno de por medio TextView.

Actúa como un puente ComposeView. ViewGroupEs una Vista en sí misma, por lo que se puede mezclar en el árbol de jerarquía de la Vista para ocupar un lugar.
Su setContent()método abre la puerta al mundo Compose, donde puede pasar al método componible para dibujar el interfaz de usuario

Uso de vistas en Compose

Hemos creado una interfaz de usuario con Compose, ¿cuándo necesitaremos incrustar View en ella?

  • La vista que se utilizará no tiene una versión Compose, por ejemplo AdViewMapViewWebView.
  • Hay una parte de la interfaz de usuario que se escribió antes y no quiero moverla (temporalmente o para siempre), y quiero usarla directamente.
  • Si no puede lograr el efecto deseado con Compose, debe usar View.

Agregar vista de Android a Componer

ejemplo:

@Composable
fun CustomView() {
    val state = remember { mutableStateOf(0) }
 
    //widget.Button
    AndroidView(
        factory = { ctx ->
            //Here you can construct your View
            android.widget.Button(ctx).apply {
                text = "My Button"
                layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
                setOnClickListener {
                    state.value++
                }
            }
        },
        modifier = Modifier.padding(8.dp)
    )
    //widget.TextView
    AndroidView(factory = { ctx ->
        //Here you can construct your View
        TextView(ctx).apply {
            layoutParams = LinearLayout.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
        }
    }, update = {
        it.text = "You have clicked the buttons: " + state.value.toString() + " times"
    })
}

 

El puente aquí es AndroidViewque es un método componible:

@Composable
fun <T : View> AndroidView(
    factory: (Context) -> T,
    modifier: Modifier = Modifier,
    update: (T) -> Unit = NoOpUpdate
)

 

La fábrica recibe un parámetro de contexto para crear una vista.
El método de actualización es una devolución de llamada, que se ejecutará después de inflar y también se ejecutará después de que cambie el valor del estado de lectura.

Usando el diseño xml en Compose

El método de uso de AndroidView en Compose mencionado anteriormente está bien para una pequeña cantidad de interfaz de usuario. ¿
Qué pasa si necesita reutilizar un diseño xml existente?
No tenga miedo, el enlace de vista está aquí.

También es muy simple de usar:

  • Primero debe habilitar Ver enlace.
buildFeatures {
    compose true
    viewBinding true
}

 

  • En segundo lugar, necesita un diseño xml, como complex_layout.
  • A continuación, agregue una dependencia de enlace de vista Compose:  androidx.compose.ui:ui-viewbinding.

Luego constrúyalo, genere la clase de enlace
y estará bien

@Composable
private fun ComposableFromLayout() {
    AndroidViewBinding(ComplexLayoutBinding::inflate) {
        sampleButton.setBackgroundColor(Color.GRAY)
    }
}

 

Entre ellos ComplexLayoutBindingestá la clase generada según el nombre del diseño.

AndroidViewBindingAndroidViewEl método componible todavía se llama internamente .

Mostrar fragmentos en Redactar

Esta escena suena un poco extraña, porque el concepto de diseño de Compose parece ser decir adiós a Fragment
En la interfaz de usuario creada por Compose, encuentre un lugar para mostrar un Fragment, que es un poco como poner vino añejo en una botella nueva.

Pero hay muchas escenas encontradas, tal vez realmente puedas conocerlas.

El fragmento se agrega a través de FragmentManager y requiere un contenedor de diseño.
Cambie el ejemplo anterior de ViewBinding, agregue un fragmentContainer al diseño y haga clic para mostrar Fragmento:

Column(Modifier.fillMaxSize()) {
    Text("I'm a Compose Text!")
    Button(
        onClick = {
            showFragment()
        }
    ) {
        Text(text = "Show Fragment")
    }
    ComposableFromLayout()
}
 
@Composable
private fun ComposableFromLayout() {
    AndroidViewBinding(
        FragmentContrainerBinding::inflate,
        modifier = Modifier.fillMaxSize()
    ) {
 
    }
}
 
private fun showFragment() {
    supportFragmentManager
        .beginTransaction()
        .add(R.id.fragmentContainer, PureComposeFragment())
        .commit()
}

 

La cuestión del tiempo no se considera aquí, porque hacer clic en el botón para mostrar el Fragmento retrasa el tiempo.
Si desea mostrar el Fragmento directamente durante la inicialización, se puede generar una excepción:

java.lang.IllegalArgumentException: No view found for id

 

Solución:

@Composable
private fun ComposableFromLayout() {
    AndroidViewBinding(
        FragmentContrainerBinding::inflate,
        modifier = Modifier.fillMaxSize()
    ) {
        // here is safe
        showFragment()
    }
}

 

 

Por lo tanto, el momento del espectáculo debe garantizar al menos que la vista del contenedor se haya inflado.

Tema y estilo

Migre la aplicación View a Compose, es posible que necesite un adaptador de tema:
https://github.com/material-components/material-components-android-compose-theme-adapter

Acerca del uso de la redacción en la aplicación de vista existente:
https://developer.android.com/jetpack/compose/interop/compose-in-existing-ui

Resumir

La combinación de Compose y View se basa principalmente en dos puentes.
Es bastante interesante:

  • ComposeViewEn realidad es una vista de Android.
  • AndroidViewDe hecho, es un método Composable.

La compatibilidad entre Compose y View garantiza que el proyecto se pueda migrar gradualmente y también da suficiente sensación de seguridad, al igual que la migración de proyectos de Java a Kotlin en aquel entonces.
 

おすすめ

転載: blog.csdn.net/qq_39312146/article/details/130632595