Xamarin Forms Webview - webview

I am currently getting the following error whenever I try to open a page from my Angular application using Xamarin.forms.view
04-05 20:12:17.110 W/BindingManager( 3550): Cannot call determinedVisibility() - never saw a connection for the pid: 3550[INFO:CONSOLE(1)] "ERROR", source: http://my-url/main.61d2d58c98366844c6a5.bundle.js (1)
My HybridView is being created as follow:
_WebView = new UIHybridWebview
{
IsLocalData = false,
Uri = "http://my-url/#/user/create",
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
};
Where UIHybridWebView is a View from Xamarin.Form.
How could I solve this problem? All solutions that I found was related to Android.Webkit, and not Xamarin.Form

You Add Permission ?
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

So I managed to make it work. The problem was not on the WebView, but on the HybridWebView. What saved me was this post on the official Xamarin's forum.
The solution was very simple. I just had to add the following line on the "OnElementChanged" function:
webView.LayoutParameters = new global::Android.Widget.AbsoluteLayout.LayoutParams(LayoutParams.MatchParent, LayoutParams.MatchParent, 0, 0);

Related

Xamarin.Forms : UI is not rendering for the same way on iOS 10.1 and iOS 10.4

I work on a Xamarin.Forms app where I need to implement transparent/translucent navigation bar.
I've studied the the Vision Conference sample, where this is implemented.
This is achieved through a CustomNavigationPage and a CustomRenderer.
The XAML of the CustomNavigationPage is:
<?xml version="1.0" encoding="utf-8" ?>
<NavigationPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ConferenceVision.Views.CustomNavigationPage"
xmlns:iOS="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
iOS:NavigationPage.IsNavigationBarTranslucent="True"
BarTextColor="{StaticResource NavigationBarTextColor}">
<NavigationPage.BarBackgroundColor>
<OnPlatform x:TypeArguments="Color">
<On Platform="Android, iOS" Value="Transparent" />
<On Platform="UWP" Value="{StaticResource NavigationBarBackgroundColor}" />
</OnPlatform>
</NavigationPage.BarBackgroundColor>
</NavigationPage>
The code-behind of the CustomNavigationPage is:
public partial class CustomNavigationPage : NavigationPage
{
public bool IgnoreLayoutChange { get; set; } = false;
protected override void OnSizeAllocated(double width, double height)
{
if (!IgnoreLayoutChange)
base.OnSizeAllocated(width, height);
}
public CustomNavigationPage() : base()
{
InitializeComponent();
}
public CustomNavigationPage(Page root) : base(root)
{
InitializeComponent();
}
}
And the CustomRenderer is:
public class CustomNavigationRenderer : NavigationRenderer
{
public override void ViewDidLoad()
{
base.ViewDidLoad();
UINavigationBar.Appearance.SetBackgroundImage(new UIImage(), UIBarMetrics.Default);
UINavigationBar.Appearance.ShadowImage = new UIImage();
UINavigationBar.Appearance.BackgroundColor = UIColor.Clear;
UINavigationBar.Appearance.TintColor = UIColor.White;
UINavigationBar.Appearance.BarTintColor = UIColor.Clear;
UINavigationBar.Appearance.Translucent = true;
UINavigationBar.Appearance.SetTitleTextAttributes(new UITextAttributes()
{
Font = UIFont.FromName("HelveticaNeue-Light", (nfloat)20f),
TextColor = UIColor.White
});
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
}
base.Dispose(disposing);
}
}
I've tested the app on :
simulators : iPhone 6 on iOS 11.3
my device : iPhone 6 on iOS 10.1
And we can see that the results are not the same. On the simulator and iOS 11.3, there is a gap between the navigation bar and the content:
But on my device under iOS 10.1, there is no gap and the content is displayed "under" the navigation bar:
The page is built like that, but the rendering is the same on all pages:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:effects="clr-namespace:ConferenceVision.Effects"
xmlns:local="clr-namespace:ConferenceVision.Views.Renderers"
xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
ios:Page.UseSafeArea="true"
Title="About"
x:Class="ConferenceVision.Views.AboutView">
<ContentPage.Content>
<ScrollView>
<ScrollView.Margin>
<OnPlatform x:TypeArguments="Thickness" Default="15,0">
<On Platform="Android" Value="15,50,15,0"/>
</OnPlatform>
</ScrollView.Margin>
...
</ScrollView>
</ContentPage.Content>
</ContentPage>
How explain it? Could this be related to the use of UseSafeArea?
I know that I get an "old" version on my device, but in my app I have to cover the largest number of users.
The difference between iOS is related to the use of SafeArea. In iOS 11+ the safearea adds a paddind.
ios:Page.UseSafeArea="true"
It's normal for that version. You must always use the last 3 version of each mobile OS, because their marketshare grants you a better stability, compatibility and acceptance with the public.
This are the numbers for the 10.1 in the world (from NetMarketshare)
Just tell the users to use a more updated version.

Using VS 2017 Xamarin.Forms PCL iOS--how do I control the image visibility using a toggle switch?

I am new to Xamarin.Forms. My project is a cross platform PCL. Single Page. Built using VS 2017. This question pertains to the iOS platform.
Background: App layout has 13 images all with the IsVisible=False. Each image has a toggle switch.
Objective: To have the user be able to control the image visibility through the toggle switch. When the switch is toggled the image will become visible.
Code sample below. Any insight would be greatly appreciated. Thank you.
XAML
<AbsoluteLayout>
<Image x:Name="Sheep_Image" Source="1-Sheep.png" Aspect="AspectFit" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds=".15,.87,.5,.1" IsVisible="False"/>
<Switch x:Name="Switch" Toggled="Switch_Toggled"/>
</AbsoluteLayout>
xaml.cs
private void Switch_Toggled(object sender, ToggledEventArgs e){
var toggle = sender as ToggleSwitch;
Sheep_Image.IsVisible = toggle.IsOn;
}
The property for Toggle is called "IsToggled"
You need to subscribe an event handler to each toggle:
void Handle_Toggled(object sender, Xamarin.Forms.ToggledEventArgs e)
{
Sheep_Image.IsVisible = e.Value;
}
In XAML, you need this:
<Switch Toggled="Handle_Toggled" />
This should work too:
<Image x:Name="Image"></Image>
<Switch IsToggled="{Binding Source={x:Reference Image}, Path=IsVisible, Mode=TwoWay}" HorizontalOptions="Start"></Switch>
As #Dbl,#lowry0031, #BraveHeart said, I just make a summary and provide more details.
Solution 1 : Event Handle
private void Switch_Toggled(object sender, ToggledEventArgs e){
Sheep_Image.IsVisible = (sender as Switch).IsToggled;
//Or
//Sheep_Image.IsVisible = e.Value;
}
Solution 2 : Binding
<Image x:Name="Sheep_Image" Source="Icon-Small.png" Aspect="AspectFit" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds=".15,.87,.5,.1" IsVisible="False"/>
<Switch x:Name="Switch" IsToggled="{Binding Source={x:Reference Sheep_Image}, Path=IsVisible, Mode=TwoWay}"/>
PS: Make sure the image is available in your Resource folder.
Test

TextInputLayout hint issue when handling FocusChange event

My app has a couple of EditTexts with a TextInputLayout wrapped around them. This works fine in most cases, but when I attach a handler to the FocusChange event of the EditText, the hint fails to animate.
I found this issue on the android forum, but he uses the OnFocusChangeListener. Proxying the call should not be necessary with events, right?
Any ideas on this issue? Is it a bug in the Xamarin android design support NuGet package?
Thanks in advance
Layout code:
<android.support.design.widget.TextInputLayout
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content">
<EditText
android:id="#+id/txtProductCode"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:inputType="textCapCharacters|textNoSuggestions"
android:hint="Artikelcode" />
</android.support.design.widget.TextInputLayout>
Fragment code:
public override void OnStart()
{
base.OnStart();
txtProductCode.FocusChange += txtProductCode_FocusChange;
// ...
}
void txtProductCode_FocusChange(object sender, View.FocusChangeEventArgs e)
{
if (!e.HasFocus)
txtDescription.Text = GetProductDescription();
}
From this post this i found my solution for the problem.
As stated in the post it's kind of a workaround but i think this should work in the new design library version 22.2.1 but for me the problem still persists.
Here is my code based on the mentioned post:
final View.OnFocusChangeListener userNameEtFocusListener = userNameEt.getOnFocusChangeListener();
userNameEt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
userNameEtFocusListener.onFocusChange(v, hasFocus);
if (!hasFocus){
userInfoValidator.checkUserNameAvailable(userNameEt.getText().toString());
}
}
});

Cordova 5 build command is deleting iOS device orientation settings

With Cordova 5.1.1, when executing "cordova build ios", any device orientation settings previously selected in the XCode project are deleted leaving the orientation settings checkboxes unselected.
While the "orientation" config preference may provide a means of forcing orientation, I need to be able to set different orientation preferences for the iPad and iPhone.
All previous Cordova versions (below 5) respected those settings. Any ideas?
Using XCode 6.3.2.
EDIT:
According to #Abhinav Gujjar the issue causing cordova prepare to overwrite manual changes made to orientation settings in the .plist has been fixed. However, AFAIK there's still no way to set different orientation preferences for iPad vs iPhone in the config.xml, so the answer below stands.
UPDATE:
I created the plugin cordova-custom-config, which wraps up the hook below and means platform-specific custom config blocks (such as these orientation settings) can be defined in config.xml. So you can use the plugin rather than need to manually create the hook below.
This was introduced in the Cordova 5.0.0 CLI - see here.
In the meantime, I've been using an after_prepare hook as a workaround. Just place the following in <your_project>/hooks/after_prepare/some_file.js and change the orientation settings as appropriate:
#!/usr/bin/env node
// Set support for all orienations in iOS .plist - workaround for this cordova bug: https://issues.apache.org/jira/browse/CB-8953
var platforms = process.env.CORDOVA_PLATFORMS.split(',');
platforms.forEach(function(p) {
if (p == "ios") {
var fs = require('fs'),
plist = require('plist'),
xmlParser = new require('xml2js').Parser(),
plistPath = '',
configPath = 'config.xml';
// Construct plist path.
if (fs.existsSync(configPath)) {
var configContent = fs.readFileSync(configPath);
// Callback is synchronous.
xmlParser.parseString(configContent, function (err, result) {
var name = result.widget.name;
plistPath = 'platforms/ios/' + name + '/' + name + '-Info.plist';
});
}
// Change plist and write.
if (fs.existsSync(plistPath)) {
var pl = plist.parseFileSync(plistPath);
configure(pl);
fs.writeFileSync(plistPath, plist.build(pl).toString());
}
process.exit();
}
});
function configure(plist) {
var iPhoneOrientations = [
'UIInterfaceOrientationLandscapeLeft',
'UIInterfaceOrientationLandscapeRight',
'UIInterfaceOrientationPortrait',
'UIInterfaceOrientationPortraitUpsideDown'
];
var iPadOrientations = [
'UIInterfaceOrientationLandscapeLeft',
'UIInterfaceOrientationLandscapeRight',
'UIInterfaceOrientationPortrait',
'UIInterfaceOrientationPortraitUpsideDown'
];
plist["UISupportedInterfaceOrientations"] = iPhoneOrientations;
plist["UISupportedInterfaceOrientations~ipad"] = iPadOrientations;
}
Note: you'll need to install the plist and xml2js node modules if you don't already have them.
IF you want to, you can to it programmatically on the JS side.
For iOS, orientation can be programmatically controlled by defining a
javascript callback on window
/**
// #param {Number} degree - UIInterfaceOrientationPortrait: 0,
// UIInterfaceOrientationLandscapeRight: 90,
// UIInterfaceOrientationLandscapeLeft: -90,
// UIInterfaceOrientationPortraitUpsideDown: 180
* #returns {Boolean} Indicating if rotation should be allowed.
*/
function shouldRotateToOrientation(degrees) {
return true;
}
Set allowed orientations in your config.xml file
<platform name="ios">
<preference name="Orientation" value="all" />
</platform>
And add the shouldRotateToOrientation(degrees)
onDeviceReady: function() {
app.receivedEvent('deviceready');
window.shouldRotateToOrientation = function(degrees) {
//if device an iPad ?
if ( navigator.userAgent.match(/iPad/i) ) {
return true;
}
//else if device an iPhone ?
else if (navigator.userAgent.match(/iPhone/i)) {
if (degrees == 0) { //orientation is portrait
return true;
}
return false; //refuse all other orientations for iPhone
}
return true;
};
}
This issue was fixed and you can now specify orientation as 'all' in config.xml
<platform name="ios">
<preference name="Orientation" value="all" />
</platform>
Docs

AdMob AdView SDK 6.0.1 memory usage

I try to include an AdMob banner in my Android App using the AdMobsAdsSdk6.0.1.
The banner shows up correctly but increases the displayed memory-usage in the phones task manager from 2 MB to 10 MB. DDMS shows approx. 5MB. I have read some articles about possible memory leaks in older versions, but could not find anything solving my problem. I reproduced the behavior with a simple test app.
The Activity only holds the AdView
public class TestActivity extends Activity {
private AdView adView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
adView = new AdView(this, AdSize.BANNER, "adunitid");
LinearLayout layout = (LinearLayout) findViewById(R.id.content_Layout);
layout.addView(adView);
adView.loadAd(new AdRequest());
}
#Override
protected void onDestroy() {
if (adView != null) {
adView.destroy();
}
super.onDestroy();
}
}
The Manifest is also only a copy from the tutorial
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="admobtest.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="4" android:targetSdkVersion="13" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".TestActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.google.ads.AdActivity"
android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" />
</application>
</manifest>
I also tried to include the banner via xml but i finally get the same results. Switching to landscape and back raises the memory further and further. Am i missing something or can somebody give me some hint how to solve this? I thought adView.destroy solved the memory leak.

Resources