Reusable Controls in Xamarin.Android

Nathan Sokalski 4,111 Reputation points
2021-03-01T00:21:02.64+00:00

I'm not quite sure how or where to ask this, so I'll just do it. I am in the process of converting my apps from UWP to Xamarin.Android. I am using Xamarin.Android rather than Xamarin.Forms because Xamarin.Forms has seemed to require me to do so much stuff in the native part of the code (the Xamarin.Android project) to get what I need, I figured it would be more efficient to write it completely in Xamarin.Android (since I have no intention of making an iOS version). This is my first time using any variation of Xamarin or Android, and one of the things I need to figure out how to do that seems very different from UWP (which is where all my experience is) is creating custom or external controls. In UWP I would inherit from another control (Button, TextBlock, UserControl, etc.) & create the accompanying xaml file, or use a ControlTemplate. I'm not sure how to do the equivelant of inheriting from a control in Android, or what the equivalent of a ControlTemplate is in Android. Is there anywhere that has a good tutorial on creating reusable custom controls in Xamarin.Android? Thanks.

Developer technologies .NET Xamarin
0 comments No comments
{count} votes

Accepted answer
  1. Anonymous
    2021-03-01T06:04:12.9+00:00

    Hello,​

    Welcome to our Microsoft Q&A platform!

    In UWP I would inherit from another control (Button, TextBlock, UserControl, etc.) & create the accompanying xaml file

    Xamarin.Android have this way to create a custom control. For example. We want to create a custom TextView.

       public class MyTextView : TextView  
           {  
               protected MyTextView(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)  
               {  
               }  
         
               public MyTextView(Context context) : base(context)  
               {  
                   Initialize(context);  
               }  
               private void Initialize(Context context, IAttributeSet attrs = null)  
               {  
                  if (attrs != null)  
                   {  
                       TypedArray ta = context.ObtainStyledAttributes(attrs, Resource.Styleable.test);  
                       string text = ta.GetString(Resource.Styleable.test_text);  
                       int textAttr = ta.GetInt(Resource.Styleable.test_testAttr, 0);  
                       // Log.e(TAG, "text = " + text + " , textAttr = " + textAttr);  
                       ta.Recycle();  
                   }  
               }  
                   public MyTextView(Context context, IAttributeSet attrs) : base(context, attrs)  
               {  
                   Initialize(context, attrs);  
               }  
         
               public MyTextView(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)  
               {  
                   Initialize(context, attrs);  
               }  
         
               public MyTextView(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes)  
               {  
                   Initialize(context, attrs);  
               }  
                protected override void OnDraw(Canvas canvas)  
               {  
                   base.OnDraw(canvas);  
               }  
         
          }  
       }  
    

    Then we can add properties like following code in the attrs.xml

       <?xml version="1.0" encoding="utf-8" ?>  
       <resources>  
         <declare-styleable name="test">  
           <attr name="text" format="string" />  
           <attr name="testAttr" format="integer" />  
         </declare-styleable>  
       </resources>  
    

    we can reusable in the layout, just with custom control's name.

       <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
           xmlns:app="http://schemas.android.com/apk/res-auto"  
             
           xmlns:tools="http://schemas.android.com/tools"  
           android:layout_width="match_parent"  
           android:layout_height="match_parent">  
         
            <App55.MyTextView  
              android:layout_width="200dp"  
              android:layout_height="200dp"  
              app:testAttr="520"  
              app:text="helloworld"   
           />  
         
       </RelativeLayout>  
    

    If you want to create custom control in Xamarin.Android, just read native android's article, there are similar.

    https://developer.android.com/guide/topics/ui/custom-components

    If you want to know more details about Xamarin.Android's custom control or view, you can google: Creating an Android Custom View in Xamarin

    ===============
    Update================

    Is there any tutorial or documentation on learn.microsoft.com for this with slightly more detail? I was also slightly confused about attrs.xml and where to put it. Thanks again, hopefully it will get me started!

    No, I did not find these articles. I read Google's Android article to create the custom-control in Xamarin Android. For attrs.xml, you can create an XML file in values folder, change the name of attrs.xml, please note his properties like following screenshot.

    73185-image.png

    Best Regards,

    Leon Lu


    If the response is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    1 person found this answer helpful.

1 additional answer

Sort by: Most helpful
  1. Anonymous
    2021-03-02T09:50:12.273+00:00

    So the way to (sort of) add "properties" is to create the "attrs.xml" file, and then obtain them using the "ObtainStyledAttributes" method?

    Yes

    The "test" part of "Resource.Styleable.test" comes from the "name="test"" in the "declare-styleable" element?

    Yes, Firstly, we add "properties" is to create the "attrs.xml" file, So we can use these properties in the xml layout. For example, app:testAttr="" app:text=""

    <App55.MyTextView
           android:layout_width="200dp"
           android:layout_height="200dp"
           app:testAttr="520"
           app:text="helloworld" 
        />
    

    After setting values to these properties, how can we get it in the custom-control’s background code? So we use ObtainStyledAttributes method to read "attrs.xml" file, get the value from xml's layout by string text = ta.GetString(Resource.Styleable.test_text);, If you add breakpoint, you will found the value of text is helloworld

    what is the purpose of the Recycle() method?

    Performance optimization, Recycles the TypedArray, to be re-used by a later caller. For example, if you used custom control, you need to create a new array, it will cost lots of system resource.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.