首页 > 其他 > 详细

自定义preference onBindView易犯的错误

时间:2014-01-21 00:48:30      阅读:675      评论:0      收藏:0      [点我收藏+]
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更新显示。

自定义preference onBindView易犯的错误

原文:http://blog.csdn.net/u012604322/article/details/18362575

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!