Calligraphy icon indicating copy to clipboard operation
Calligraphy copied to clipboard

Design Support Library support?

Open nealsanche opened this issue 9 years ago • 17 comments

I've noticed the fonts in the CollapsingToolbarLayout in particular, the Title attribute, isn't set. I've had to resort to something ugly like the following to get it to set the font on it:


public static void modifyCollapsingToolbarTextFont(Context context, CollapsingToolbarLayout collapsingToolbar) {
        // Hack so that the typeface is correct for the title and the title is centered
        try {
            // Get the mCollapsingTextHelper instance
            Field declaredField = collapsingToolbar.getClass().getDeclaredField("mCollapsingTextHelper");
            declaredField.setAccessible(true);
            Object collapsingTextHelper = declaredField.get(collapsingToolbar);

            // The get its mTextPaint field
            Field paintField = collapsingTextHelper.getClass().getDeclaredField("mTextPaint");
            paintField.setAccessible(true);
            TextPaint textPaint = (TextPaint) paintField.get(collapsingTextHelper);

            final Typeface tf = Typeface.createFromAsset(context.getAssets(), "fonts/FrutigerLTStd-Light.otf");
            textPaint.setTypeface(tf);

        } catch (Exception e) {
            Timber.e(e, "Unexpected error.");
        }
    }

I'd much rather have Calligraphy handle this for me in a nice, unseen, magical way as per usual. I was hoping that the following would just work:


    <style name="TextAppearance.Hero.Title" parent="TextAppearance.AppCompat.Title">
        <item name="fontPath">fonts/FrutigerLTStd_Light.ttf</item>
        <item name="android:textColor">@color/cpb_text_color_error</item>
        <item name="android:textSize">@dimen/hero_font_size</item>
        <item name="android:textStyle">normal</item>
    </style>

And then in the layout:

            <android.support.design.widget.CollapsingToolbarLayout
                android:id="@+id/collapsing_toolbar"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:fitsSystemWindows="true"
                app:title="Title"
                app:titleEnabled="true"
                app:contentScrim="@android:color/transparent"
                app:expandedTitleMarginBottom="85dp"
                app:expandedTitleGravity="center"
                app:expandedTitleTextAppearance="@style/TextAppearance.Hero.Title"
                app:layout_scrollFlags="scroll|exitUntilCollapsed"
                app:statusBarScrim="@android:color/transparent">

But, sadly, it doesn't set the font.

nealsanche avatar Aug 24 '15 20:08 nealsanche

@nealsanche until google do sensible things like inflate layouts like they should be then it's very difficult to intercept anything like this, they do dirty things like creating TextViews pragmatically. From memory the Collapsing stuff is particularly difficult as they actually paint the text (TextView doesn't even scrap the surface of being able to do what they want).

That said it is possible to "intercept" the CollapsingToolbarLayout IF they expose setters for Typefaces.

I would suggest you raise a bug at b.google.com and ask them to expose Typeface support on the widget. Once they are exposed, its pretty trivial to enable Calligraphy to do this.

chrisjenx avatar Aug 25 '15 10:08 chrisjenx

I think @chrisjenx meant http://b.android.com.

But... no need to raise another issue! I've created a Feature/Enhancement Request already. Please star the issue.

https://code.google.com/p/android/issues/detail?id=184873

onyxmueller avatar Sep 03 '15 21:09 onyxmueller

@chrisjenx Is this the same issue that I'm having with Calligraphy not setting the typeface when I define a fontPath item in my style that i pass to NavigationView.setItemTextAppearance()? The only way I seem to be able to modify the font of items in my NavigationView seems to be by changing the default font I set during Calligraphy's initialization.

Just so it's clear, I'm subclassing NavigationView, and then in each constructor I call my own method called init(). inside init() I do the following:

setItemTextAppearance(R.style.my_style_with_a_fontPath_item); inflateMenu(R.menu.my_nav_view_menu);

If so, I'll open another enhancement ticket to get the typeface of the menu items exposed like the ticket that was made for CollapsingToolbarLayout. Chris Banes already assigned that one to himself.

dphillipsprosper avatar Sep 04 '15 00:09 dphillipsprosper

@dphillipsprosper MenuItems aren't handled at the moment regardless, I would need to look into how NavigationView is inflated, as I haven't looked yet.

chrisjenx avatar Sep 04 '15 09:09 chrisjenx

Hmm, that's good to know about MenuItems not being handled. But they seem to just be a backing dataitem for an adapter.

I dug into the NavigationView class a bit. It seems that in the constructor, it news up a NavigationMenuPresenter, then calls mPresenter.initForMenu(Context context, MenuBuilder menu), passing in the Context from the constructor. NavigationMenuPresenter.initForMenu() then uses that context to create a LayoutInflater and keeps that inflater around as a member of NavigationMenuPresenter. This inflater is used in NavigationMenuPresenter.NavigationMenuAdapter.getView(), which is where the actual views for the menu items are created. After a view for a menu item is inflated, the setTextAppearance(Context, int) method is called on the view, using the style I set as the TextAppearance in init(), and view.getContext() is used as the context.

So if I understand how Calligraphy works, the Context used to create the LayoutInflater should be the one that's wrapped with the CalligraphyContextWrapper, correct? So the Context attached to the views for the menu items should have the stuff needed for Calligraphy to do its thing?

dphillipsprosper avatar Sep 04 '15 16:09 dphillipsprosper

@Don, yes the CalligraphyLayoutInflater will be passed to the View. The issue being that we apply the font at Inflation, setting the setTextAppearance after the view is inflated will have no effect (at least to the font). So you need to be able to define the style/textAppearance that will be used to inflate the menu item.

If there is no style/attribute defining the menuitem inside the xml then Calligraphy can't hook into a set font.

It's a pain.

On Fri, 4 Sep 2015 at 17:51 Don Phillips [email protected] wrote:

Hmm, that's good to know about MenuItems not being handled. But they seem to just be a backing dataitem for an adapter.

I dug into the NavigationView class a bit. It seems that in the constructor, it news up a NavigationMenuPresenter, then calls mPresenter.initForMenu(Context context, MenuBuilder menu), passing in the Context from the constructor. NavigationMenuPresenter.initForMenu() then uses that context to create a LayoutInflater and keeps that inflater around as a member of NavigationMenuPresenter. This inflater is used in NavigationMenuPresenter.NavigationMenuAdapter.getView(), which is where the actual views for the menu items are created. After a view for a menu item is inflated, the setTextAppearance(Context, int) method is called on the view, using the style I set as the TextAppearance in init(), and view.getContext() is used as the context.

So if I understand how Calligraphy works, the Context used to create the LayoutInflater should be the one that's wrapped with the CalligraphyContextWrapper, correct? So the Context attached to the views for the menu items should have the stuff needed for Calligraphy to do its thing?

— Reply to this email directly or view it on GitHub https://github.com/chrisjenx/Calligraphy/issues/202#issuecomment-137789070 .

chrisjenx avatar Sep 04 '15 22:09 chrisjenx

Ahh, so I'm sunk, because the XML layout that's being inflated inside the NavigationView to display each menu item is coming out of the support design library, and that XML layout doesn't have a fontPath attribute on it's tags or in it's default textAppearance. Bummer, but thanks for explaining.

dphillipsprosper avatar Sep 04 '15 22:09 dphillipsprosper

It might have a style applied to it though. In that case you can just override that style from the design library.

On Fri, 4 Sep 2015 23:53 Don Phillips [email protected] wrote:

Ahh, so I'm sunk, because the XML layout that's being inflated inside the NavigationView to display each menu item is coming out of the support design library, and that XML layout doesn't have a fontPath attribute on it's tags or in it's default textAppearance. Bummer, but thanks for explaining.

— Reply to this email directly or view it on GitHub https://github.com/chrisjenx/Calligraphy/issues/202#issuecomment-137874313 .

chrisjenx avatar Sep 07 '15 07:09 chrisjenx

Found the XML for the item. It does have a textAppearance set, but it's set to a style directly rather than an attribute, so no go on the override there I think. But at least this means I can submit an enhancement (make the textAppearance reference a theme attribute rather than a style) and make our lives easier.

Here's the XML for the NavigationMenuItemView, in case I'm incorrect:

<android.support.design.internal.NavigationMenuItemView
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="?attr/listPreferredItemHeightSmall"
        android:paddingLeft="?attr/listPreferredItemPaddingLeft"
        android:paddingRight="?attr/listPreferredItemPaddingRight"
        android:drawablePadding="@dimen/design_navigation_icon_padding"
        android:gravity="center_vertical|start"
        android:maxLines="1"
        android:textAppearance="@style/TextAppearance.AppCompat.Body2"/>

dphillipsprosper avatar Sep 08 '15 16:09 dphillipsprosper

Well in theory if you override TextAppearance.AppCompat.Body2 in your styles.xml. That will get picked up and applied to the View. (including the fontPath).

On Tue, 8 Sep 2015 at 17:42 Don Phillips [email protected] wrote:

Found the XML for the item. It does have a textAppearance set, but it's set to a style directly rather than an attribute, so no go on the override there I think. But at least this means I can submit an enhancement (make the textAppearance reference a theme attribute rather than a style) and make our lives easier.

Here's the XML for the NavigationMenuItemView, in case I'm incorrect:

<android.support.design.internal.NavigationMenuItemView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="?attr/listPreferredItemHeightSmall" android:paddingLeft="?attr/listPreferredItemPaddingLeft" android:paddingRight="?attr/listPreferredItemPaddingRight" android:drawablePadding="@dimen/design_navigation_icon_padding" android:gravity="center_vertical|start" android:maxLines="1" android:textAppearance="@style/TextAppearance.AppCompat.Body2"/>

— Reply to this email directly or view it on GitHub https://github.com/chrisjenx/Calligraphy/issues/202#issuecomment-138626140 .

chrisjenx avatar Sep 08 '15 22:09 chrisjenx

So looks like setTypeface is enabled on the latest version of the design lib. This would still require a nasty work around tho to extract the correct Style for it. Although I could at the very least support the Default/Theme typeface.

chrisjenx avatar Sep 21 '15 22:09 chrisjenx

Looks like the NavigationView menu items are working now with the Calligraphy library and menu items display the correct font. At least with the latest version 23.1.1.

touchbee avatar Nov 25 '15 17:11 touchbee

An alternative method for setting the typeface for the CollapsingToolbarLayout for anyone else that was wondering: http://developer.android.com/reference/android/support/design/widget/CollapsingToolbarLayout.html#setCollapsedTitleTypeface(android.graphics.Typeface)

dsardari avatar Feb 18 '16 19:02 dsardari

Can anyone confirm whether or not expandedTitleTextAppearance is playing nice with Calligraphy at this time? I'm not seeing the font change properly, but the comments on this bug make me think Chris and touchbee are indicating it does play nice now. Trying to deduce what I'm missing. I have a style with a fontPath being assigned as the expandedTitleTextAppearance but it only respects the size color, and not the font.

Kusand avatar Jan 30 '17 17:01 Kusand

IT does not, we only look for textAppearance at the moment.

On Mon, 30 Jan 2017 at 10:13 Kusand [email protected] wrote:

Can anyone confirm whether or not expandedTitleTextAppearance is playing nice with Calligraphy at this time? I'm not seeing the font change properly, but the comments on this bug make me think Chris and touchbee are indicating it does play nice now. Trying to deduce what I'm missing. I have a style with a fontPath being assigned as the expandedTitleTextAppearance but it only respects the size color, and not the font.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/chrisjenx/Calligraphy/issues/202#issuecomment-276124020, or mute the thread https://github.com/notifications/unsubscribe-auth/ABHRsSpNs96NEgQJPqYx4h5pjPYjHPvwks5rXhpCgaJpZM4FxTYE .

chrisjenx avatar Jan 30 '17 17:01 chrisjenx

Drat. Would that be desirable to patch in? I can probably get some bandwidth to do so, and clearance to contribute.

Kusand avatar Jan 30 '17 17:01 Kusand

Yeah sure, it would be better as a plugin, we are working on making this much more flexible at the moment.

On Mon, 30 Jan 2017 at 10:18 Kusand [email protected] wrote:

Drat. Would that be desirable to patch in? I can probably get some bandwidth to do so, and clearance to contribute.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/chrisjenx/Calligraphy/issues/202#issuecomment-276125402, or mute the thread https://github.com/notifications/unsubscribe-auth/ABHRsQiqbFzaot__9C5iwhszm1f9Ns-5ks5rXhtYgaJpZM4FxTYE .

chrisjenx avatar Jan 30 '17 17:01 chrisjenx