我根据Android Studio中的ConstraintLayout创建了一些自定义组件。首先,我创建了名为Mybutton的基本抽象类,在其中做一些基本的事情(例如,获取对我的组件的引用(。接下来,我创建了派生的类称为myspecialbutton的派生类,它扩展了mybutton,但是当我将onclicklistener附加到按钮上时,我的行为很奇怪,这是我自定义组件的一部分,并调用仅在onClicklistener中仅在myspecialbutton中存在的元素(参考(的方法。
在当前的代码中,当我尝试从OnClickListener中调用setImage()
时,最终以log: E/NULL: ImageView reference is null!
结束,这意味着从角度来看,参考 vImageViev
是无效的,但是它在 inflateView
call中进行了初始化。但是,当我调用setImage()
不是来自OnClicklistener,而是直接来自inflateView(R.layout.my_special_button)
之后的init()
方法,一切正常。同样,当我将protected ImageView vImageView = null;
声明从myspecialbutton移动到mybutton时一切都很好。
这是我的mybutton课程:
public abstract class MyButton extends ConstraintLayout
{
protected Context context = null;
protected View rootView = null;
protected Button vButton = null;
protected Switch vSwitch = null;
public MyButton(Context context)
{
super(context);
this.context = context;
init();
}
public MyButton(Context context, AttributeSet attrs)
{
this(context);
}
protected abstract void init();
protected void inflateView(int res)
{
rootView = inflate(context, res, this);
vButton = (Button)rootView.findViewById(R.id.vButton);
vSwitch = (Switch)rootView.findViewById(R.id.vSwitch);
}
}
这是我的myspecialbutton类:
public class MySpecialButton extends MyButton
{
protected ImageView vImageView = null;
public MySpecialButton(Context context)
{
super(context);
}
public MySpecialButton(Context context, AttributeSet attr)
{
this(context);
}
@Override
protected void inflateView(int res)
{
super.inflateView(res);
vImageView = (ImageView)rootView.findViewById(R.id.vImageView);
}
protected void init()
{
inflateView(R.layout.my_special_button);
vButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
setImage();
}
});
}
protected void setImage()
{
if(vImageView == null)
Log.e("NULL", "ImageView reference is null!");
else
vImageView.setImageResource(R.drawable.ic_window);
}
}
发生了什么事?我应该做些什么才能在没有null参考的情况下从OnClicklistener调用setImage()
?
我认为您在构造函数中做错了超级呼叫:
这个
public MySpecialButton(Context context, AttributeSet attr)
{
this(context);
}
应该是:
public MySpecialButton(Context context, AttributeSet attr)
{
super(context, attr);
}
对另一堂课相同。并将您的自定义初始化以您从每个构造函数调用的不同函数。
那是因为 setOnClicklisnter 是为基类(这是约束layout(的,因为您没有在无法访问imageView的子类中覆盖它。
尝试以下操作:
public abstract class MyButton extends ConstraintLayout
{
protected Context context = null;
protected View rootView = null;
protected Button vButton = null;
protected Switch vSwitch = null;
//...
@Override
public void setOnClickListener(@Nullable OnClickListener l) {
vButton.setOnClickLisnter(l);
}
}