我有以下代码
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
我真的不明白这个错误,也无法弄清楚我做错了什么。有人可以向我解释这个问题或可能澄清这种情况的链接吗?
答案 0 :(得分:38)
创建死锁
您使用ModelAdapter.ModelViewHolder
作为BaseAdapter
的模板参数,让ModelAdapter
扩展BaseAdapter
,然后编译器首先尝试创建ModelViewHolder
,但是尚未创建ModelAdapter.ModelViewHolder
类(类型为类)。它必须等待ModelAdapter
被创建,因为ModelViewHolder
在ModelAdapter
的范围内。
解决问题的方法是将ModelViewHolder
类放入新的* .java文件中。
答案 1 :(得分:2)
以下是我如何解决这个问题。通常不应该存在循环依赖性问题,因为嵌套的视图持有者类是静态的。例如。查看臭名昭着的LayoutParams
层次结构,它的构建方式完全相同:一个类继承另一个类,然后它们的静态嵌套类具有相应的继承关系。
看起来循环来自可见范围问题。 ModelViewHolder
只有在外部ViewHolder
继承ModelAdapter
的可见范围后才能了解BaseAdapter
,ModelAdapter
可能会延长BaseAdapter
。同时,ModelViewHolder
无法继承ModelViewHolder
,直到初始化ViewHolder
类,因为它需要泛型参数。另一方面,ModelViewHolder
是一个静态嵌套类,在技术上并不依赖于它的外部类。
因此,解决方案是在声明extends BaseAdapter.ViewHolder
时完全限定ModelViewHolder
的名称。请注意下面代码段中的ModelAdapter
部分。这样,ViewHolder
无需使用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
}
}
的范围来了解{{1}}。
<强> ModelAdapter.java 强>
{{1}}
关于Android Studio的说明:尽管问题本身与Android Studio无关,但是我使用AS的“复制类”功能(使用AS 3.0)遇到了它。在复制时,它为我“简化”了代码,删除了完全限定的名称。所以,要注意AS的聪明才智!
答案 2 :(得分:0)
在扩展基类时发生了同样的事情。但是这次我有这样的想法(按照问题中给出的例子)
<强> 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中的 import 。
我认为Fei Liang的答案部分不正确,因为ModelViewHolder static应该可以在不初始化其父类ModelAdapter的情况下初始化ModelViewHolder
答案 3 :(得分:0)
之前我遇到过这个问题,我不确定为什么会这样,
但我通过
解决了这个问题制作
the not-accessible inner
类stand-alone
类(不是内部,意味着在单独的文件中)