import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.Button
import android.widget.LinearLayout
import android.widget.TextView
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import com.example.myapp.R
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Set content with a mix of View-based and Compose UI
setContentView(R.layout.activity_main)
// Find the ComposeView in the XML layout
val composeView = findViewById<ComposeView>(R.id.compose_view)
// Set Compose content in ComposeView
composeView.setContent {
MyComposeContent()
}
}
}
// Legacy View-based component to be used in Compose
@Composable
fun LegacyTextView(counter: Int, modifier: Modifier = Modifier) {
AndroidView(
factory = { context ->
TextView(context).apply {
text = "Legacy View Counter: $counter"
textSize = 16f
setPadding(16, 16, 16, 16)
}
},
update = { view ->
// Update the view when counter changes
view.text = "Legacy View Counter: $counter"
},
modifier = modifier
)
}
// Compose component to be used in View-based layout
@Composable
fun MyComposeContent() {
MaterialTheme {
var counter by remember { mutableStateOf(0) }
Column(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
// Pure Compose UI
Text(
text = "Compose Counter: $counter",
style = MaterialTheme.typography.headlineSmall
)
Spacer(modifier = Modifier.height(16.dp))
// Legacy View embedded in Compose
LegacyTextView(counter = counter)
Spacer(modifier = Modifier.height(16.dp))
// Compose Button
Button(onClick = { counter++ }) {
Text("Increment Counter")
}
}
}
}
// XML layout (res/layout/activity_main.xml)
<xaiArtifact artifact_id="2f898c5b-459f-43c2-9441-2eac3360e207" artifact_version_id="81208868-168e-4def-a326-74ce5d1336b5" title="activity_main.xml" contentType="text/xml">
<?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"
android:padding="16dp">
<!-- Legacy View-based UI -->
<TextView
android:id="@+id/legacy_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Legacy View-based UI"
android:textSize="18sp"/>
<!-- ComposeView for embedding Compose content -->
<androidx.compose.ui.platform.ComposeView
android:id="@+id/compose_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<!-- Legacy Button -->
<Button
android:id="@+id/legacy_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Legacy Button"/>
</LinearLayout>
This implementation demonstrates:
- ComposeView in View-based System:
- Uses ComposeView in activity_main.xml to embed Compose UI in a traditional View-based layout
- Sets Compose content in MainActivity using setContent on the ComposeView
- Combines with legacy TextView and Button in the XML layout
- AndroidView in Compose:
- Uses AndroidView to embed a legacy TextView in the Compose hierarchy
- Provides factory to create the View and update to handle state changes
- Synchronizes with Compose's counter state
- Hybrid UI Features:
- Maintains a shared counter state in Compose
- Updates both Compose and View-based components
- Demonstrates seamless interaction between the two systems
- Best Practices:
- Proper use of MaterialTheme for consistent styling
- State management with remember and mutableStateOf
- Efficient layout with Compose's Column and modifiers
- Clean separation of concerns between View and Compose systems
To use this:
- Add the XML layout to res/layout/activity_main.xml
- Include the Kotlin code in MainActivity.kt
- Ensure dependencies in build.gradle:
Comments
Post a Comment