【发布时间】:2015-02-06 05:58:25
【问题描述】:
我为 Android 创建了一个 自定义视图,它呈现两个内部视图以在两列中存储一个键和一个值。该类如下所示:
public class KeyValueRow extends RelativeLayout {
protected TextView mLabelTextView;
protected TextView mValueTextView;
public KeyValueRow(final Context context) {
super(context);
init(context, null, 0);
}
public KeyValueRow(final Context context, final AttributeSet attrs) {
super(context, attrs);
init(context, attrs, 0);
}
public KeyValueRow(final Context context,
final AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context, attrs, defStyle);
}
protected void init(final Context context,
final AttributeSet attrs, int defStyle) {
View layout = ((LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE))
.inflate(R.layout.key_value_row, this, true); // line 46
mLabelTextView = (TextView) layout.findViewById(
R.id.key_value_row_label);
mValueTextView = (TextView) layout.findViewById(
R.id.key_value_row_value);
}
public void setLabelText(final String text) {
mLabelTextView.setText(text);
}
public void setValueText(final String text) {
mValueTextView.setText(text);
}
}
相关的布局文件layout/key_value_row.xml如下所示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="1.0">
<TextView
android:id="@+id/key_value_row_label"
style="@style/KeyValueLabel"
android:layout_weight=".55"
tools:text="Label"/>
<TextView
android:id="@+id/key_value_row_value"
style="@style/KeyValueValue"
android:layout_weight=".45"
tools:text="Value"/>
</LinearLayout>
这可以在布局中如下使用:
<com.example.myapp.customview.KeyValueRow
android:id="@+id/foobar"
style="@style/KeyValueRow" />
直到这里一切正常!
挑战
现在,我想允许对两个内部 TextViews 的 layout_weight 属性进行自定义设置。因此,我在values/attrs.xml中准备了属性:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="KeyValueRow">
<attr name="label_layout_weight" format="float" />
<attr name="value_layout_weight" format="float" />
</declare-styleable>
</resources>
第一个问题是:float 是layout_weight 的正确格式吗?
接下来,我会将它们应用到布局文件中:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:weightSum="1.0">
<TextView
android:id="@+id/key_value_row_label"
style="@style/KeyValueLabel"
android:layout_weight="?label_layout_weight"
tools:text="Label"/>
<TextView
android:id="@+id/key_value_row_value"
style="@style/KeyValueValue"
android:layout_weight="?value_layout_weight"
tools:text="Value"/>
</LinearLayout>
那么就可以在例子中使用:
<com.example.myapp.customview.KeyValueRow
android:id="@+id/foobar"
style="@style/KeyValueRow"
custom:label_layout_weight=".25"
custom:value_layout_weight=".75" />
当我运行这个实现时,会抛出以下异常:
Caused by: java.lang.NumberFormatException: Invalid float: "?2130772062"
at java.lang.StringToReal.invalidReal(StringToReal.java:63)
at java.lang.StringToReal.parseFloat(StringToReal.java:310)
at java.lang.Float.parseFloat(Float.java:300)
at android.content.res.TypedArray.getFloat(TypedArray.java:288)
at android.widget.LinearLayout$LayoutParams.<init>(LinearLayout.java:1835)
at android.widget.LinearLayout.generateLayoutParams(LinearLayout.java:1743)
at android.widget.LinearLayout.generateLayoutParams(LinearLayout.java:58)
at android.view.LayoutInflater.rInflate(LayoutInflater.java:757)
at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
at com.example.myapp.customview.KeyValueRow.init(KeyValueRow.java:46)
at com.example.myapp.customview.KeyValueRow.<init>(KeyValueRow.java:28)
... 33 more
【问题讨论】:
-
看起来你没有定义值是双精度还是浮点数,但双精度是默认值。 Double 是 64 位,float 32 所以你得到了异常。将所有内容更改为双精度或将值指定为浮点数。
-
@user3427079 这个浮点定义:
<attr name="label_layout_weight" format="float" />不够? -
我认为这实际上是导致问题的原因。属性中指定的浮点数是预期的,但实际传递的是双精度数。 NumberFormatException 可能是由于将较大的值放入较小的框中,因为它作为字符串传递,然后直接转换为 Float,但字符串也是 64 位。反过来,自动装箱将捕获。如果您将它们更改为双倍或指定您作为浮点数传递的值,我认为它应该可以工作。例如,尝试 1.0f 的重量。我不确定android的内部属性转换是如何处理的,希望它有效。
-
@user3427079 Android
attrs不提供double格式类型。 - 在我的问题的第一部分,您可以看到0.55值在没有任何类型限定符的情况下工作正常,如建议的0.55f中所示。尽管如此,我还是尝试了string作为格式类型,并按照您的建议附加了f。但这会以同样的错误结束。 -
嗯,太糟糕了。您是否考虑过扩大价值?而不是 0.75 和 0.25 使用它们作为百分比作为重量除以定义的总重量。所以使用 75 和 25 作为权重而不是浮点数/双精度数。
标签: android android-xml numberformatexception declare-styleable