FlutterFragment is not retaining state - flutter

I am trying to embed a Flutter app inside my existing Android app using this steps:
https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps
I am embedding the FlutterFragment inside my Activity in onCreate method, but when I rotate the screen, the fragment does not retain it's state.
This is MainActivity code:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction().also {
it.replace(android.R.id.content, Flutter.createFragment(null), "flutter")
}.commit()
} else {
val flutterFragment = supportFragmentManager.findFragmentByTag("flutter")
supportFragmentManager.beginTransaction().also {
it.attach(flutterFragment!!)
}.commit()
}
}
}

You are probably not declaring your Activity properly. The configChanges are very important for Flutter to work with Android's lifecycle.
You have to declare it on the AndroidManifest like this:
<activity
android:launchMode="singleTop"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
android:name=".MainActivity"
android:theme="#style/AppTheme.NoActionBar"/>

Related

How to receive image dragged from Safari webpage with SwiftUI `.onDrop()`

I'm not able to receive image dragged from Safari webpage in my SwiftUI app on macOS. I suppose Safari uses different mechanics, because it works properly when it comes to Chrome and Firefox. I use .onDrop() but it results empty providers no matter what kind of UTType used. Below is my code but output no provider available.
So, what UTType it is when dragging image from Safari webpage, and how can I implement it in .onDrop()
.onDrop(of: [.url, .fileURL], isTargeted: $isTarget) { providers -> Bool in
if let provider = providers.first,
let identifier = provider.registeredTypeIdentifiers.first {
print(identifier)
provider.loadItem(forTypeIdentifier: identifier) { data, error in
// Do something here
}
} else {
print("no provider available")
}
return true
}

SwiftUI - How to disable sidebar from collapsing?

Gif to understand easier
Is there any way to disable collapsibility of SidebarListStyle NavigationViews?
EDIT: This method still works as of late 2022, and has never stopped working on any version of macOS (up to latest Ventura 13.1). Not sure why there are answers here suggesting otherwise. If the Introspection library changes their API you may need to update your calls accordingly, but the gist of the solution is the same.
Using this SwiftUI Introspection library:
https://github.com/siteline/SwiftUI-Introspect
We can introspect the underlying NSSplitView by extending their functionality:
public func introspectSplitView(customize: #escaping (NSSplitView) -> ()) -> some View {
return introspect(selector: TargetViewSelector.ancestorOrSibling, customize: customize)
}
And then create a generic extension on View:
public extension View {
func preventSidebarCollapse() -> some View {
return introspectSplitView { splitView in
(splitView.delegate as? NSSplitViewController)?.splitViewItems.first?.canCollapse = false
}
}
}
Which can be used on our sidebar:
var body: some View {
(...)
MySidebar()
.preventSidebarCollapse()
}
The introspection library mentioned by Oskar is not working for MacOS.
Inspired by that, I figured out a solution for MacOS.
The rationality behind the solution is to use a subtle way to find out the parent view of a NavigationView which is a NSSplitViewController in the current window.
Below codes was tested on XCode 13.2 and macOS 12.1.
var body: some View {
Text("Replace with your sidebar view")
.onAppear {
guard let nsSplitView = findNSSplitVIew(view: NSApp.windows.first?.contentView), let controller = nsSplitView.delegate as? NSSplitViewController else {
return
}
controller.splitViewItems.first?.canCollapse = false
// set the width of your side bar here.
controller.splitViewItems.first?.minimumThickness = 150
controller.splitViewItems.first?.maximumThickness = 150
}
}
private func findNSSplitVIew(view: NSView?) -> NSSplitView? {
var queue = [NSView]()
if let root = view {
queue.append(root)
}
while !queue.isEmpty {
let current = queue.removeFirst()
if current is NSSplitView {
return current as? NSSplitView
}
for subview in current.subviews {
queue.append(subview)
}
}
return nil
}
While the method that Oskar used with the Introspect library no longer works, I did find another way of preventing the sidebar from collapsing using Introspect. First, you need to make an extension on View:
extension View {
public func introspectSplitView(customize: #escaping (NSSplitView) -> ()) -> some View {
return inject(AppKitIntrospectionView(
selector: { introspectionView in
guard let viewHost = Introspect.findViewHost(from: introspectionView) else {
return nil
}
return Introspect.findAncestorOrAncestorChild(ofType: NSSplitView.self, from: viewHost)
},
customize: customize
))
}
}
Then do the following:
NavigationView {
SidebarView()
.introspectSplitView { controller in
(controller.delegate as? NSSplitViewController)?.splitViewItems.first?.canCollapse = false
}
Text("Main View")
}
This being said, we don't know how long this will actually work for. Apple could change how NavigationView works and this method may stop working in the future.

Implement unity banner ads in swift

I have a game that I want to implement Unity banner ads to. I have implemented Unity rewarded and interstitial ads but there is no documentation or videos about banner ads. I had Admob Ads but Google blocked my account for 30 days so I need to transfer to Unity in this month.
there is my implementation:
Create method like this:
func prepareUnityBannerAdd() {
if UnityAds.isReady() {
UnityAdsBanner.initialize()
UnityAdsBanner.setDelegate(self)
UnityAdsBanner.setBannerPosition(UnityAdsBannerPosition.topCenter)
UnityAdsBanner.load(UNITY.banner) // This is my placment id string
}
}
in UnityAdsDelegate method AdsReady call like this:
func unityAdsReady(_ placementId: String) {
prepareUnityBannerAdd()
}
and finally in UnityAdsBannerDelegate method BannerDidLoad do something like this:
func unityAdsBannerDidLoad(_ placementId: String, view: UIView) {
bannerView.addSubview(view) // bannerView is just UIView to hold banner...
}
I hope this will help you

Disable the loading of Stylesheets in UIWebView and/or WKWebView

I have absolutely tried everything with this one. I've read every apple article and no where can I find how to disable the loading of CSS (Styling) in the legacy UIWebView or the new WKWebView. I don't mind what web view I use just as long as it can accomplish this.
I've tried WKPreferences() and WKWebViewConfiguration and both have no member userStyleSheetEnabled.
I've referred myself to this apple article https://developer.apple.com/documentation/webkit/webpreferences/1536396-userstylesheetenabled?
Does anyone know the answer and how to achieve this on Swift 4?
The WebView class you referenced is very old and has been deprecated. If you need to add a webview to your app, use WKWebView instead. This answer works with iOS >= 11 and macOS >= 10.13.
What you need is adding WKContentRuleList to your WKWebView's configuration. They are similar to Safari content blockers (i.e. ad-blockers) that you may already have installed on your phone:
// This should ideally be in a file but we're using string for convenience
let jsonRuleList = """
[{
"trigger": {
"url-filter": ".*",
"resource-type": ["style-sheet"]
},
"action": {
"type": "block"
}
}]
"""
// Compile the content-blocking list
WKContentRuleListStore.default().compileContentRuleList(forIdentifier: "blockStyleSheet", encodedContentRuleList: jsonRuleList) { list, error in
guard error == nil else { print(error!.localizedDescription); return }
guard let list = list else { return }
// Add the stylesheet-blocker to your webview's configuration
let configuration = WKWebViewConfiguration()
configuration.userContentController.add(list)
// Adding the webview to the view. Nothing to see here
self.webView = WKWebView(frame: self.view.bounds, configuration: configuration)
self.view.addSubview(self.webView)
// Let's try Apple's website without CSS
let request = URLRequest(url: URL(string: "https://www.apple.com")!)
self.webView.load(request)
}
Result:
References
Customized Loading in WKWebView (WWDC video)
Creating Safari Content-Blocking Rules

View disappears when apply ConstraintSet in Constraintlayout android

At the beginning, the ImageView is horizontally center. I'm moving the View to the left in Kotlin. After applying, the ImageView disappears. I don't have any clue to debug this issue
override fun onViewCreated(view: View, savedInstanceState: Bundle?){
super.onViewCreated(view, savedInstanceState)
applyConstraintSet.clone(vConstraint)
}
private fun startAnimation() {
applyConstraintSet.setHorizontalBias(R.id.ivAvatar, 0.2F)
val transition = AutoTransition()
transition.duration = 1500
transition.interpolator = AccelerateDecelerateInterpolator()
TransitionManager.beginDelayedTransition(vConstraint, transition)
applyConstraintSet.applyTo(vConstraint)
}
XML
<android.support.constraint.ConstraintLayout
android:id="#+id/vConstraint"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.facebook.drawee.view.SimpleDraweeView
android:id="#+id/ivAvatar"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_marginBottom="84dp"
android:scaleX="0"
android:scaleY="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
fresco:roundAsCircle="true" />
</android.support.constraint.ConstraintLayout>
I have the same question today.
I fixed it by adding id for all children of ConstraintLayout.
It works for me in version 1.0.2