nAndroid
nAndroid

Reputation: 980

How do you use Calligraphy with TabLayout in Android Design Support Library for custom Font in xml?

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

Upvotes: 5

Views: 3599

Answers (6)

Kourosh
Kourosh

Reputation: 2299

If you used FragmentPagerAdapter, You can use Spannable in getPageTitle for example:

override fun getPageTitle(position: Int): CharSequence? {
        val sBuilder = SpannableStringBuilder()
        when(position){
            0->    sBuilder.append("First Tab")
            1->    sBuilder.append("Second Tab")
            else-> sBuilder.append("Third Tab")
        }
        CalligraphyTypefaceSpan(TypefaceUtils.load(getAssets(), "fonts/Roboto-Bold.ttf"))
        return sBuilder
}

Upvotes: 0

Sabeeh
Sabeeh

Reputation: 1297

Hi i think this is easy and best way to do it with calligraphy library. Calligraphy Github

fontName is font name in assets like "fonts/cocon_next_font.ttf".

public static void changeTabsFont(TabLayout tabLayout, String fontName) {

        ViewGroup vg = (ViewGroup) tabLayout.getChildAt(0);
        int tabsCount = vg.getChildCount();
        for (int j = 0; j < tabsCount; j++) {
            ViewGroup vgTab = (ViewGroup) vg.getChildAt(j);
            int tabChildsCount = vgTab.getChildCount();
            for (int i = 0; i < tabChildsCount; i++) {
                View tabViewChild = vgTab.getChildAt(i);
                if (tabViewChild instanceof TextView) {
                    CalligraphyUtils.applyFontToTextView(tabLayout.getContext(), (TextView) tabViewChild, fontName);
                }
            }
        }
    }

Upvotes: 3

nAndroid
nAndroid

Reputation: 980

Updated:

See (for now) https://developer.android.com/preview/features/working-with-fonts.html Android O lets you bundle fonts as resources by adding the font file in the res/font/ folder. These fonts are compiled in your R file and are automatically available in Android Studio. You can access the font resources with the help of a new resource type, font. For example, to access a font resource, use @font/myfont, or R.font.myfont.

To add fonts as resources, perform the following steps in the Android Studio:

  1. Right-click the res folder and go to New > Android resource directory. The New Resource Directory window appears.
  2. In the Resource type list, select font, and then click OK. Note: The name of the resource directory must be font.

  3. Add your font files in the font folder. The folder structure below generates R.font.dancing_script, R.font.lobster, and R.font.typo_graphica. Adding the font files in the resource directory

  4. Double-click a font file to preview the file's fonts in the editor.

Create Font family

New-Font-resource file, file like

<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
    <font
        android:fontStyle="normal"
        android:fontWeight="400"
        android:font="@font/lobster_regular" />
    <font
        android:fontStyle="italic"
        android:fontWeight="400"
        android:font="@font/lobster_italic" />
</font-family>

-- then textiview like so

 <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fontFamily="@font/lobster"/>

Upvotes: 1

Luigi Papino
Luigi Papino

Reputation: 408

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);
      }
    }
  }
}

Upvotes: 9

Gozdera Patryk
Gozdera Patryk

Reputation: 11

You can define style for android.support.design.widget.TabLayout and then write your own style for text appearance such like this:

<style name="TextAppearance.FontPath" parent="android:TextAppearance">
<item name="fontPath">fonts/Roboto-Light.ttf</item>

then you have to add item:

<item name="tabTextAppearance">@style/TextAppearance.FontPath</item>

to your style of android.support.design.widget.TabLayout. It should work.

Upvotes: 1

JKMirko
JKMirko

Reputation: 161

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:

Upvotes: 4

Related Questions