自定义preference onBindView易犯的错误

public class PowerInformationPreference extends Preference {

    private TextView firstName;

    public PowerInformationPreference(Context context, AttributeSet attr, int defStyle) {
        super(context, attr, defStyle);
        setLayoutResource(R.layout.layout_power_information);
    }

    @Override
    protected void onBindView(View view) {(1)
        // TODO Auto-generated method stub
        super.onBindView(view);
        firstName = (TextView)view.findViewById(R.id.firstname);(2)
    }

}

上面是我们很常见到的自定义preference的基本形式,我们在onBindView()函数中操作自定义视图,比如上面的代码中我们需要动态的改变firstName这一TextView的text值。

如下,我们提供一个setText()接口,通过这个接口我们可以动态改变TextView的text值。

public void setText(String text){(3)
    firstName.setText(text);//NullPointerException(4)
}

如果我们真的是这样写这个接口的话,会发现一定会出现NullPointerException,调试发现这里的firstName为空。而回到onBindView()中调试分析又会发现,firstName = (TextView)view.find...实际上是会运行的,也就是有这个firstName对象存在。那么唯一的解释就是setText()的调用在onBindView()运行之前,因此我们的疑惑来了,如何确保onBindView()在setText()调用之前运行呢?

事实上,到这里我们如果继续这样分析的话,就会钻入误区,跳出来,从逻辑层面上想想,我们会发现,(1),(2),(4)是对UI的操作,(3)是对数据的操作。这里,(1)(2)和(4)分开了,也就是说,(1)(2)运行的时候不能保证(4)运行;(4)运行的时候不能保证(1)(2)运行,这对UI操作是非常危险的事,很容易就产生了控制正异常。

不仅仅是这里,我们查看Adapter.java的源码,查看有getView(), onCreateView(), onBindView()等类的相关源码,都会发现,凡是涉及到UI操作的一定是放在一起的。


现给出上例的修正方案:

public class PowerInformationPreference extends Preference {

    private TextView firstName;
    private String text;

    public PowerInformationPreference(Context context, AttributeSet attr, int defStyle) {
        super(context, attr, defStyle);
        setLayoutResource(R.layout.layout_power_information);
    }

    @Override
    protected void onBindView(View view) {(1)
        // TODO Auto-generated method stub
        super.onBindView(view);
        firstName = (TextView)view.findViewById(R.id.firstname);(2)
        firstName.setText(text);
    }

public void setText(String text){(3) this.text = text;
notifyChanged();
}
}


这里还需要强调的一点是一定不要忘记notifyChanged()这个函数通知UI更新数据,否则我们会发现通过这个接口设置的数据并没有改变原来的值。这个函数如同View中的invalidate(),虽然数据更新了,但是显示在视图中的数字图像依然没变,因此需要通知UI更新显示。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值