2016-11-09 1 views
2

У меня есть абстрактный класс адаптера из внешней библиотеки:Android - «Нет ограждающего экземпляр„some.abstract.class.name“типа класса находится в области видимости» ошибки при выдвижении

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

Если мой ViewHolderForChecklist является внутренний класс ChecklistAdapter он прекрасно работает. Но если перенести 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; 
    } 
} 

Существует ошибка в реальном времени

No enclosing instance of type 'library.package.name.DragItemAdapter' class is in scope

и ошибка при компиляции

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

Использование «движение» от рефрактор имеет ту же проблему. Я еще новичок в этом виде ... «вложенной-класса», так что я не знаю, что это неправильно с этим или какого рода информацию я должен включать в себя больше.

Спасибо!

+0

Вид подобного, посмотрите: http://stackoverflow.com/a/22117161/3931910 – YakuZa

ответ

1

ViewHolder является внутренним классом DragItemAdapter (поскольку он не был объявлен static). Это означает, что каждый объект класса ViewHolder должен быть связан с объектом класса DragItemAdapter (на самом деле он должен быть подклассом DragItemAdapter). может думать о ViewHolder, имеющем скрытую переменную экземпляра, такую ​​как

DragItemAdapter __outerObject; 

ViewHolder может напрямую обращаться к переменным экземпляра и методам, принадлежащим __outerObject.

Это означает, что когда вы говорите new ViewHolder(...), для связи с ViewHolder вы должны иметь DragItemAdapter.

То же самое относится к любому подклассу ViewHolder, включая ViewHolderChecklist, так как подкласс наследует скрытую переменную __outerObject.

В первом примере, где ViewHolderChecklist находится внутри ChecklistAdapter, метод onCreateViewHolder всегда будет вызываться на ChecklistAdapter экземпляра. Когда этот метод говорит new ViewHolderChecklist, то новый объект __outerObject будет установлен в ChecklistAdapter. Кроме того, если внешний класс имеет ChecklistAdapter adapter;, он может использовать его для создания нового ViewHolderChecklist, указав adapter.new ViewHolderChecklist(...).

При перемещении ViewHolderChecklist вне класса, хотя, нет никакого способа для нового экземпляра будет создан, так как нет никакого способа, чтобы использовать new таким образом, что бы сказать ему, что его __outerObject должно быть. Синтаксис adapter.new ViewHolderChecklist(...) не будет работать, потому что этот синтаксис разрешен только для вложенных классов, а ViewHolderChecklist не является вложенным классом. Таким образом, ViewHolderChecklist должен быть вложенным классом внутри подкласса DragItemAdapter.

Исправление: На самом деле можно объявить ViewHolderChecklist следующим образом. Тем не менее, вы должны дать ему явный конструктор, и он должен иметь квалификационный вызов конструктора суперкласса (см. this; также см. Также https://stackoverflow.com/questions/40501642/what-rule-prohibits-this-nested-class-reference/40501815.

+0

Спасибо за подробное объяснение. Ваш вывод «должен быть вложенным классом» - это то, что доказывает его невозможность, и это экономит много времени на поиске решения. –

+0

Пожалуйста, см. Мою коррекцию, хотя, скорее всего, она включает в себя конструкцию вы не захотите использовать. – ajb

+0

Спасибо, я посмотрю на это. –

Смежные вопросы