{"id":3265,"date":"2012-12-23T07:07:46","date_gmt":"2012-12-23T12:07:46","guid":{"rendered":"http:\/\/blog.xamarin.com\/?p=3265"},"modified":"2012-12-23T07:07:46","modified_gmt":"2012-12-23T12:07:46","slug":"android-tricks-insettextview","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/android-tricks-insettextview\/","title":{"rendered":"Android Tricks: InsetTextView"},"content":{"rendered":"<p>Inset styling is a useful effect, especially on text. It is well-suited for secondary UI elements, because it makes them appear less prominent. In one of my own applications, I recently used inset text to improve the discoverability of a particular feature&mdash;informing the user that they can drag nearby user interface elements:<\/p>\n<p><a href=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/drag-us.png\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/sites\/44\/2019\/04\/drag-us.png\" alt=\"drag-us\" width=\"151\" height=\"50\" class=\"aligncenter size-full wp-image-3332\" \/><\/a><\/p>\n<p>The following is the code that I used to implement the inset text style:<\/p>\n<pre class=\"lang:csharp decode:true\">\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\n\nusing Android.App;\nusing Android.Content;\nusing Android.OS;\nusing Android.Runtime;\nusing Android.Util;\nusing Android.Views;\nusing Android.Widget;\nusing Android.Graphics;\n\nnamespace Foo\n{\n\tpublic class InsetTextView : View\n\t{\n\t\tconst int DefaultFontSize = 35;\n\t\tconst float Offset = 1;\n\n\t\tstring text;\n\t\tPaint textPaint;\n\t\tPaint lightPaint;\n\t\tPaint darkPaint;\n\n\t\tpublic InsetTextView (Context context) : base (context)\n\t\t{\n\t\t\tInitialize ();\n\t\t}\n\n\t\tpublic InsetTextView (Context context, IAttributeSet attrs) :\n\t\t\tbase (context, attrs)\n\t\t{\n\t\t\ttext = attrs.GetAttributeValue (null, &quot;text&quot;);\n\t\t\tInitialize ();\n\t\t}\n\n\t\tpublic InsetTextView (Context context, IAttributeSet attrs, int defStyle) :\n\t\t\tbase (context, attrs, defStyle)\n\t\t{\n\t\t\ttext = attrs.GetAttributeValue (null, &quot;text&quot;);\n\t\t\tInitialize ();\n\t\t}\n\n\t\tprivate void Initialize ()\n\t\t{\n\t\t\ttextPaint = new Paint () {\n\t\t\t\tColor = Color.Rgb (0xe9, 0xe9, 0xe9),\n\t\t\t\tAntiAlias = true,\n\t\t\t\tTextAlign = Paint.Align.Center,\n\t\t\t\tTextSize = DefaultFontSize\n\t\t\t};\n\t\t\ttextPaint.SetTypeface (Typeface.DefaultBold);\n\t\t\tlightPaint = new Paint () {\n\t\t\t\tColor = Color.Argb (0xfa, 0xff, 0xff, 0xff),\n\t\t\t\tAntiAlias = true,\n\t\t\t\tTextAlign = Paint.Align.Center,\n\t\t\t\tTextSize = DefaultFontSize\n\t\t\t};\n\t\t\tlightPaint.SetTypeface (Typeface.DefaultBold);\n\t\t\tdarkPaint = new Paint () {\n\t\t\t\tColor = Color.Argb (0x30, 0, 0, 0),\n\t\t\t\tAntiAlias = true,\n\t\t\t\tTextAlign = Paint.Align.Center,\n\t\t\t\tTextSize = DefaultFontSize\n\t\t\t};\n\t\t\tdarkPaint.SetTypeface (Typeface.DefaultBold);\n\t\t}\n\n\t\tpublic string Text {\n\t\t\tget {\n\t\t\t\treturn text;\n\t\t\t}\n\t\t\tset {\n\t\t\t\ttext = value ?? string.Empty;\n\t\t\t\tInvalidate ();\n\t\t\t}\n\t\t}\n\n\t\tpublic Color TextColor {\n\t\t\tget {\n\t\t\t\treturn textPaint.Color;\n\t\t\t}\n\t\t\tset {\n\t\t\t\ttextPaint.Color = value;\n\t\t\t\tInvalidate ();\n\t\t\t}\n\t\t}\n\n\t\tprotected override void OnMeasure (int widthMeasureSpec, int heightMeasureSpec)\n\t\t{\n\t\t\tvar width = (int)Math.Ceiling (textPaint.MeasureText (text)) + 2;\n\t\t\tvar metrics = textPaint.GetFontMetricsInt ();\n\t\t\tvar height = -metrics.Top + metrics.Bottom + 2;\n\n\t\t\tSetMeasuredDimension (width, height);\n\t\t}\n\n\t\tprotected override void OnDraw (Canvas canvas)\n\t\t{\n\t\t\tvar hCenter = canvas.Width \/ 2;\n\t\t\tvar vCenter = canvas.Height - (textPaint.GetFontMetricsInt ().Bottom + 1);\n\n\t\t\tcanvas.DrawText (text, hCenter - Offset, vCenter - Offset, darkPaint);\n\t\t\tcanvas.DrawText (text, hCenter + Offset, vCenter + Offset, lightPaint);\n\t\t\tcanvas.DrawText (text, hCenter, vCenter, textPaint);\n\t\t}\n\t}\n}\n<\/pre>\n<p>A &#8220;real&#8221; inset effect implies inner glow and proper shading, but I chose to use a simpler approach. I used solid colors in a shading palette and layered three instances of the text.<\/p>\n<p>You can use <code>InsetTextView<\/code> in XML or in code. The following XML snippet demonstrates how it can be used in an Android user interface layout:<\/p>\n<pre class=\"lang:xml decode:true\">\n&lt;Foo.InsetTextView\n    android:layout_width=&quot;wrap_content&quot;\n    android:layout_height=&quot;wrap_content&quot;\n    android:layout_gravity=&quot;center&quot;\n    android:layout_marginTop=&quot;16dp&quot;\n    text=&quot;Hey Oh&quot; \/&gt;\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Inset styling is a useful effect, especially on text. It is well-suited for secondary UI elements, because it makes them appear less prominent. In one of my own applications, I recently used inset text to improve the discoverability of a particular feature&mdash;informing the user that they can drag nearby user interface elements: The following is [&hellip;]<\/p>\n","protected":false},"author":1925,"featured_media":39167,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[5,4],"class_list":["post-3265","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-developers","tag-android","tag-xamarin-platform"],"acf":[],"blog_post_summary":"<p>Inset styling is a useful effect, especially on text. It is well-suited for secondary UI elements, because it makes them appear less prominent. In one of my own applications, I recently used inset text to improve the discoverability of a particular feature&mdash;informing the user that they can drag nearby user interface elements: The following is [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/3265","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/1925"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=3265"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/3265\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media\/39167"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=3265"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=3265"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=3265"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}