Sinua
Platforms

Android View

Use Sinua from XML layouts and classic Android Views.

SinuaViewLayout is a regular Android View: put it in an XML layout with its attributes, or create it in code. Under the hood it hosts the Compose view, so it looks and behaves identically.

The layout lives in res/layout/ (Android resource names are lowercase), and the activity finds the view by id:

orb_screen.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <dev.sinua.view.SinuaViewLayout
        android:id="@+id/orb"
        android:layout_width="160dp"
        android:layout_height="160dp"
        android:layout_gravity="center"
        android:contentDescription="Assistant"
        app:fxPattern="listening"
        app:fxTheme="auto"
        app:fxMaxFps="30" />
</FrameLayout>
android-view.kt
package snippets.platforms

import android.os.Bundle
import androidx.activity.ComponentActivity
import dev.sinua.view.SinuaViewLayout
import dev.sinua.voice.LocalMicVoiceSource
import snippets.R

class OrbActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.orb_screen)
        val orb = findViewById<SinuaViewLayout>(R.id.orb)
        // Every XML attribute is also a property; setting one redraws.
        orb.pattern = "speaking"
        orb.voice = LocalMicVoiceSource()   // connect it once RECORD_AUDIO is granted
    }
}
  • Attributes: app:sinuaPattern="speaking", app:sinuaTheme="auto", and android:contentDescription for the accessible name. For a design file, use app:sinuaSpecAsset="assistant.fxspec.json" (a file in assets/) with app:sinuaState="listening" for the lifecycle state. Every attribute has a Kotlin property without the fx prefix (fxPattern → pattern, fxState → state, fxMaxFps → maxFps), and setting one updates the view. fxSpecAsset is the exception: it loads the file into spec.
  • Host: like any Compose-in-View, it needs a lifecycle owner: a ComponentActivity, AppCompat 1.3+ or Fragment 1.3+.
  • Ids: give each instance a unique id, so its saved state is restored correctly.