How do I use calligraphy to apply a custom font to TabLayout from design support library please?
I have gotten it to work in java which most of the answers seem to refer to. (e.g. Change the font of tab text in android design support TabLayout )
I'd prefer not to make a custom class, I'd like to just use Calligraphy. (https://github.com/chrisjenx/Calligraphy )
Thanks
I used the approach of extend the TabLayout. In this way you can simply define the fontPath in the TabLayout;
<com.mypackage.base.widget.FontAwareTabLayout
android:id="@+id/tab_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
fontPath="@string/common_fonts_sans_condensed_bold"
/>
Here the class code:
/**
* Simple helper class which extends a TabLayout to allow us to customize the font of the tab.
* https://gist.github.com/tmtrademarked/09926077a406959be15fc8a824a52751
* https://github.com/chrisjenx/Calligraphy/issues/180
*/
public final class FontAwareTabLayout extends TabLayout {
private String fontPath;
public FontAwareTabLayout(Context context, AttributeSet attrs) {
super(context, attrs);
fontPath = pullFontPathFromView(context, attrs, new int[] { R.attr.fontPath });
}
/**
* Tries to pull the Custom Attribute directly from the TextView.
*
* @param context Activity Context
* @param attrs View Attributes
* @param attributeId if -1 returns null.
* @return null if attribute is not defined or added to View
*/
static String pullFontPathFromView(Context context, AttributeSet attrs, int[] attributeId) {
if (attributeId == null || attrs == null) return null;
final String attributeName;
try {
attributeName = context.getResources().getResourceEntryName(attributeId[0]);
} catch (Resources.NotFoundException e) {
// invalid attribute ID
return null;
}
final int stringResourceId = attrs.getAttributeResourceValue(null, attributeName, -1);
return stringResourceId > 0 ? context.getString(stringResourceId)
: attrs.getAttributeValue(null, attributeName);
}
@Override
public void addTab(@NonNull Tab tab, int position, boolean setSelected) {
super.addTab(tab, position, setSelected);
ViewGroup mainView = (ViewGroup) getChildAt(0);
ViewGroup tabView = (ViewGroup) mainView.getChildAt(tab.getPosition());
int tabChildCount = tabView.getChildCount();
for (int i = 0; i < tabChildCount; i++) {
View tabViewChild = tabView.getChildAt(i);
if (tabViewChild instanceof TextView) {
CalligraphyUtils.applyFontToTextView(getContext(), (TextView) tabViewChild, fontPath);
}
}
}
}
There is a way to use custom font in xml for TabLayout, but it's a little bit hacky. You have to provide your own custom layout for Tabs and in that layout you can style your TextViews whatever you like.
So basically you need to have this setup:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Get the ViewPager and set it's PagerAdapter so that it can display items
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
SampleFragmentPagerAdapter pagerAdapter =
new SampleFragmentPagerAdapter(getSupportFragmentManager(), MainActivity.this);
viewPager.setAdapter(pagerAdapter);
// Give the TabLayout the ViewPager
TabLayout tabLayout = (TabLayout) findViewById(R.id.sliding_tabs);
tabLayout.setupWithViewPager(viewPager);
// Iterate over all tabs and set the custom view
for (int i = 0; i < tabLayout.getTabCount(); i++) {
TabLayout.Tab tab = tabLayout.getTabAt(i);
tab.setCustomView(pagerAdapter.getTabView(i));
}
}
//...
}
And then the PagerAdapter:
public class SampleFragmentPagerAdapter extends FragmentPagerAdapter {
private Context context;
private String tabTitles[] = new String[] { "Tab1", "Tab2" };
// ...
public View getTabView(int position) {
// Given you have a custom layout in `res/layout/custom_tab.xml` with a TextView
View v = LayoutInflater.from(context).inflate(R.layout.custom_tab, null);
TextView tv = (TextView) v.findViewById(R.id.textView);
tv.setText(tabTitles[position]);
return v;
}
}
This is custom_tab.xml:
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="match_parent"
fontPath="fonts/CustomFont.otf"
tools:ignore="MissingPrefix" />
Some things are missing in the code, but I think you can fill in the missing parts, this is just a gist of it. This is just a segment of the blog post in the references with the added addition of Calligraphy. You can take a look at it for more details.
References:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With