我的CustomTextView.有问题我正在尝试从我的layout-xml文件中获取一个自定义值,并在我的setText()方法中使用这个值。不幸的是,setText()方法在构造函数之前调用了,因此不能在该方法中使用自定义值。
下面是我的代码(细分为相关部分):
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>作为一个证明-这是LogCat输出:
30912-30912/com.mypackage.views D/CustomTextView﹕ in setText function
30912-30912/com.mypackage.views D/CustomTextView﹕ in CustomTextView constructor因此,如您所见,在构造函数之前调用setText()方法。这有点奇怪,为了在setText方法中使用我的自定义属性(cHeight),我不知道需要更改什么。
提前感谢您的帮助!
发布于 2014-08-29 10:03:56
它是TextView super()构造函数,它根据属性值调用setText()。
如果在设置文本值时确实需要访问自定义属性,也可以为文本使用自定义属性。
发布于 2016-06-06 22:23:01
我不认为这些解决方案都是好的,IMHO。如果您只是使用一个自定义方法,比如setCustomText(),而不是覆盖自定义TextView.setText(),那该怎么办?我认为它在可伸缩性方面可能会更好,而黑客/重写TextView的实现可能会使您陷入未来的问题。
干杯!
发布于 2016-05-27 15:46:23
首先,记住在使用TypedArray之后始终回收它。
因此,TextView在其构造过程中调用#setText(CharSequence text, BufferType type)定义了对setText的延迟调用,如下所示:
private Runnable mDelayedSetter;
private boolean mConstructorCallDone;
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);
mConstructorCallDone = true;
}然后在您的setText-override中:
public void setText(final CharSequence text, final TextView.BufferType type) {
if (!mConstructorCallDone) {
// The original call needs to be made at this point otherwise an exception will be thrown in BoringLayout if text contains \n or some other characters.
super.setText(text, type);
// Postponing setting text via XML until the constructor has finished calling
mDelayedSetter = new Runnable() {
@Override
public void run() {
CustomTextView.this.setText(text, type);
}
};
post(mDelayedSetter);
} else {
removeCallbacks(mDelayedSetter);
Spannable s = getCustomSpannableString(getContext(), text);
super.setText(s, BufferType.SPANNABLE);
}
}https://stackoverflow.com/questions/25565939
复制相似问题