Android - “没有封闭的类型实例'some.abstract.class.name'类在范围内”扩展时出错

时间:2016-11-09 05:00:37

标签: java android abstract-class extends android-viewholder

我有一个来自外部库的抽象适配器类:

public abstract class DragItemAdapter<T, VH extends DragItemAdapter.ViewHolder> extends RecyclerView.Adapter<VH> {
    //Their other codes
    public class ViewHolder extends RecyclerView.ViewHolder {
        public ViewHolder(final View itemView, int handleResId) {
            super(itemView);
            //The rest of their codes
        }
    }
}

我的适配器扩展了适配器

public class ChecklistAdapter extends DragItemAdapter<Pair<Integer, SomeClass>, ViewHolderForChecklist> {

    @Override
    public ViewHolderForChecklist onCreateViewHolder(ViewGroup parent, int viewType) {
          View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
          grab = R.id.grab;
          return new ViewHolderForChecklist(view,grab);
    }
}

如果我的ViewHolderForChecklistChecklistAdapter的内部类,则可以正常工作。但是如果我将ViewHolderForChecklist移到一个全新的班级

public class ViewHolderForChecklist extends DragItemAdapter<Pair<Long, SomeClass>, ViewHolderForChecklist>.ViewHolder { // The error is at this line

    public ViewHolderForChecklist(final View itemView, int grab) {
        super(itemView, grab);
    }

    @Override
    public void onItemClicked(View view) {

    }

    @Override
    public boolean onItemLongClicked(View view) {
        return true;
    }
}

实时出错

  

没有封闭的'library.package.name.DragItemAdapter'类的实例在范围内

和编译时的错误

  

错误:需要包含DragItemAdapter.ViewHolder的封闭实例

从Refractor使用“move”也有同样的问题。我仍然是这种......'嵌套类'的新手,所以我不知道这有什么问题,或者我应该包含哪些信息。

谢谢!

1 个答案:

答案 0 :(得分:1)

ViewHolderDragItemAdapter内部类(因为它未声明为static)。这意味着类ViewHolder的每个对象都必须与类DragItemAdapter的对象相关联(实际上,它必须是DragItemAdapter的子类)。您可以将ViewHolder视为具有隐藏的实例变量,如

DragItemAdapter __outerObject;

ViewHolder可以直接访问属于__outerObject的实例变量和方法。

这意味着,当您说new ViewHolder(...)时,您必须有一些DragItemAdapterViewHolder相关联。

同样适用于ViewHolder的任何子类,包括ViewHolderChecklist,因为子类继承了隐藏的__outerObject变量。

在第一个示例中,ViewHolderChecklist位于ChecklistAdapter内,onCreateViewHolder方法将始终在ChecklistAdapter实例上调用。当该方法显示new ViewHolderChecklist时,新对象的__outerObject将设置为ChecklistAdapter实例。此外,如果外部课程有ChecklistAdapter adapter;,则可以使用ViewHolderChecklist来创建新的adapter.new ViewHolderChecklist(...)

但是,当您将ViewHolderChecklist移到课堂外时,无法创建新实例,因为无法以某种方式使用new来告诉它__outerObject adapter.new ViewHolderChecklist(...) 1}}应该是。 ViewHolderChecklist语法不起作用,因为该语法仅允许嵌套类,ViewHolderChecklist不是嵌套类。所以DragItemAdapter必须是ViewHolderChecklist的子类中的嵌套类。

更正:实际上可以像这样声明UserName。但是,您必须为其提供一个显式构造函数,并且必须具有Qualified Superclass Constructor Invocation(请参阅this;另请参阅https://stackoverflow.com/questions/40501642/what-rule-prohibits-this-nested-class-reference/40501815