Shanu Habi Shanu Habi - 1 month ago 10
Android Question

Custom font not working after updating appcompat library to 23.4.0.1

I have been using a custom font for all the views in my application. But currently the font is getting applied only for the toolbar while the rest of the views uses the default font. This occured in side effect toa appcompat lib update to version 23.4.0.1. Has any one experienced this issue. Please find below the font usage classes

FontUtility.cs

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.Views;
using Android.Widget;
using Android.Graphics;

namespace HPScanJA.Android.Utils
{
class FontUtility
{
public static Typeface applyRegularFont(Context context)
{

Typeface hpRegularTypeface = Typeface.CreateFromAsset(context.Assets, "fonts/Simplified_Rg.ttf");
return hpRegularTypeface;
}

public static Typeface applyBoldFont(Context context)
{

Typeface hpBoldTypeface = Typeface.CreateFromAsset(context.Assets, "fonts/Simplified_Bd.ttf");
return hpBoldTypeface;
}
}
}


also the usage is in the base activity shown below. This gets extended by all the activities

BaseActivity.cs

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.Views;
using Android.Widget;
using Android.Graphics;
using HPScanJA.Android.Utils;
using Android.Support.V7.App;

namespace HPScanJA.Android.Activities
{
[Activity(Label = "BaseActivity")]
public class BaseActivity : AppCompatActivity
{
Context context;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
context = this;
// Get the Resources object from our context
global::Android.Content.Res.Resources res = context.Resources;

// Create your application here
int titleId = res.GetIdentifier("action_bar_title", "id",
"android");
TextView titleView = (TextView)FindViewById(titleId);
if (titleView != null)
titleView.SetTypeface(FontUtility.applyRegularFont(context), TypefaceStyle.Normal);
}

public override View OnCreateView(string name, Context context, global::Android.Util.IAttributeSet attrs)
{
View view = base.OnCreateView(name, context, attrs);
return setCustomTypeFaceIfNeeded(name, attrs, view);
}


protected View setCustomTypeFaceIfNeeded(String name, global::Android.Util.IAttributeSet attrs, View view)
{
View result = null;
Console.WriteLine("*******************************************"+name+"*******************************************");
if ("TextView".Equals(name))
{
result = new TextView(this, attrs);

if (null != ((TextView)result).Typeface && TypefaceStyle.Bold == ((TextView)result).Typeface.Style)
{
((TextView)result).SetTypeface(FontUtility.applyBoldFont(context), TypefaceStyle.Normal);
}
else
{
((TextView)result).SetTypeface(FontUtility.applyRegularFont(context), TypefaceStyle.Normal);
}


}

else if ("EditText".Equals(name))
{
result = new EditText(this, attrs);
if (null != ((EditText)result).Typeface && TypefaceStyle.Bold == ((EditText)result).Typeface.Style)
{
((EditText)result).SetTypeface(FontUtility.applyBoldFont(context), TypefaceStyle.Normal);
}
else
{
((EditText)result).SetTypeface(FontUtility.applyRegularFont(context), TypefaceStyle.Normal);
}

}

else if ("Button".Equals(name))
{
result = new Button(this, attrs);
if (null != ((Button)result).Typeface && TypefaceStyle.Bold == ((Button)result).Typeface.Style)
{
((Button)result).SetTypeface(FontUtility.applyBoldFont(context), TypefaceStyle.Normal);
}
else
{
((Button)result).SetTypeface(FontUtility.applyRegularFont(context), TypefaceStyle.Normal);
}

}

else if ("CheckedTextView".Equals(name))
{
result = new CheckedTextView(this, attrs);
if (null != ((CheckedTextView)result).Typeface && TypefaceStyle.Bold == ((CheckedTextView)result).Typeface.Style)
{
((CheckedTextView)result).SetTypeface(FontUtility.applyBoldFont(context), TypefaceStyle.Normal);
}
else
{
((CheckedTextView)result).SetTypeface(FontUtility.applyRegularFont(context), TypefaceStyle.Normal);
}

}

else if ("CheckBox".Equals(name))
{
result = new CheckBox(this, attrs);
if (null != ((CheckBox)result).Typeface && TypefaceStyle.Bold == ((CheckBox)result).Typeface.Style)
{
((CheckBox)result).SetTypeface(FontUtility.applyBoldFont(context), TypefaceStyle.Normal);
}
else
{
((CheckBox)result).SetTypeface(FontUtility.applyRegularFont(context), TypefaceStyle.Normal);
}

}
else if ("RadioButton".Equals(name))
{
result = new RadioButton(this, attrs);
if (null != ((RadioButton)result).Typeface && TypefaceStyle.Bold == ((RadioButton)result).Typeface.Style)
{
((RadioButton)result).SetTypeface(FontUtility.applyBoldFont(context), TypefaceStyle.Normal);
}
else
{
((RadioButton)result).SetTypeface(FontUtility.applyRegularFont(context), TypefaceStyle.Normal);
}

}
else if ("Switch".Equals(name))
{
result = new Switch(this, attrs);
if (null != ((Switch)result).Typeface && TypefaceStyle.Bold == ((Switch)result).Typeface.Style)
{
((Switch)result).SetTypeface(FontUtility.applyBoldFont(context), TypefaceStyle.Normal);
}
else
{
((Switch)result).SetTypeface(FontUtility.applyRegularFont(context), TypefaceStyle.Normal);
}

}




if (result == null)
{
return view;
}
else
{
return result;
}
}


}
}


Kindly let me know if anyone faced this issue.

Answer

After a long while finally I solved this... This issue was occurring as the BaseActivity class is trying to change the font during run time. Prior to support library v23 this was working fine. But from support lib v23 onward the system was changing certain view types during run time and hence this piece of code was not working.

I solved this by going with a different approach that is to extend each UI View class and set the typeface within it For eg. the Textviews code is given below

 public class CustomTextView : TextView
{
    public CustomTextView(Context context) : base(context)
    {
        SetCustomTypeFace();
    }
    public CustomTextView(Context context, IAttributeSet attrs) : base(context, attrs)
    {

        SetCustomTypeFace();

    }
    public CustomTextView(Context context, IAttributeSet attrs, int defStyleAttr) : base(context, attrs, defStyleAttr)
    {
        SetCustomTypeFace();
    }
    public CustomTextView(Context context, IAttributeSet attrs, int defStyleAttr, int defStyleRes) : base(context, attrs, defStyleAttr, defStyleRes)
    {
        SetCustomTypeFace();

    }

    public void SetCustomTypeFace()
    {
        Typeface tf = null;
        if (this.Typeface.Style == TypefaceStyle.Normal)
        {
            tf = Typeface.CreateFromAsset(Application.Context.Assets, "fonts/Simplified_Rg.ttf");
        }
        else if (this.Typeface.Style == TypefaceStyle.Bold)
        {
            tf = Typeface.CreateFromAsset(Application.Context.Assets, "fonts/Simplified_Bd.ttf");

        }
        SetTypeface(tf, this.Typeface.Style);
    }

}

Then I used this custom textview in the layout instead of the default TextView.

Comments