Search code examples
androidstylesdeclare-styleable

How to obtain typeface for RobotoTextView from reference styleable attribute


I have a custom view which contains several RobotoTextViews and I want to set typefaces for them. So, I use declare-styleable item like this:

<declare-styleable name="CustomView">
        <attr name="firstTextviewStyle" format="reference" />
        <attr name="secondTextviewStyle" format="reference" />
</declare-styleable>

The attributes are referenced to styles.

<style name="firstTextAppearance">
        <item name="typeface">roboto_medium</item>
        <item name="android:textSize">16sp</item>
        <item name="android:textColor">@android:color/white</item>
</style>

So, question is, how to get typeface attr value from this?


Solution

  • @nullpex you can do something like this for dynamic or runtime font change in your app like the following example. You can also use it in your layout file cuz there is custom view also with custom attributes.

    I have created a repository for the following code on GitHub https://github.com/harsh159357/customtextview

    Feel free to ask any question

    CustomTextViewActivity.java

    package com.harsh.customtextview;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Button;
    
    public class CustomTextViewActivity extends AppCompatActivity implements View.OnClickListener {
    
        CustomTextView customTextView1, customTextView2;
        Button changeToRoboto, changeToCalculus;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_text_view);
    
            customTextView1 = (CustomTextView) findViewById(R.id.customTextView1);
            customTextView2 = (CustomTextView) findViewById(R.id.customTextView2);
    
            changeToRoboto = (Button) findViewById(R.id.change_to_roboto);
            changeToCalculus = (Button) findViewById(R.id.change_to_calculus);
            changeToRoboto.setOnClickListener(this);
            changeToCalculus.setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.change_to_roboto:
                    customTextView1.setFont(getString(R.string.font_roboto_regular));
                    customTextView2.setFont(getString(R.string.font_roboto_regular));
                    break;
                case R.id.change_to_calculus:
                    customTextView1.setFont(getString(R.string.font_calculus_sans));
                    customTextView2.setFont(getString(R.string.font_calculus_sans));
                    break;
            }
        }
    }
    

    activity_text_view.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white"
        android:gravity="center"
        android:orientation="vertical"
        tools:context="com.harsh.customtextview.CustomTextViewActivity">
    
        <com.harsh.customtextview.CustomTextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/themed_text"
            android:textColor="@color/colorPrimary"
            android:textSize="22sp"
            app:theme="@style/roboto_theme"/>
    
        <com.harsh.customtextview.CustomTextView
            android:id="@+id/customTextView1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:text="@string/calculus_sans"
            android:textColor="@color/colorPrimary"
            android:textSize="22sp"
            app:fonts="@string/font_calculus_sans" />
    
        <com.harsh.customtextview.CustomTextView
            android:id="@+id/customTextView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:text="@string/roboto_regular"
            android:textColor="@color/colorPrimary"
            android:textSize="24sp"
            app:fonts="@string/font_roboto_regular" />
    
        <Button
            android:id="@+id/change_to_roboto"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:text="Change to Roboto" />
    
        <Button
            android:id="@+id/change_to_calculus"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:text="Change to Calculus" />
    
    </LinearLayout>
    

    CustomTextView.java

    package com.harsh.customtextview;
    
    import android.annotation.SuppressLint;
    import android.annotation.TargetApi;
    import android.content.Context;
    import android.content.res.TypedArray;
    import android.graphics.Typeface;
    import android.os.Build;
    import android.util.AttributeSet;
    import android.widget.TextView;
    
    @SuppressLint("AppCompatCustomView")
    public class CustomTextView extends TextView {
    
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        public CustomTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
            super(context, attrs, defStyleAttr, defStyleRes);
            init(attrs);
        }
    
        public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            init(attrs);
        }
    
        public CustomTextView(Context context, AttributeSet attrs) {
            super(context, attrs);
            init(attrs);
        }
    
        public CustomTextView(Context context) {
            super(context);
            init(null);
        }
    
        private void init(AttributeSet attrs) {
            if (attrs != null) {
                TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.CustomView);
                String fontName = a.getString(R.styleable.CustomView_fonts);
    
                try {
                    if (fontName != null) {
                        Typeface myTypeface = Typeface.createFromAsset(getContext().getAssets(), "fonts/" + fontName);
                        setTypeface(myTypeface);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
    
                a.recycle();
            }
        }
    
        public void setFont(String fontName) {
            setTypeface(Typeface.createFromAsset(getContext().getAssets(), "fonts/" + fontName));
        }
    }
    

    attrs.xml

    <?xml version="1.0" encoding="utf-8"?>
    <resources>
        <declare-styleable name="CustomView">
            <attr name="fonts" format="string" />
        </declare-styleable>
    </resources>
    

    styles.xml

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>
    
    
    <style name="roboto_theme">
        <item name="font">@string/font_calculus_sans</item>
    </style>
    

    strings.xml

    <resources>
        <string name="app_name">CustomTextView</string>
        <string name="font_calculus_sans">Calculus_Sans.ttf</string>
        <string name="font_roboto_regular">Roboto_Regular.ttf</string>
        <string name="calculus_sans">Calculus Sans</string>
        <string name="roboto_regular">Roboto Regular</string>
        <string name="themed_text">Themed Text</string>
    </resources>