具有图像视图参考和派生类的奇怪行为



我根据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);
    }
}

最新更新