Подтвердить что ты не робот

Недоступен в текущем контексте

У меня есть следующий код

public abstract class BaseAdapter<T, V extends BaseAdapter.ViewHolder> extends ArrayAdapter<T> {
    public BaseAdapter(Context context, int resource, Collection<T> collection) {
        // typical constructor logic
    }

    // some other custom defined methods

    public static class ViewHolder {
        // custom defined logic
    }
}

public class ModelAdapter extends BaseAdapter<Model, ModelAdapter.ModelViewHolder> {
    public ModelAdapter(Context context, int resource, Collection<Model> collection) {
       super(context, resource, collection);
       // typical constructor logic
    }

    public static class ModelViewHolder extends ViewHolder {
        // custom defined logic
    }
}

BaseAdapter и ModelAdapter находятся в разделенных файлах. Проблема в том, что у меня есть ошибка компиляции при попытке определить ModelAdapter: ModelViewHolder недоступен в текущем контексте

Я действительно не понимаю эту ошибку и не могу понять, что я делаю неправильно. Может ли кто-нибудь объяснить мне эту проблему или ссылку, которая может прояснить эту ситуацию?

4b9b3361

Ответ 1

Создание мертвой блокировки

Вы используете ModelAdapter.ModelViewHolder как параметр шаблона BaseAdapter, и пусть ModelAdapter extends BaseAdapter, тогда компилятор попытался создать ModelViewHolder сначала, но класс ModelAdapter.ModelViewHolder (тип Класс) еще не создан. Он должен ждать создания ModelAdapter, потому что ModelViewHolder находится в области ModelAdapter.

Способ его решения помещает класс ModelViewHolder в новый *.java файл.

Ответ 2

Вот как это разрешилось для меня. Как правило, не должно быть проблемы с циклической зависимостью, поскольку классы вложенных зрителей являются статическими. Например. посмотрите на пресловутую иерархию LayoutParams, которая построена точно так же: класс наследует другой класс, а затем их статические вложенные классы имеют соответствующие отношения наследования.
Похоже, округлость возникает скорее из области видимости. ModelViewHolder может расширить ViewHolder только после того, как внешний ModelAdapter наследует область видимости BaseAdapter. Между тем ModelAdapter не может наследовать BaseAdapter до тех пор, пока класс ModelViewHolder не инициализируется, как это требуется для общего параметра. С другой стороны, ModelViewHolder является статическим вложенным классом и технически не зависит от его внешнего класса.

Таким образом, решение должно полностью квалифицировать имя ViewHolder при объявлении ModelViewHolder. Обратите внимание на часть extends BaseAdapter.ViewHolder в нижеприведенном фрагменте. Таким образом, ModelViewHolder не нужно использовать область ModelAdapter, чтобы знать о ViewHolder.

ModelAdapter.java

public class ModelAdapter extends BaseAdapter<Model, ModelAdapter.ModelViewHolder> {
    public ModelAdapter(Context context, int resource, Collection<Model> collection) {
        super(context, resource, collection);
        // typical constructor logic
    }

    public static class ModelViewHolder extends BaseAdapter.ViewHolder {
        // custom defined logic
    }
}

Заметка об Android Studio: несмотря на то, что сама проблема не связана с Android Studio, я столкнулся с ней с помощью функции AS "Copy class" (с использованием AS 3.0). При копировании он "упростил" код для меня, удалив полное имя. Итак, следите за умностью AS!

Ответ 3

Случилось то же самое при расширении базового класса. Но на этот раз я сделал это так (следуя приведенному примеру в вопросе)

BaseAdapter.java

public abstract class BaseAdapter<T, V extends BaseAdapter.ViewHolder> extends ArrayAdapter<T> {
    public BaseAdapter(Context context, int resource, Collection<T> collection) {
        // typical constructor logic
    }

    // some other custom defined methods

    public static class ViewHolder {
        // custom defined logic
    }
}

ModelAdapter.java

import com.mypackage.ModelAdapter.ModelViewHolder; ***//NOTE THIS IMPORT!!!***

public class ModelAdapter extends BaseAdapter<Model, ModelAdapter.ModelViewHolder> {
    public ModelAdapter(Context context, int resource, Collection<Model> collection) {
       super(context, resource, collection);
       // typical constructor logic
    }

    public static class ModelViewHolder extends ViewHolder {
        // custom defined logic
    }
}

Таким образом, предупреждение не прошло и не нужно было отделять ModelViewHolder в другом файле .java. Обратите внимание, что они находятся в двух разных файлах и импортировать в ModelAdapter.java.

Я думаю, что ответ Фэй Ляна частично неверен, потому что, поскольку статический ModelViewHolder должен сделать возможным инициализацию ModelViewHolder без инициализации родительского класса ModelAdapter

Ответ 4

Я столкнулся с этой проблемой раньше, я не уверен, почему это произошло,

но я разрешил его

создание класса the not-accessible inner class stand-alone (не внутреннего, что означает в отдельном файле)