SplashScreen compat library with Jetpack Compose - android-jetpack-compose

Is it possible to properly use the SplashScreen compat library (https://developer.android.com/about/versions/12/splash-screen-migration#splashscreen_compat_library) with Jetpack Compose? It is desirable to immediately call setContent in onCreate, like so:
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
installSplashScreen()
setContent {
// ...
}
}
}
However, setContent replaces the root view when it finishes loading. Therefore, the splash screen exit animation does not finish. The alternative is to call setContent when the exit animation finishes, but this is inefficient. Is there any other alternative?

This problem has been fixed with version 1.0.0-alpha02 of the library. See https://developer.android.com/jetpack/androidx/releases/core#core-splashscreen-1.0.0-alpha02 for details.

Related

Communication beet fragment and jetpack compose screen

I am using navigation component and single activity pattern. Now I am using jetpack compose inside fragment with xml layout. I have integrate with library. The library for checking user card data. After launching library from fragment it override to method success and failed. Now I want to change from fragment composable screen state. How I can implement it. Here is my code
#AndroidEntryPoint
#OptIn(ExperimentalMaterialApi::class)
class InstallmentFragment : Fragment(),ResultListener {
private val viewModel: TrancheViewModel by viewModels()
private val preferenceHelper by lazy { PreferenceHelper.defaultPreference(requireContext()) }
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View { // Inflate the layout for this fragment
requireActivity().window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
return ComposeView(requireActivity()).apply {
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
setContent {
AppTheme {
Navigation(SectionName.nasiyaMain.name)
}
}
ViewCompat.setOnApplyWindowInsetsListener(rootView) { view, insent ->
val bottom = insent.getInsets(WindowInsetsCompat.Type.ime()).bottom
view.updatePadding(bottom = bottom)
insent
}
}
}
override fun onError(e: Exception) {
TODO("Not yet implemented")
}
override fun onSuccess(result: MyResult) {
TODO("Not yet implemented")
}
}
I want to change composable screen content onSuccess function
There are so many ways to fix your problem. the simplest way is using mutableStateOf as a property in InstallmentFragment and changing its value in onResult method.
I suggested seeing this.

Embed iOS UIViewController in a Flutter widget

I have a Flutter fullscreen modal widget with a header, a footer and some content which should be rendered natively for iOS. I know I can host iOS UIViews in Flutter using Platform Views and I managed to do all the logic to get this working.
My issue is that I need to host a whole view controller within this widget, not only a simple view, and this view controller belongs to a third-party framework.
An option would be implementing the header and footer natively, but this would take a lot of time since this would involve passing lot of data, performing network requests, adding callbacks and so on. I read online that a UIKitViewController exists, but it can only be created from PlatformViewServices, which is still a work in progress and should not be used. I didn't manage to find proper documentation online.
I think you can try this.
class NativeView: NSObject, FlutterPlatformView {
private var _vc: UIViewController
init(
frame: CGRect,
viewIdentifier viewId: Int64,
arguments args: Any?,
binaryMessenger messenger: FlutterBinaryMessenger?
) {
_vc = UIViewController()
super.init()
}
func view() -> UIView {
return _vc.view
}
}
Calling _vc.view will call loadView() and viewDidLoad() when view is not initialized yet.

ComposeView with view binding

I added a ComposeView in my XML layout file. I use view binding to inflate this file in my Activity. When I try to call binding.myComposeView.setContent { ... } then I get the following compilation error: Unresolved reference: setContent. When I take a look at the generated binding file, the type of myComposeView is View and not ComposeView. When I use findViewById<ComposeView>(R.id.myComposeView).setContent { ... } then everything works fine. Why is the binding not generated correctly? What can I do to use view binding with a ComposeView?
It turns out that I had two versions of the same layout: portrait and horizontal. I converted the portrait one to Compose by replacing a LinearLayout with a ComposeView. However, in the horizontal layout myComposeView was still a LinearLayout. That's why the view binding class that got created had a field myComposeView of type View instead of ComposeView. The view with the same id had different types in two layout versions.
Maybe there is a problem with the way the binding is set up in onCreate of your activity. Are you using something along the lines of the following code? :
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
val view = binding.root
setContentView(view)
binding.composeView.setContent {
MaterialTheme {
Text(text = "Hello World")
}
}
}

Android text selection toolbar is not showing up while using SelectionContainer in Jetpack Compose

I want to create selectable text using Jetpack Compose. Sample code is as following
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
TextSelectionTheme {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
Greeting("Android")
}
}
}
}
}
#Composable
fun Greeting(name: String) {
SelectionContainer(){
Text(text = "Hello This is a sample text for testing out selections $name!")
}
}
The problem is, it is showing only copy button near selection.
but when I use normal text view with isSelectable = true, it shows Android text selection toolbar,
Need help to understand how to show such toolbar in Jetpack compose when some text is selected and also is it possible to show More custom options ?

buildMenu is called in AppDelegate but not UIViewController

I'm attempting to create a custom menu for each view in my app, however it appears buildMenu is not being called in View Controllers. Here's an example:
In my AppDelegate, this code is used, which works 100% as expected.
override func buildMenu(with builder: UIMenuBuilder) {
print("Updating menu from AppDelegate")
super.buildMenu(with: builder)
let command = UIKeyCommand(
input: "W",
modifierFlags: [.command],
action: #selector(self.helloWorld(_:))
)
command.title = "Hello"
builder.insertChild(UIMenu(
__title: "World",
image: nil,
identifier: UIMenu.Identifier(rawValue: "com.hw.hello"),
options: [],
children: [command]
), atEndOfMenu: .file)
}
#objc private func helloWorld(_ sender: AppDelegate) {
print("Hello world")
}
However I need to change the options available in the menu depending on where the user is in the app, so I tried doing this in a UIViewController:
override func viewDidAppear(_ animated:Bool){
// Tried all of these to see if any work
UIMenuSystem.main.setNeedsRebuild()
UIMenuSystem.context.setNeedsRebuild()
UIMenuSystem.main.setNeedsRevalidate()
UIMenuSystem.context.setNeedsRevalidate()
}
and again..
// This is never called
override func buildMenu(with builder: UIMenuBuilder) {
print("Updating menu in View Controller")
}
but the buildMenu in the UIViewController is never called :(
Any ideas if this is intended behavior or if there are any workarounds?
For main menus, the system only consults UIApplication and UIApplicationDelegate, since main menus can exist without any window and hence without any UIViewController hierarchy. That's why your override on UIViewController doesn't get called for main menus.
For context menus, the system does consult the full responder chain starting at the view.
If you need to update main menu commands depending on their context:
You could leave buildMenu(with:) in UIApplicationDelegate, arrange for delegate to figure out when and what changed and call UIMenuSystem.main.setNeedsRebuild() when it does change, or
You could define a private method buildMyMenu(with:) in your UIViewController subclasses, and arrange for buildMenu(with:) in UIApplicationDelegate to call it, or
You could build a static menu in buildMenu, and rely on your overrides of canPerformAction(_:withSender:) and validate(_:) to enable or disable or even hide particular commands e.g. by updating the attributes property in your validate(_:) override.
This is the intended behavior. Quoting from docs:
Because menus can exist with no window or view hierarchy, the system only consults UIApplication and UIApplicationDelegate to build the app’s menu bar.
The same docs page explains how you can adjust the menu commands from view controllers, and there is a great sample project too, so make sure to check it.

Resources