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

Android's List View. Parameterized type in 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());
    }
});

Why can't I have syntax such as "AdapterView<ArrayAdapter<T>>.OnItemClickListener"?

Why doesn't something like this exist: <T> getItemPosition(int position)? Can it be implemented?

感谢帮助我的松鼠不被施放。

(说真的,我想更多地了解这个 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 class。现在,要在 abstract class 中获取 interface 的引用,您只需要静态访问,例如 AdapterView.OnItemClickListener,因此会出现上述编译器错误。

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

如果您注意到 AdapterView class

的签名
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);
}

需要将您的 Squirrel 转换为 onItemClick。看看有没有帮助!