View Android list. Parameterized type in AdapterView.OnItemClickListener
I have ListView
a hypothetical one SquirrelAdapter
. Something like that:
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;
}
}
So, in activity
I can do this:
Squirrel[] squirrels = // Lot of Squirrels
SquirrelAdapter squirrelAdapter = new SquirrelAdapter(
getApplicationContext(),
R.layout.squirrel_layout,
Arrays.asList( squirrels )
);
squirrelListView.setAdapter( squirrelAdapter );
And so I can add 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());
}
});
It works really well. But now for a really boring question:
How can I use a Java parameterized type in AdapterView<T extends Adapter>.setOnItemClickListener
? I think something like below, but it gives errors:
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 don't I have a syntax like "
AdapterView<ArrayAdapter<T>>.OnItemClickListener
"?Why doesn't this happen
<T> getItemPosition(int position)
:? Can it be implemented?
Thank you my squirrels won't be thrown.
(More seriously, I want to know more about this Java feature ...)
source to share
As you may have noticed, if you try new AdapterView<SquirrelAdapter>.OnItemClickListener()
, the compiler will say:
The member type AdapterView<SquirrelAdapter>.OnItemClickListener cannot be qualified with a parameterized type, since it is static.
What you do inside listView.setOnItemClickListener
is create a class Anonymous
for interface OnItemClickListener
inside abstract class AdapterView
. Now, in order to get a reference interface
inside a class abstract
, you only need to access statically, for example, AdapterView.OnItemClickListener
and hence the compiler error as stated above.
Even if you try to create a specific class that implements
OnItemClickListener
you only need to access statically, likeclass MyImpl implements MyAbstract.MyInterface
If you notice the AdapterView
class signature
abstract class AdapterView<T extends Adapter>
which indicates AdapterView
can have Adapter
or any subtype of this parameter as its parameter. But to get items (data) Adapter
connected, AdapterView
uses
Object getItem(int position);
As you could see inside:
public Object getItemAtPosition(int position) {
T adapter = getAdapter();
return (adapter == null || position < 0) ? null : adapter.getItem(position);
}
Casting your Squirrel
inside is required onItemClick
. See if this helps!
source to share