【发布时间】:2019-12-11 22:57:08
【问题描述】:
我在 Android Studio 中基于 ConstraintLayout 创建了一些自定义组件。首先,我创建了名为 MyButton 的基本抽象类,我在其中做一些基本的事情(例如,获取对我的组件的引用)。接下来,我创建了名为 MySpecialButton 的派生类,它扩展了 MyButton,但是当我将 onClickListener 附加到我的 Button(这是我的自定义组件的一部分)时,我有奇怪的行为,并调用修改仅存在于来自 onClickListener 的 MySpecialButton 中的元素(引用)的方法。
在当前代码中,当我尝试从 onClickListener 调用 setImage() 时,最终会出现日志:E/NULL: ImageView reference is null!,这意味着从 onClickListener 的角度来看,引用 vImageViev 为空,但它在 @987654324 中初始化@ 称呼。但是当我不是从 onClickListener 而是直接从 init() 方法在 inflateView(R.layout.my_special_button) 之后调用 setImage() 时,一切正常。
此外,当我将 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);
}
}
发生了什么事?我应该怎么做才能在没有空引用的情况下从 onClickListener 调用 setImage()?
【问题讨论】:
标签: java android derived-class