I'm having some trouble understanding how scope is affecting my code. I can't seem to access the public attributes of a public class.
I created a custom class ArtistPacket
which has a block of information I would like to send to my custom adapter (ArtistListAdapter
).
The custom class is below:
public class ArtistPacket{
public String name;
public int id;
public ArtistPacket(String name, int id){
this.name = name;
this.id = id;
}
}
It is defined in MainActivityFragment
, where I create an ArtistListAdapter
which takes these ArtistPackets
.
public class MainActivityFragment extends Fragment{
...
ArtistListAdapter<ArtistPacket> artistListAdapter =
new ArtistListAdapter<ArtistPacket>(getActivity(), artistData);
...
I then define the ArtistListAdapter
and getView
private class ArtistListAdapter<ArtistPacket> extends ArrayAdapter<ArtistPacket>{
public ArtistListAdapter(Context context,ArrayList<ArtistPacket> artists){
super(getActivity(),0,artists);
}
@Override
public View getView(int position, View view, ViewGroup parent) {
...
In the getView
, I need the name
and id
from the ArtistPacket
object (in this case artist
). So I try calling
ArtistPacket artist = getItem(position);
textItemContent.setText((CharSequence) artist.name);
But I get a compile error. In the debugger, it appears as if the full object is coming through - it just doesn't seem like the Adapter access the name
or id
attribute.
The error I get is:
Error:(98, 58) error: cannot find symbol variable name
where ArtistPacket is a type-variable:
ArtistPacket extends Object declared in class
MainActivityFragment.ArtistListAdapter
Is there an issue with scope in my implementation? Why would the Adapter not be able to see the contents of the ArtistPacket
object if it is plainly seen in the debugger?
Here's the full getView:
@Override
public View getView(int position, View view, ViewGroup parent) {
// Find the artist packet at a given position
ArtistPacket artist = getItem(position);
if (view == null) {
view = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
}
TextView textItemContent = (TextView) view.findViewById(R.id.list_item_content);
ImageView imageViewContent = (ImageView) view.findViewById(R.id.list_item_image);
textItemContent.setText((CharSequence) artist.name);
imageViewContent.setImageResource(artist.id);
return view;
}
Subtle yet important answer to this.
The following class definition:
private class ArtistListAdapter<ArtistPacket> extends ArrayAdapter<ArtistPacket>
can be broken up to be better understood.
ArtistListAdapter<ArtistPacket>
Implies that the ArtistListAdapter
is defining the type argument as ArtistPacket
. This means that anytime ArtistPacket is referenced, it is referencing this type declaration - not the class defined above.
On the other hand,
extends ArrayAdapter<ArtistPacket>
Implies that the ArtistListAdapter
extends an ArrayAdapter
which uses the aforementioned ArtistPacket class.
In other words, the first <> is about defined types, while the second <> is about used types.
Thus, I used the following declaration:
private class ArtistListAdapter extends ArrayAdapter<ArtistPacket>
Which implies the ArrayAdapter
will be extending the ArtistListAdapter
using the type ArtistPacket
- without confusing the situation by defining it's own, local, ArtistPacket type.