Showing posts with label xamarin. Show all posts
Showing posts with label xamarin. Show all posts

Monday, June 22, 2015

GridSplitter control for Xamarin Forms

I created a GridSplitter control for Xamarin Forms, for iOS and Android.

You can find the full description of how it works and how to include it in your app:
https://github.com/andreinitescu/GridSplitterApp

Some screenshots with sample layouts included in the sample app:

mGkd879Oqv

and a Grid with both horizontal and vertical splitters:

DnaXEi1wzw

The sample app also shows a technique to create reusable custom controls which you can style easily just with XAML, very similar to how it works on Windows.

Wednesday, June 10, 2015

Xamarin Forms: Create a style BasedOn default style defined in app's global resource dictionary

Suppose there’s a style defined in app's global resource dictionary (App.xaml):

<Style TargetType="Label">
    <Setter Property="TextColor" Value="Red" />
</Style>

And this style defined in a page:

<Style x:Key="MyLabelStyle" TargetType="Label">
    <Setter Property="FontSize" Value="14" />
</Style>

If you want MyLabelStyle to inherit the global style, one way is to use this syntax:

<Style x:Key="MyLabelStyle" TargetType="Label" BasedOn=”{StaticResource Xamarin.Forms.Label}”>

otherwise MyLabelStyle will not have the text color red.

Note that this won’t work:
<Style x:Key="MyLabelStyle" TargetType="Label" BasedOn=”{StaticResource {x:Type Label}}”>

Instead of hard coding the Label’s type full name, a nicer way would be to define a custom markup extension which resolves the Label type (something like this)

Monday, June 08, 2015

IconView control for Xamarin Forms


Someone was asking on the forum how to draw a colored icon.
I created an IconView control which does this: https://github.com/andreinitescu/IconApp/

The control takes a local image and applies a color on it. This is useful when you want to color images on the fly, without the need to have multiple images for different colors.

At this moment the implementation is for Android and iOS. Contributions for Windows support are welcome!

Usage

An example of a Page using the IconView control:
<?xml version="1.0" encoding="UTF-8"?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="IconApp.MyPage" xmlns:controls="clr-namespace:IconApp;assembly=IconApp"> <controls:IconView Source="monkey" Foreground="Red" WidthRequest="100" HeightRequest="100" HorizontalOptions="Center" VerticalOptions="Center" /> </ContentPage>
This draws the "monkey" image with red color in the center of the screen:



Add the control to your project


1. Add /IconApp/IconApp/IconView.cs to your Xamarin Forms PCL project
2. The control uses native renderes. You need to add the renderers to your Android and iOS project respectively:
/IconApp/IconApp.Droid/Renderers/IconViewRenderer.cs
IconApp/IconApp.iOS/Renderer/IconViewRenderer.cs

Note you might need to update some namespaces.

Wednesday, May 20, 2015

Manually install Xamarin Studio addins

Just copy the .dll file to (note the Xamarin Studio version, it might be different today):

on Windows:
%LocalAppData%\XamarinStudio-5.0\LocalInstall\Addins

on Mac:
/Users/[YourUser]/Library/Application Support/XamarinStudio-5.0/LocalInstall/Addins

Source:
http://forums.xamarin.com/discussion/comment/6356/#Comment_6356


Tuesday, August 05, 2014

Auto binding of outlets in Xamarin iOS and MvvmCross

 

If you are like me and you don’t like doing the bindings in code, you start thinking about solutions.

So I’m experimenting with the idea of creating the bindings at runtime, based on a simple name convention:

  • An UIButton outlet with the name 'btnXXX' is bound to the view-model 'XXXCommand' property.
  • An UITextField outlet with the name 'txtXXX' is bound to the view-model 'XXX' property.
  • An UILabel outlet with the name 'lblXXX' is bound to the view-model 'XXX' property.

For example, if you have a UIButton outlet called btnLogin, it's bound to view-model LoginCommand property.

I uploaded the code here;

https://github.com/nitescua/AutoBinding/

This can be done for other platforms as well.

Tuesday, July 29, 2014

Xamarin HttpClient NameResolutionFailure exception

 

If you look on internet there are plenty of people reporting this error.

Xamarin is somehow aware of this error, and it marked it as fixed but it doesn’t seem like it is.

Fortunately, this exception appears only in debug mode, not in release mode.

Sunday, September 22, 2013

Xamarin MVVMCross PCL Visual Studio issues

 

Introduction to MVVMCross setup

MVVMCross framework is suitable for Xamarin applications with the following structure:

- a platform-independent PCL Core (MyApp.Core) project containing your app logic like view models, services, models
- several platform specific applications projects (MyApp.Droid, MyApp.iOS, MyApp.Store)

Note that MVVMCross works with PCL targeting frameworks
’NET Framework 4.5’,
‘Silverlight 4 and higher’.
‘Windows Phone 7.5 and higher’,
‘.NET for Windows Store apps’

You don’t need to select all these, just the platforms you target but MVVMCross doesn’t work  with ‘.NET Framework 4.0’ or ‘Windows Phone 7’.

The problem

Because of the framework target profiles, Visual Studio by default won’t let you add a PCL project as reference to your Xamarin Android project in Visual Studio.
In the case of MVVMCross, you cannot add the Core PCL project to the application project.

Solutions

The solutions I’ve seen:


#1. (Most popular) Create profiles for ‘Mono for Android’ and ‘MonoTouch’ in
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETPortable\v4.0\Profile\Profile104\SupportedFrameworks
This makes the two profiles available when creating the PCL and makes Visual Studio recognizing the PCL project compatible with the Xamarin app projects.
http://slodge.blogspot.ro/2012/12/cross-platform-winrt-monodroid.html
http://jpobst.blogspot.co.uk/2012/04/mono-for-android-portable-libraries-in.html
http://psvitz.com/xamarin-vs2012-pcl-mvvm-cross-v3-awesome1one1/

#2. Manually edit the Xamarin application projects to add reference to the PCL project. It will compile fine but with a warning generated about the possible framework incompatibility
http://blog.ostebaronen.dk/2013/07/working-with-pcls-in-lates.html

#3.  The solution I am using: create PCL project and app project in Visual Studio, then use Xamarin Studio just to add the PCL project as reference to the application project. Then switch back and continue work in Visual Studio.

      (If you’ve been using the two profiles from method #1, remove them in advance. For this solution, you shouldn’t see them when creating the PCL, because they create an issue selecting the ‘WP7.5 and higher’ without these two profiles selected, see more below)
 

I also saw another way which involves using a WPF class library (you read it right).
http://neueobjective.wordpress.com/2013/08/08/using-asyncawait-system-net-http-httpclient-and-mvvmcross-in-wp8-xamarin-android-and-xamarin-ios/

 

Problems with having the ‘Mono for Android’ and ‘MonoTouch’ custom profiles

When using #1 with custom profiles, if you try to use NuGet in Visual Studio, Visual Studio will complain about the larger majority of the available toolkits in NuGet:

image

The reason is because most toolkits do not know about the ‘Mono for Android’ and ‘MonoTouch’ framework targets.
As a workaround, even if the operation failed, you can still manually add as references the toolkit assemblies downloaded by NuGet in the ‘packages’ folder. But that makes NuGet a bit less useful.

Another side issue I've noticed is with having the two profiles (‘Mono for Android’ and ‘MonoTouch’):
When you create a PCL project you cannot select 'Windows Phone 7.5 and higher' without also having the two profiles selected.
Without these two profiles selected, Visual Studio will automatically select ‘Windows Phone 7 and higher’ profile.

(Off topic about Json.NET: Json.NET happens to have a Xamarin component available in the http://components.xamarin.com/view/json.net/ but Xamarin currently does not have the Component feature for PCLs).


I am eager to hear other opinions, experiences, solutions, thoughts.

Wednesday, September 18, 2013

A first implementation of alert dialog support in Xamarin + MVVMCross


Update: You can use this MvvmCross plugin: https://github.com/brianchance/MvvmCross-UserInteraction
              At this moment however, the plugin doesn't have an implementation for Windows Phone and Windows Store, it's only for Android and iOS.

The implementation steps:
#1. In the Core PCL project, have the dialog interface declared in IDialogService.cs.
namespace MyApp.Core.Services
{
    public interface IDialogService
    {
        Task<bool?> ShowAsync(string message, string title, string OKButtonContent, string CancelButtonContent);
    }
}

#2. In the platform specific project, implement the dialog support. Example for Android:

namespace MyApp.Droid.Services
{
    public class DialogService : IDialogService
    {
        public Task<bool?> ShowAsync(string message, string title, string OKButtonContent, string CancelButtonContent)
        {
            var tcs = new TaskCompletionSource<bool?>();

            var mvxTopActivity = Mvx.Resolve<IMvxAndroidCurrentTopActivity>();
            AlertDialog.Builder builder = new AlertDialog.Builder(mvxTopActivity.Activity);
            builder.SetTitle(title)
                   .SetMessage(message)
                   .SetCancelable(false)
                   .SetPositiveButton(OKButtonContent, (s, args) =>
                    {
                        tcs.SetResult(true);
                    })
                   .SetNegativeButton(CancelButtonContent, (s, args) =>
                   {
                       tcs.SetResult(false);
                   });

            builder.Create().Show();
            return tcs.Task;
        }
    }
}


#3.
Still in the platform specific project, register the service:

namespace MyApp.Droid
{
    public class Setup : MvxAndroidSetup
    {
        public Setup(Context applicationContext) : base(applicationContext)
        {
        }

        protected override void InitializeLastChance()
        {
            Mvx.RegisterSingleton<IDialogService>(new DialogService());
            base.InitializeLastChance();
        }
    }
}

#4. In the view models, here is how I can call the display of the dialog:


void async DeleteUser()
{
    var result = await Mvx.Resolve<IDialogService>().Show("Are you sure you want to delete selected user?", "Confirmation", "OK", "Cancel");
    if(result == true)
    {
        // delete user...
    }
}


This is a first implementation of showing dialogs. There’s a lot of possible parameterization / customization, but it needs to take into account the capabilities and behavior of all platforms.
In tests, the IDialogService implementation obviously does not call showing a dialog, it does nothing.

One interesting discussion I had with Greg Shackles is about using a different approach than what I showed here: have the view full responsibility of displaying the dialog and communicate with view model using commands \ methods, etc. I understand the idea but I don't have a very clear way of doing this so until I see all the issues I think I will use this solution.

Localization in Xamarin + MVVMCross



Here is how I implement localization in my Xamarin MVVMCross (what a great pair!) app:
#1. In the Core PCL project, create resource (project properties \ Resources) and use editor to enter all localizable strings in the app (or, you might use localization tools which produce the .resx file).
     Make sure to select Public visibility for the members of the generated Resources class.image
     For the resource name, I usually use the actual string + 'Text':
         'Username' –> UsernameText. 
         'Change password' –> ChangePasswordText.
     For long strings, I try to give it a short distinctive name  + usage + 'Text':
         'NewAppVersionAvailableMessageText'  -> 'A new version of the application is currently available. Would you like to download it?'
         'DeleteUserConfirmationText'  ->  'Are you sure you want to delete selected user?'
#2. I have a BaseViewModel class derived from MvxViewModel serving as a base for all my view models. It uses an indexer to get the translated string value based on an index resource value  
public class ViewModelBase : MvxViewModel
{
    public string this[string index]
    {
        get
        {
            return Resources.ResourceManager.GetString(index);
        }
    }

#3.
(for Android, but the idea is similar to other platforms too) In the layout, I am using MVVMCross binding to bind the controls to the view model’s indexer and pass the resource name:

<TextView local:MvxBind="Text [UsernameText]"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content" />

At runtime, because of the MVVMCross binding between the TextView’s Text property and view model indexer, the Text property will call the view model’s indexer using the ‘UsernameText’ as index.
This in turn calls ResourceManager.GetString which returns the localized string.

This setup works great. I haven’t yet tried it on all the platforms but it makes sharing a single set of localized strings. Also, the resource strings can be referenced by the statically typed properties of the Resources class.

If the application needs to switch the language at runtime, it should be enough to tell the view model to notify its bound controls to refresh their values. I haven’t tried it yet, but viewModel.RaisePropertyChanged(string.Empty) should work.

There are different approaches to localization, here are few links:
N=21 - Internationalisation - i18n - N+1 Days of MvvmCros (using the MVMCross plugin) 
Using resx-files for localization in MvvmCross (mentioned in the video)
http://danielvaughan.org/post/Generating-Localized-Resources-in-Mono-for-Android-Using-T4.aspx (interesting ideas)

I am happy to hear your thoughts on this approach.

Thursday, August 29, 2013

Why use ‘AppName.Droid’ for Xamarin Android apps and not ‘AppName.Android’

 

It looks like the if you use “Android” you end up having to use `global::Android` a lot.

So even if “Android” might look better than “Droid”, use “Droid”

Monday, August 26, 2013

Xamarin iOS app setup intro (Visual Studio)


To make the Visual Studio build iOS apps, you need to install Xamarin Studio on the Mac and possibly update your XCode version. Follow the requirements and instructions from http://docs.xamarin.com/guides/ios/getting_started/introduction_to_xamarin_ios_for_visual_studio
After all setup is done, in Visual Studio create a iOS \ Universal app.
Make sure you have Solution Platforms combo-box available in the standard command bar, otherwise click on the overflow button and choose Add\Remove buttons, and choose Solution Platforms. This combo-box should show iPhone and iPhoneSimulator options.
To connect to the mac machine, I am using VNC viewer: http://www.realvnc.com/download/viewer/
In Visual Studio, running the app you might get an error on the mac: “The simulated application quit.” and an option to switch SDK.
Here’s the things I did to make it work:
- make sure you have Application name (‘HelloWorld_App1’), Identifier (‘com.helloworldapp’), Version (1) and Deployment Target (6.1) set.
- if you get the error, right click and select to dock the simulator.  I was able to select ‘Reset settings’ from the menu just before the error dialog appeared. If not try to delete ~/Library/Application Support/iPhone Simulator directory on your Mac



Other info on the iOS setup:

http://forums.xamarin.com/discussion/comment/6084/#Comment_6084
http://blogs.endjin.com/2013/05/xamarin-platform-setup-gotchas/

Monday, June 03, 2013

Issues when deploying a release version of a Xamarin app made with MVVMCross on a device (Android)

First, you can send to someone the .apk file representing the app and he can install it on the device.
There are few deployment options:
  • Via a Website – A Xamarin.Android application can be made available for download on a website, from which users may then install the application by clicking on a link.
  • By e-mail – It is possible for users to install a Xamarin.Android application from their e-mail. The application will be installed when the attachment is opened with an Android-powered device.
  • Through a Market – There are several application marketplaces that exist for distribution, such as Google Play or Amazon App Store for Android.
See more here http://docs.xamarin.com/guides/android/deployment,_testing,_and_metrics/publishing_an_application
I am trying to deploy the app on a device by sending the .apk file to someone to test it on his device.
First, I need to compile the app in Release mode and sign it. When compiling, Xamarin produces a signed version of the app.
In the \bin\Release folder, there is yourapp.apk and yourapp-Signed.apk files.

Second, I encountered different problems when running the app in Release mode on the device, there were a number of issues with MVVMCross.

The issues are related to the Xamarin linker. If you look to the build properties of the Xamarin app (In Xamarin Studio, that's project Options \ Build \ Android Build \ General tab), there are few linker options:

  1. Don't Link
  2. Link SDK Assemblies
  3. Link All Assemblies

Linking is described in Xamarin docs: http://docs.xamarin.com/guides/android/advanced_topics/linking
'Don't Link' option produces the largest app files, linker not being enabled. The app will definitely work without an issue.
Issues start appearing with the two options, becausue with these two options, the linker is enabled.
The issues appear at runtime, for example I was getting MvvMCross errors written in the application output, mentioning about bindings / events not working right.

When using the 'Don't link' linker option, the app size was 20 MB! When switching to 'Link SDK Assemblies', it was 7 MB!
The idea is to use 'Link SDK Assemblies' linker option and do the necessary to make linker do the right thing.

A solution is to force the linker include code from MVVMCross, using a dummy class.

class LinkerIncludePlease
{
private void IncludeVisibility(View widget)
{
widget.Visibility = widget.Visibility + 1;
}
private void IncludeClick(View widget)
{
widget.Click += (s,e) => {};
}
private void IncludeRelativeLayout(RelativeLayout relativeLayout)
{
relativeLayout.Click += (s, e) => { };
}
public void Include(INotifyCollectionChanged changed)
{
changed.CollectionChanged += (s,e) => { var test = string.Format("{0}{1}{2}{3}{4}", e.Action,e.NewItems, e.NewStartingIndex, e.OldItems, e.OldStartingIndex); } ;
}
}

 More info here:
http://stackoverflow.com/questions/16924178/issues-with-mvvmcross-and-linking-on-android/16924320?noredirect=1#comment24433662_16924320
http://stackoverflow.com/questions/11349864/mvvmcross-monotouch-fail-to-bind-properties-on-a-real-ipad-but-it-works-on-th (including the info and links from comments)
http://spouliot.wordpress.com/2011/08/11/when-to-link-monotouch-applications/

Note there are other options, in the same Build tab: Use shared Mono runtime and Fast assembly deployment. These are not meant to be used on Release (if you have over the options, the explanation is pretty good and you should get a good idea of how they work).



MvvmCross Android app with dynamic fragments

It’s not much different than implementing the app with Java, except using the MvvmCross MvxXXXX classes.
Let’s do a simple exercise: have an activity loading a fragment by code behind.
Here’s the code we need:

1. a MvxFragmentActivity derived class.  It is the corresponding to Android’s FragmentActivity class

[Activity(Label = "View for FirstViewModel")]
public class FirstView : MvxFragmentActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.FirstView);
this.AddChildView ();
}
void AddChildView()
{
var childView = new ChildView () {
ViewModel = new ChildViewModel()
};
var fm = this.SupportFragmentManager;
var ft = fm.BeginTransaction ();
ft.Add (Resource.Id.childViewHost, childView, "childView");
ft.Commit ();
}


2. a corresponding Android layout for it: FirstView.axml
  it needs to have a host widget for the fragment, let’s say a FrameLayout called childViewHost
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/childViewHost" />
</FrameLayout >

 
  3. a MvxFragment derived class. Note the MvvmCross BindingInflate method which makes binding work in the fragment
public class ChildView : MvxFragment
{
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var ignored = base.OnCreateView(inflater, container, savedInstanceState);
return this.BindingInflate(Resource.Layout.ChildView, null);
}
}
4. a corresponding Android layout  for it: ChildView.axml. Let’s have a textbox bound to the ViewModel’s property
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<TextView
local:MvxBind="Text Hello"
android:textAppearance="?android:attr/textAppearanceSmall"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/textView2" />
</LinearLayout>



Friday, May 24, 2013

ActionBarSherlock in Xamarin Android targeting Android 2.1

ActionBarSherlock is a library which is an extension of the ActionBar in Android. ActionBar appeared in Android 4.

Besides being an extension, this library works for version previous to Android 4, starting from Android 2.1

 

First, we need to build the ActionBarSherlock from scratch using Eclipse. (I had also to install ‘Android SDK Tools’ using the Android SDK Manger).

Second, we need to create a Xamarin Java Binding Library, which will create a bridge library for Xamarin based on the ActionBarSherlock Android library.

For these two steps, follow instructions from http://www.craigsprogramming.com/2012/07/actionbarsherlock-with-mono-for-android.html

To test the app, in the app’s Activit1, just use the sample  code also posted there (use the code from TabActivity class).

 

In order to target Android 2.1:

1. Change properties of the ActionBarSherlockBindings project to have Android minimum version 2.1

2. For the app, also change properties to have Android minimum version 2.1 (in Visual Studio, right click on project, Properties and from the dialog, it’s in the Application tab, ‘Minimum Android to target’)

3. On the app, we need to change it to target Android 4. This is specified in the AndroidManifest.xml file of the app

If it does not exist, in Visual Studio, go to the app properties, and click on ‘Android Manifest’ Tab and click to generate the file.

Once done, UI appears with options for the manifest,  set ‘Target API level’ to 14.

 

Also,  once I targeted Android 2.1, I had to make few changes in the sample code for it to work.

Some classes need to be replaced with classes from the Android.Support.V4.App (like Fragment) and a constant (ActionBar.NavigationModeTabs instead of ActionBar_Sherlock.ActionBarSherlock.ActionBarNavigationMode.Tabs)

Now the app can be tested on an Android 2.1 device or emulator.

Wednesday, May 22, 2013

First app with Xamarin Android and MVVMCross – gotchas

1. After installing Xamarin, create a new ‘Visual C# / Android / Android Application’ using Visual Studio, say ‘DemoApp.Android’ but have the solution called ‘DemoApp’.

2. Add an ‘Visual C# / Windows / Portable Class Library’ called DemoApp.Core.
   First select ‘Windows Phone 7.5 and later’ and then ‘Mono Android’ and ‘MonoTouch’. Note that Xamarin frameworks become available only if you select ‘Windows Phone 7.5 and later’

3. Make sure you have the latest NuGet installed. For this, in Visual Studio, go to Help \ About Microsoft Visual Studio.
image

4. Using NuGet, search for ‘mvvmcross’ and add ‘MVVMCross Hot Tuna Starter Pack’ to BOTH the DemoApp.Android and DemoApp.Core
In the DemoApp.Android, it creates a SplashScreen activity and layout, and a layout and a view in FirstView.axml and FirstView.cs respectively.
In the DemoApp.Core, it creates a FirstViewModel view model.

6. In DemoApp.Android, delete the Activity1.cs and Resources/Layout/Main.axml.

7. Run. It should run OK at this point.