I built a custom ArrayAdapter to fill a Spinner.
public class CountryAdapter extends ArrayAdapter<CountryItem> {
public CountryAdapter(@NonNull Context context, ArrayList<CountryItem> countryList) {
super(context, 0, countryList);
}
@NonNull
@Override
public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
return initView(position, convertView, parent);
}
@Override
public View getDropDownView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
return initView(position, convertView, parent);
}
private View initView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(
R.layout.country_spinner_row, parent, false);
}
ImageView imageViewFlag = convertView.findViewById(R.id.image_view_flag);
TextView textViewName = convertView.findViewById(R.id.text_view_name);
CountryItem currentItem = getItem(position);
imageViewFlag.setImageResource(currentItem.getFlagImage());
textViewName.setText(currentItem.getCountryName());
return convertView;
}
}
the setImageResource
and setText
methods show me a NullPointer warning, but is this neglectable considering that i pass an ArrayList here anyways? In my opinion, this should also return an item for the given position.
The problem is here:
CountryItem currentItem = getItem(position);
getItem()
can return a null value. The below is the source code of the method and you will notice that it's annotated with @Nullable
.
@Override
public @Nullable T getItem(int position) {
return mObjects.get(position);
}
This means that when you call this method, you need to handle for null condition. I know that in normal operation you will never get null, and you can just ignore this warning. But the right way is to do a null check.
final CountryItem currentItem = getItem(position);
if (currentItem != null) {
imageViewFlag.setImageResource(currentItem.getFlagImage());
textViewName.setText(currentItem.getCountryName());
}