I'm developing with Xamarain Android on C# targeted at KitKat (4.4 - API19).
Setting
So I have this list of vehicles I wanted to render using the GridView. As this is within some tabbing the GridView is contained within a fragment to be created when first clicking on the corresponding tab (code not shown here). That works fine, the problem arises when the GarageFragmentAdapter starts to getting Views. I made sure the fragment and adapter are only created once, so it is not an issue of multiple instances colliding with their works. I haven't attached any bells or whistles (scrolling reaction or item reaction) at the moment its just about the rendering.
Problem
In my example, I have 4 vehicles, so my list is 4 items long. The first call to the adapter uses position 0 (ok), the second call also uses position 0 (NOT ok) and then there is only a third call which uses position 1 (definitely not ok) and no fourth call. The visual output is then only two items being shown which is also not what I'd expect but I reckon the GridView uses the position to render an item AT position x.
So my question would be, how to I convince the adapter to correctly iterate through my data list?
Code
The code as seen below is the latest iteration, beforehand the adapter was set within the fragment, which I thought was the problem due to reading somewhere this can be an issue.
public class GarageFragment : Fragment
{
private readonly VehiclesResponse _garageResponse;
private readonly GarageFragmentAdapter _adapter;
public GarageFragment(VehiclesResponse garageResponse, GarageFragmentAdapter adapter)
{
_garageResponse = garageResponse;
_adapter = adapter;
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var fragmentView = inflater.Inflate(Resource.Layout.fragment_garage, container, false);
fragmentView.FindViewById<GridView>(Resource.Id.gridVehicleCards).Adapter = _adapter;
fragmentView.FindViewById<Button>(Resource.Id.btnShowFullGarage).Visibility = _garageResponse.TotalCarsInGarageCount > 4 ? ViewStates.Visible : ViewStates.Gone;
fragmentView.FindViewById<LinearLayout>(Resource.Id.boxAddVehicles).Visibility = _garageResponse.CanAddVehicles ? ViewStates.Visible : ViewStates.Gone;
return fragmentView;
}
}
public class GarageFragmentAdapter : BaseAdapter
{
private readonly Activity _context;
private readonly IList<Vehicle> _tileList;
public GarageFragmentAdapter(Activity context, IList<Vehicle> vehicles)
{
_context = context;
_tileList = vehicles;
}
public override int Count => _tileList.Count;
public override Object GetItem(int position)
{
return null;
}
public override long GetItemId(int position)
{
return position;
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var view = convertView;
if (view == null)
{
var item = _tileList[position];
view = _context.LayoutInflater.Inflate(Resource.Layout.BasicVehicleCard, null);
view.FindViewById<TextView>(Resource.Id.vehicleName).Text = item.Name;
}
return view;
}
}
It appears GridView does not work as I would expect. It does not grow along with the provided content, it defines how much content it will show / load depending on the space it has. (something which would have been nice to be stated in the documentation of the GridView)
As this is not feasible for my requirement I will instead use GridLayout and add the content element views therein.