使用设置样式ATTRS时NumberFormatException异常样式、异常、ATTRS、NumberFormatException

由网友(silent 黑白年代)分享简介:我创建Android的一个自定义视图这使得两个内部视图存储一键,两列的值。这个类看起来是这样的: 公共类KeyValueRow扩展RelativeLayout的{    保护的TextView mLabelTextView;    保护的TextView mValueTextView;    公共KeyValueRow...

我创建Android的一个自定义视图这使得两个内部视图存储一键,两列的值。这个类看起来是这样的:

 公共类KeyValueRow扩展RelativeLayout的{    保护的TextView mLabelTextView;    保护的TextView mValueTextView;    公共KeyValueRow(最终上下文的背景下){        超级(上下文);        初始化(上下文,空,0);    }    公共KeyValueRow(最终上下文的背景下,最终的AttributeSet ATTRS){        超(背景下,ATTRS);        初始化(上下文,ATTRS,0);    }    公共KeyValueRow(最终上下文的背景下,                       最终的AttributeSet ATTRS,诠释defStyle){        超(背景下,ATTRS,defStyle);        的init(背景下,ATTRS,defStyle);    }    保护无效的init(最终上下文的背景下,                        最终的AttributeSet ATTRS,诠释defStyle){        查看布局=((LayoutInflater)上下文            .getSystemService(Context.LAYOUT_INFLATER_SERVICE))            .inflate(R.layout.key_value_row,这一点,真正的); //行46        mLabelTextView =(TextView中)layout.findViewById(            R.id.key_value_row_label);        mValueTextView =(TextView中)layout.findViewById(            R.id.key_value_row_value);    }    公共无效setLabelText(最后字符串文本){        mLabelTextView.setText(文本);    }    公共无效setValueText(最后字符串文本){        mValueTextView.setText(文本);    }} 

相关联的布局文件的布局/ key_value_row.xml 的是这样的:

 <?XML版本=1.0编码=UTF-8&GT?;<的LinearLayout    的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android    的xmlns:工具=htt​​p://schemas.android.com/tool​​s    机器人:方向=横向    机器人:layout_width =match_parent    机器人:layout_height =WRAP_CONTENT    机器人:weightSum =1.0>    <的TextView        机器人:ID =@ + ID / key_value_row_label        风格=@风格/ KeyValueLabel        机器人:layout_weight =55        工具:文本=标签/>    <的TextView        机器人:ID =@ + ID / key_value_row_value        风格=@风格/ KeyValueValue        机器人:layout_weight =45        工具:文本=值/>< / LinearLayout中> 

这可被用作在一个布局如下:

 < com.example.myapp.customview.KeyValueRow    机器人:ID =@ + ID / foobar的    风格=@风格/ KeyValueRow/> 
提取道路 EXCEL中从地址中提取道路名称等信息

在此之前,一切工作正常!

挑战

现在,我想允许为内的TextView 秒。因此,我prepared中的值/ attrs.xml 的属性:

 <?XML版本=1.0编码=UTF-8&GT?;<资源>    <申报-设置样式名称=KeyValueRow>        < attr指示NAME =label_layout_weight格式=浮动/>        < attr指示NAME =value_layout_weight格式=浮动/>    < /申报,设置样式>< /资源> 

第一个问题是:是的浮动作为正确格式 layout_weight 结果接下来,我会申请他们在布局文件:

 <?XML版本=1.0编码=UTF-8&GT?;<的LinearLayout    的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android    的xmlns:工具=htt​​p://schemas.android.com/tool​​s    机器人:方向=横向    机器人:layout_width =match_parent    机器人:layout_height =WRAP_CONTENT    机器人:weightSum =1.0>    <的TextView        机器人:ID =@ + ID / key_value_row_label        风格=@风格/ KeyValueLabel        机器人:label_layout_weightlayout_weight =        工具:文本=标签/>    <的TextView        机器人:ID =@ + ID / key_value_row_value        风格=@风格/ KeyValueValue        机器人:value_layout_weightlayout_weight =        工具:文本=值/>< / LinearLayout中> 

然后,他们可以在例如使用:

 < com.example.myapp.customview.KeyValueRow    机器人:ID =@ + ID / foobar的    风格=@风格/ KeyValueRow    定制:label_layout_weight =25    75:定制value_layout_weight = /> 

当我运行这个实现以下异常被抛出:

 产生的原因:java.lang.NumberFormatException:无效的浮动:2130772062    在java.lang.StringToReal.invalidReal(StringToReal.java:63)    在java.lang.StringToReal.parseFloat(StringToReal.java:310)    在java.lang.Float.parseFloat(Float.java:300)    在android.content.res.TypedArray.getFloat(TypedArray.java:288)    在android.widget.LinearLayout $的LayoutParams<&初始化GT;(LinearLayout.java:1835)    在android.widget.LinearLayout.generateLayoutParams(LinearLayout.java:1743)    在android.widget.LinearLayout.generateLayoutParams(LinearLayout.java:58)    在android.view.LayoutInflater.rInflate(LayoutInflater.java:757)    在android.view.LayoutInflater.inflate(LayoutInflater.java:492)    在android.view.LayoutInflater.inflate(LayoutInflater.java:397)    在com.example.myapp.customview.KeyValueRow.init(KeyValueRow.java:46)    在com.example.myapp.customview.KeyValueRow<&初始化GT;(KeyValueRow.java:28)    ... 33更多 

解决方案

您可以使用

 私人无效applyAttributes(上下文的背景下,ATTRS的AttributeSet){    TypedArray A = context.getTheme()。obtainStyledAttributes(        ATTRS,R.styleable.KeyValueRow,0,0);    尝试{        labelWeight = a.getFloat(            R.styleable.KeyValueRow_label_layout_weight,0.55f);        valueWeight = a.getFloat(            R.styleable.KeyValueRow_value_layout_weight,0.45f);    } {最后        a.recycle();    }} 

和在这之后,你可以通过应用此:

  mLabelTextView =(TextView中)layout.findViewById(R.id.key_value_row_label);LinearLayout.LayoutParams的LayoutParams =新LinearLayout.LayoutParams(    LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT,labelWeight);mLabelTextView.setLayoutParams(的LayoutParams); 

要让它运行替换的android:layout_weight =label_layout_weight?有一些默认值,如的android:layout_weight =0.5布局/ key_value_row.xml 。它将会被覆盖。

I created a custom view for Android which renders two inner views to store a key and a value in two columns. The class looks like this:

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);
    }

}

The associated layout file layout/key_value_row.xml looks like this:

<?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>

This can be used as follows in a layout:

<com.example.myapp.customview.KeyValueRow
    android:id="@+id/foobar"
    style="@style/KeyValueRow" />

Until here everything works fine!

The challenge

Now, I want to allow custom settings for the layout_weight attributes of both inner TextViews. Therefore, I prepared the attributes in 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>

First question would be: is float the correct format for layout_weight? Next, I would apply them in the layout file:

<?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>

Then they can be used in the example:

<com.example.myapp.customview.KeyValueRow
    android:id="@+id/foobar"
    style="@style/KeyValueRow"
    custom:label_layout_weight=".25"
    custom:value_layout_weight=".75" />

When I run this implementation the following exception is thrown:

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

解决方案

You can use

private void applyAttributes(Context context, AttributeSet attrs) {
    TypedArray a = context.getTheme().obtainStyledAttributes(
        attrs, R.styleable.KeyValueRow, 0, 0);
    try {
        labelWeight = a.getFloat(
            R.styleable.KeyValueRow_label_layout_weight, 0.55f);
        valueWeight = a.getFloat(
            R.styleable.KeyValueRow_value_layout_weight, 0.45f);
    } finally {
        a.recycle();
    }
}

and after this you can apply this via:

mLabelTextView = (TextView) layout.findViewById(R.id.key_value_row_label);
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, labelWeight);
mLabelTextView.setLayoutParams(layoutParams);

To get it running replace android:layout_weight="?label_layout_weight" with some default value such as android:layout_weight="0.5" in layout/key_value_row.xml. It will be overwritten.