Know the different coding style between native Android and Xamarin.Android through one project

I made a mistake / misunderstanding when writing the previous blog: Xamarin.Android vs. Native Android - How you implement Java Listener in C#, which is about how to transfer Java code to C# coding when doing Xamarin.Android project. (Means that sometimes you will have to implement some code in C# by refering to some code from native Android sample which is written in Java.)

I will keep that blog because it’s still correct but not the best practice as I can think of for now. So you can think of this as a better one.

Background

Recently I am reading a pdf which is from Microsoft official site for Xamarin.Android development. I read about the Downloadable Fonts which has more benefits than you packaged the font into the apk file.

For detail information about Downloadable Fonts, check here: Downloadable Fonts.

In the above link, you will see there is a sample from Google that demonstrate how this works.

Here is the link: android-DownloadableFonts

But I am learning Xamarin.Android so I thought maybe I can try to implement it with a Xamarin.Android version. (Usually I will use Xamarin.Forms for developing Xamarin app.)

Then the nightmare happened, I found it really hard to implement the code just by reading the Java code from Google’s sample, even C# and Java are quite similar.

The good thing is that I suddenly found that Xamarin team has done a sample for Xamarin.Android also, it’s exactly the same as Google’s sample. Which means that someone has done the same thing as I want to.

Here is the link: Xamarin.Android DownloadableFonts Sample

I checked the code and it’s quite good and elegant.

So, what you will see in this blog is that I am gonna use these 2 sample projects to get through some important points and practice that how you can do Xamarin.Android development if you need to refer to a native Android project.

What I got by comparing these 2 samples?

There will never be correct answers on how you implement your code. Every language has its own features and specialty, so no one can say that you can only achive the goal by writing the code like this. But as I said, I found the Xamarin.Android version of the Downloadable Fonts is really good when author is trying to implement the same in C#.

What I can think of to share here are:

  • UI
  • Fields in Java vs. Properties in C#
  • Listener in Java vs. Event Handler in C#

Prerequisition

If you are going to implement a same project as some other native Android project, the first and the only thing you have to do in Xamarin.Android is to make sure that you have included / added all the needed dependencies such as V7 / V4 support libraries, etc.

UI

If you check on both projects, you will find in UI, there is nothing you need to worry.

The only thing to do is to copy and paste the UI code even file from the native Android project because Xamarin.Android also uses these libraries for UI, especially the AppCompat UI elements from V7 or V4 support library.

I got some issue at first with the Theme because the UI is based on AppCompat, I have to modify the Theme to be compatible with AppCompat UI controls. I plan to write another blog to show this point. Will not cover too much here.

Fields in Java vs. Properties in C

There is a big improvements in C# than Java is the Property concept. You can never avoid using Fields in your programming, so knowing the difference of this between Java and C# is really important.

For example, if you declare a field in Java, then each time you want to modify the value of that field, you have to call setXXXX() method to that object.

On the other hand, C# always implement the same as Properties.

Check below Java code:

1
2
3
4
5
6
7
8
public class Person
{
private String name;
public void setName(String name)
{
this.name = name;
}
}

Then you will modify the value like this:

1
2
Person p = new Person();
p.setName("Allen");

But in C#, you will do like this:

1
2
3
4
public class Person
{
public string Name {get;set;}
}

Then you do like this:

1
2
Person p = new Person();
p.Name = "Allen";

This is a very useful pattern when you are transferring Java to C#.

Listener in Java vs. Event Handler in C

It’s a very common thing that in one Activity’s UI page, there will be multiple same controls such as SeekBar, TextView, etc.

In this Downloadable Fonts project, tehre are 3 SeekBar with the same behavior: when you move the point, the value of the text behind it should change accordingly.

See screenshot as below:

In Java code, you will do as below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
mWidthSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
widthTextView
.setText(String.valueOf(progressToWidth(progress)));
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});

mWeightSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
weightTextView
.setText(String.valueOf(progressToWeight(progress)));
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});

mItalicSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromuser) {
italicTextView
.setText(String.valueOf(progressToItalic(progress)));
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});

Of course you can check my previous blog as a solution for this. However, here I will introduce a much better solution as below:

  1. Create an Inner class within the MainActivity class named SeekBarListenerImpl. The reason for creating an Inner class is that this Listener is used for this Activity’s 3 SeekBar. So there is no chance to re-use it. And it will only exist if this Activity is instantated.

    The code is as below:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    class SeekBarListenerImpl: Object, SeekBar.IOnSeekBarChangeListener
    {
    public enum SeekBarType
    {
    WIDTH, WEIGHT, ITALIC
    }

    public SeekBarType mSeekBarType { get; set; }
    public TextView mTextView { get; set; }
    public MainActivity mActivity { get; set; }

    public void OnProgressChanged(SeekBar seekBar, int progress, bool fromUser)
    {
    var progressText = "";
    switch (mSeekBarType)
    {
    case SeekBarType.WIDTH:
    progressText = String.ValueOf(mActivity.ProgressToWidth(progress));
    break;
    case SeekBarType.WEIGHT:
    progressText = String.ValueOf(mActivity.ProgressToWeight(progress));
    break;
    case SeekBarType.ITALIC:
    progressText = String.ValueOf(mActivity.ProgressToItalic(progress));
    break;
    }
    mTextView.Text = progressText;
    }

    public void OnStartTrackingTouch(SeekBar seekBar)
    {
    // No Op
    }
    public void OnStopTrackingTouch(SeekBar seekBar)
    {
    // No Op
    }
    }

We can see from this class, we already implement 3 different usage of the SeekBar. So we have done all the implementations for 3 SeekBars already. But how should we use it?

  1. We can use this implementation as below:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    var widthSeekBarListener = new SeekBarListenerImpl
    {
    mActivity = this,
    mTextView = widthTextView,
    mSeekBarType = SeekBarListenerImpl.SeekBarType.WIDTH
    };
    WidthSeekBar.SetOnSeekBarChangeListener(widthSeekBarListener);

    var weightSeekBarListener = new SeekBarListenerImpl
    {
    mActivity = this,
    mTextView = widthTextView,
    mSeekBarType = SeekBarListenerImpl.SeekBarType.WEIGHT
    };
    WidthSeekBar.SetOnSeekBarChangeListener(weightSeekBarListener);

    var italicSeekBarListener = new SeekBarListenerImpl
    {
    mActivity = this,
    mTextView = widthTextView,
    mSeekBarType = SeekBarListenerImpl.SeekBarType.ITALIC
    };
    WidthSeekBar.SetOnSeekBarChangeListener(italicSeekBarListener);

We can see it’s much easier than my previous blog and much shorter code.

Additional point

I’d like to mention one more scenario that we need to use Internal class. In this Downloadable Fonts sample, to call the download font API, we have to make the class inherit from FontsContractCompat.FontRequestCallBack and override 2 methods within that base class.

However, if we are going to do it in MainAcitivity, this Acitivity class has already inherited AppCompatAcitivity. Then it will not be possible to inherit from other classes.

So in the Xamarin sample, the author used Inner class to resolve the issue.

But in the Xamarin.Android official document, it implements a new class called FontDownloadHelper to make that class inherit from FontsContractCompat.FontRequestCallBack.

Both will work depends on your real development scenario. In the Helper class, it’s more common to use but lack of the possiblity to change or fit the usage for all Activities. However, inner class can meet all the needs that this Activity need to implement.

That’s all, thanks for reading!

Xamarin.Android vs. Native Android - How you implement Java Listener in C#
You need to set install_url to use ShareThis. Please set it in _config.yml.

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×