安卓的列表视图。AdapterView.OnItemClickListener 中的参数化类型



我有一个ListView和一个假设的SquirrelAdapter。类似这样的东西:

public class SquirrelAdapter extends ArrayAdapter<Squirrel> {
    private LayoutInflater layoutInflater;
    private Context context;
    private int resource;
    public SquirrelAdapter (Context context, int resource, List<Squirrel> squirrels) {
        super(context, resource, squirrels);
        layoutInflater = LayoutInflater.from(context);
        this.context = context;
        this.resource = resource;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Squirrel squirrel = getItem( position );
        convertView = layoutInflater.inflate(resource, null);
        TextView squirrelNicknameTextView = (TextView) convertView.findViewById(R.id.squirrelNickname);
        squirrelNicknameTextView.setText( squirrel.getCuteNickname() );
        return convertView;
    }
}

所以在activity中,我可以这样做:

Squirrel[] squirrels = // Lot of Squirrels
SquirrelAdapter squirrelAdapter = new SquirrelAdapter(
    getApplicationContext(),
    R.layout.squirrel_layout,
    Arrays.asList( squirrels )
);
squirrelListView.setAdapter( squirrelAdapter );

所以我可以附加一个onItemClickListener:

squirrelListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        // Bad people cast a squirrel :|
        Squirrel squirrel = (Squirrel) parent.getItemAtPosition(position);
        Log.i("WWF", "Tapped squirrel " + squirrel.getCuteNickname());
    }
});

它真的很好用。但现在真正无聊的问题是:

如何在AdapterView<T extends Adapter>.setOnItemClickListener中使用Java的参数化类型?我在想下面这样的事情,但它给出了错误:

squirrelListView.setOnItemClickListener(new AdapterView<SquirrelAdapter>.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<SquirrelAdapter> parent, View view, int position, long id) {
        // Squirrels approved!
        Squirrel squirrel = parent.getItemAtPosition(position);
        Log.i("WWF", "Tapped squirrel " + squirrel.getCuteNickname());
    }
});

为什么我不能使用诸如"AdapterView<ArrayAdapter<T>>.OnItemClickListener"之类的语法?

为什么不存在这样的东西:<T> getItemPosition(int position)?它能实施吗?

谢谢你帮助我的松鼠不被铸造。

(更重要的是,我想了解更多关于这个Java功能的信息…(

如果您尝试new AdapterView<SquirrelAdapter>.OnItemClickListener()编译器,您可能会看到

The member type AdapterView<SquirrelAdapter>.OnItemClickListener cannot be qualified with a parameterized type, since it is static.

您在listView.setOnItemClickListener中所做的是为abstract class AdapterView中的interface OnItemClickListener创建一个Anonymous类。现在,要在abstract类中获得interface的引用,您只需要静态访问,例如AdapterView.OnItemClickListener,因此会出现如上所述的编译器错误。

即使您试图创建一个implementsOnItemClickListener的具体类,也只能静态访问,例如class MyImpl implements MyAbstract.MyInterface

如果您注意到AdapterView类的签名

abstract class AdapterView<T extends Adapter>

这表明AdapterView可以具有Adapter或其任何子类型作为其参数。但是为了获取Adapter所连接的元素(数据(,AdapterView使用

Object getItem(int position);

正如你在里面看到的:

public Object getItemAtPosition(int position) {
    T adapter = getAdapter();
    return (adapter == null || position < 0) ? null : adapter.getItem(position);
}

需要在onItemClick中铸造Squirrel。看看它是否有帮助!

最新更新