user3989678 user3989678 - 6 months ago 45
Android Question

Custom TextView - setText() called before constructor

I've got a problem with my CustomTextView. I'm trying to get a custom value from my

layout-xml
file and use this in my
setText()
method. Unfortunately the setText() method gets called before the constructor and because of this I can't use the custom value in this method.

Here's my code (broken down to the relevant parts):

CustomTextView.class



public class CustomTextView extends TextView {

private float mHeight;
private final String TAG = "CustomTextView";
private static final Spannable.Factory spannableFactory = Spannable.Factory.getInstance();

public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
Log.d(TAG, "in CustomTextView constructor");
TypedArray values = context.obtainStyledAttributes(attrs, R.styleable.CustomTextView);
this.mHeight = values.getDimension(R.styleable.CustomTextView_cHeight, 20);
}

@Override
public void setText(CharSequence text, BufferType type) {
Log.d(TAG, "in setText function");
Spannable s = getCustomSpannableString(getContext(), text);
super.setText(s, BufferType.SPANNABLE);
}

private static Spannable getCustomSpannableString(Context context, CharSequence text) {
Spannable spannable = spannableFactory.newSpannable(text);
doSomeFancyStuff(context, spannable);
return spannable;
}

private static void doSomeFancyStuff(Context context, Spannable spannable) {
/*Here I'm trying to access the mHeight attribute.
Unfortunately it's 0 though I set it to 24 in my layout
and it's correctly set in the constructor*/
}
}


styles.xml



<declare-styleable name="CustomTextView">
<attr name="cHeight" format="dimension"/>
</declare-styleable>


layout.xml



<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ctvi="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<com.mypackage.views.CustomTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/my_fancy_string"
android:textSize="16sp"
ctvi:cHeight="24dp" />

</LinearLayout>


And just as a proof - here's the LogCat output:

30912-30912/com.mypackage.views D/CustomTextView﹕ in setText function
30912-30912/com.mypackage.views D/CustomTextView﹕ in CustomTextView constructor


So as you can see the
setText()
method is called before the constructor. That's kinda weird and I don't know what I need to change in order to use my custom attribute (
cHeight
) in the setText-method.

Thanks in advance for any help!

Answer

It's the TextView super() constructor that calls your setText() based on the attribute values.

If you really need to access your custom attribute when setting a text value, use a custom attribute for the text as well.