3

The problem is how to get the proper activity context to launch to get the Fragment Manager? From interoperability between Composables and Fragment point of view is this even possible?

   @Keep
    class Card @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null
    ) : FrameLayout( // or any other View you want
        // don't forget to use context wrapper and to apply your own theme
        ContextThemeWrapper(
            context,
            context.resources.newTheme().apply { applyStyle(R.style.FantasyTheme, true) }
        ),
        attrs
    ), GamingHubView {
    
        override fun initialize(data: Map<String, Any>?) {
            // inflate a view or render views dynamically
    //        inflate(context, R.layout.view_card, this)
    
    
            val transaction: FragmentTransaction =
                (this.context as AppCompatActivity).supportFragmentManager.beginTransaction()
            transaction.replace(
                this.id,
                BlankFragment.newInstance("", ""),
                BlankFragment::class.simpleName
            )
            transaction.addToBackStack(null)
            transaction.commit()
        }
    
    
    }
    
    /**
     * Get activity instance from desired context.
     */
    fun getActivity(context: Context?): AppCompatActivity? {
        if (context == null) return null
        if (context is AppCompatActivity) return context
        return if (context is ContextWrapper) getActivity(context.baseContext) else null
    }
Sharan
  • 1,055
  • 3
  • 21
  • 38
  • Does this answer your question? [How to get activity in compose](https://stackoverflow.com/questions/64675386/how-to-get-activity-in-compose) – Phil Dukhov Jan 07 '22 at 03:28
  • If you're running `setContent` from a Fragment, you can get it in the same way prior the activity. – Phil Dukhov Jan 07 '22 at 03:29
  • Not sure, the class is an overload of Composable & not even compose so I think my question itself is wrong – Sharan Jan 07 '22 at 05:23
  • 1
    Mostly avoid using context of any form in composable and supply handling classes as params... – MobileEvangelist Jan 07 '22 at 12:00
  • This might address your question https://medium.com/mobile-app-development-publication/load-fragments-in-jetpack-compose-beyond-what-google-taught-356a7981268d?sk=43b363c34040c646454d1629ef5f504b – Elye Jun 24 '22 at 08:45

2 Answers2

1

You can get a reference to the activity from within a compose function with this line:

val activity = LocalContext.current as? AppCompatActivity ?: return

Then you can get the support fragment manager and do fragment transactions from within your compose code.

activity.supportFragmentManager.commit {
    ...
}

I think this is not in the full spirit of compose but if you have a hybrid fragment/compose app then I don't see the harm in doing this.

Trevor
  • 1,349
  • 10
  • 16
0

I have searched for this everywhere but I couldn't find that specific answer. I guess what you are trying to do is combine compose and fragment. What I did in my case was created a MyActivity with a compose view that fills the entire screen like this

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MyActivity">

    <androidx.compose.ui.platform.ComposeView
        android:id="@+id/compose_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Then in MyActivity onCreate method, you instantiate your compose view like this

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_capture)

        findViewById<ComposeView>(R.id.compose_view).setContent {
            **YourTheme** {

            }
        }
    }

Then anywhere in your activity, you have access to supportFragmentManager that you can use to perform fragment transactions. All compose function will be done within the composeView.setContent { }

ilatyphi95
  • 555
  • 5
  • 22