Yet Another [à compléter]

Random thoughts of Jérémie Laval

MfA Tricks #3 - InsetTextView

Inset is a pretty useful effect especially on text. Since your letters seems incrustated in the screen, the text is less prominent than a normal one making it perfect for secondary UI elements.

I personally use it on a text indicating how to use a row of sensitive elements just above:

The code of the view is given 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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
using Android.Graphics;

namespace Foo
{
  public class InsetTextView : View
  {
      const int DefaultFontSize = 35;
      const float Offset = 1;

      string text;
      Paint textPaint;
      Paint lightPaint;
      Paint darkPaint;

      public InsetTextView (Context context) : base (context)
      {
          Initialize ();
      }

      public InsetTextView (Context context, IAttributeSet attrs) :
          base (context, attrs)
      {
          text = attrs.GetAttributeValue (null, "text");
          Initialize ();
      }

      public InsetTextView (Context context, IAttributeSet attrs, int defStyle) :
          base (context, attrs, defStyle)
      {
          text = attrs.GetAttributeValue (null, "text");
          Initialize ();
      }

      private void Initialize ()
      {
          textPaint = new Paint () {
              Color = Color.Rgb (0xe9, 0xe9, 0xe9),
              AntiAlias = true,
              TextAlign = Paint.Align.Center,
              TextSize = DefaultFontSize
          };
          textPaint.SetTypeface (Typeface.DefaultBold);
          lightPaint = new Paint () {
              Color = Color.Argb (0xfa, 0xff, 0xff, 0xff),
              AntiAlias = true,
              TextAlign = Paint.Align.Center,
              TextSize = DefaultFontSize
          };
          lightPaint.SetTypeface (Typeface.DefaultBold);
          darkPaint = new Paint () {
              Color = Color.Argb (0x30, 0, 0, 0),
              AntiAlias = true,
              TextAlign = Paint.Align.Center,
              TextSize = DefaultFontSize
          };
          darkPaint.SetTypeface (Typeface.DefaultBold);
      }

      public string Text {
          get {
              return text;
          }
          set {
              text = value ?? string.Empty;
              Invalidate ();
          }
      }

      public Color TextColor {
          get {
              return textPaint.Color;
          }
          set {
              textPaint.Color = value;
              Invalidate ();
          }
      }

      protected override void OnMeasure (int widthMeasureSpec, int heightMeasureSpec)
      {
          var width = (int)Math.Ceiling (textPaint.MeasureText (text)) + 2;
          var metrics = textPaint.GetFontMetricsInt ();
          var height = -metrics.Top + metrics.Bottom + 2;

          SetMeasuredDimension (width, height);
      }

      protected override void OnDraw (Canvas canvas)
      {
          var hCenter = canvas.Width / 2;
          var vCenter = canvas.Height - (textPaint.GetFontMetricsInt ().Bottom + 1);

          canvas.DrawText (text, hCenter - Offset, vCenter - Offset, darkPaint);
          canvas.DrawText (text, hCenter + Offset, vCenter + Offset, lightPaint);
          canvas.DrawText (text, hCenter, vCenter, textPaint);
      }
  }
}

A “real” inset effect implies inner glow and proper shading, here we are simplifying things by using solid colors in a shading palette and layering 3 times the text using it.

You can use InsetTextView in XML or in code, an example snippet in XML would be:

1
2
3
4
5
6
<Foo.InsetTextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_marginTop="16dp"
    text="Hey Oh" />

Comments