Butterknife自定义视图解除绑定

11

调用的最佳实践是什么:-

Butterknife.unbind()
在自定义的Android视图中怎么做?
4个回答

26

是的,onDetachedFromWindow 是正确的函数,如 NJ的回答中所述,因为这是视图不再具有用于绘制的表面的地方。

但是该答案中提到的用法是不正确的。正确的方法是在onFinishInflate()中进行绑定:

@Override
protected void onFinishInflate() {
    super.onFinishInflate();
    unbinder = ButterKnife.bind(this);
}

onDetachedFromWindow中取消绑定:

@Override
protected void onDetachedFromWindow() {
    super.onDetachedFromWindow();
    // View is now detached, and about to be destroyed
    unbinder.unbind();
}

在自定义视图中是否需要绑定?我在片段中没有解除绑定,为什么在视图中需要这样做?我只是想知道是否需要进行清理或为什么要解除绑定。 - j2emanue
如果您需要将视图和侦听器置空,则最好在自定义视图中调用unbind。这不是必需的,但建议采用此方法。您还应该在Fragment中解除绑定。Jake Wharton在此处提到了原因: 可能存在这样一种情况,即片段的视图已被销毁,但片段实例仍然存在。例如,当片段进入后退堆栈时 - 调用onDestroyView(),但不会调用onDestroy()。 来源:https://github.com/JakeWharton/butterknife/issues/291 - Wahib Ul Haq
@j2emanue 这里有更好的解释,为什么要在 onDestroyView(); 中将视图设置为空。https://dev59.com/W18d5IYBdhLWcg3w21Om#26370042 @WahibUlHaq 我不确定你是否需要在 onDetachedFromView() 中这样做,因为此时您的自定义视图尚未为空,如果您尝试在取消绑定后更改其子项,则会出现 NullPointerException。 - Roman Nazarevych
我想知道,在绑定之前,是否最好在onCreateView中取消绑定? - j2emanue

10

尝试在 onDetachedFromWindow() 中使用。

Unbinder unbinder;
unbinder = Butterknife.bind(this, root);

onDetachedFromWindow方法中,您需要调用unbinder.unbind();

@Override
protected void onDetachedFromWindow() {
    super.onDetachedFromWindow();
    // View is now detached, and about to be destroyed
   unbinder.unbind()
}

1
这是正确的方法,但要小心,因为 onDetachedFromWindow 回调不一定意味着 View 将被销毁(例如,如果它是 RecyclerView 的一部分)。 - Bartek Lipinski
1
@BartekLipinski 在 ViewHolder 中自定义视图的正确方法是什么?在 onDetachedFromWindow() 中调用 unbind 是不可能的。 - erdna

1

onDetachedFromWindow 不总是有效的,例如当自定义视图位于 RecyclerView 中时。事实上,添加它实际上会导致我的应用程序崩溃。老实说,不解绑也可以正常工作。


0

警告!

如果您在 XML 中设置属性为 app:attribute="value",则在读取时将丢失其值:

@Override
protected void onFinishInflate() {
    super.onFinishInflate();
    unbinder = ButterKnife.bind(this);

    TypedValue typedValue = new TypedValue();
    TypedArray typedArray = getContext().obtainStyledAttributes(typedValue.data, R.styleable.YourStyleable);
    try {
        int number = typedArray.getResourceId(R.styleable.YourStyleable_number, 0);
        image.setImageResource(number);

        String text = typedArray.getString(R.styleable.YourStyleable_text);
        text.setText(text);
    } finally {
        typedArray.recycle();
    }
}

它们的值将为0和null。在自定义视图的构造函数中初始化它们。

一个原因是使用obtainStyledAttributes(typedValue.data而不是obtainStyledAttributes(attrs

参见:使用obtainStyledAttributes方法的魔法


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接