Tran Hoai Nam Tran Hoai Nam - 2 months ago 13
Android Question

Android - "No enclosing instance of type '' class is in scope" error when extended

I have an abstract adapter class from an external library:

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) {
//The rest of their codes

And I have my Adapter extended that adapter

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

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

If my
is an inner class of the
it works fine. But if I move the
to a brand new class

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);

public void onItemClicked(View view) {


public boolean onItemLongClicked(View view) {
return true;

There is an error in real time

No enclosing instance of type '' class is in scope

and the error when compile

error: an enclosing instance that contains DragItemAdapter.ViewHolder is required

Using "move" from Refractor has the same problem. I'm still new to this kind of... 'nested-class" so I don't know what is wrong with this or what kind of info should I include more.

Thank you!

ajb ajb

ViewHolder is an inner class of DragItemAdapter (because it wasn't declared static). That means that every object of class ViewHolder must be associated with an object of class DragItemAdapter (actually, it would have to be a subclass of DragItemAdapter). You can think of ViewHolder having a hidden instance variable like

DragItemAdapter __outerObject;

The ViewHolder can directly access instance variables and methods belonging to the __outerObject.

That means that when you say new ViewHolder(...), you have to have some DragItemAdapter for the ViewHolder to be associated with.

The same applies to any subclass of ViewHolder, including ViewHolderChecklist, since the subclass inherits the hidden __outerObject variable.

In the first example, where ViewHolderChecklist is inside a ChecklistAdapter, the onCreateViewHolder method will always be called on a ChecklistAdapter instance. When that method says new ViewHolderChecklist, the new object's __outerObject will be set to the ChecklistAdapter instance. Also, if an outside class has a ChecklistAdapter adapter;, it can use that to create a new ViewHolderChecklist by saying ViewHolderChecklist(...).

When you move ViewHolderChecklist outside the class, though, there's no way for a new instance to be created, since there's no way to use new in a way that would tell it what its __outerObject is supposed to be. The ViewHolderChecklist(...) syntax won't work, because that syntax is only allowed for nested classes, and ViewHolderChecklist isn't a nested class. So ViewHolderChecklist has to be a nested class inside a subclass of DragItemAdapter.