dotnet/maui · error · InvalidOperationException
View for cell must implement INativeElementView to enable re
Error message
View for cell must implement INativeElementView to enable recycling.
What it means
Thrown by the legacy Android ListViewAdapter when ListViewCachingStrategy.RecycleElement is active and the recycled Android convertView cannot be cast to INativeElementView. Cell recycling on Android requires each native cell view to expose its backing Cell via the INativeElementView.Element property so the adapter can rebind data instead of inflating a new view. When the recycled view does not implement this interface, the adapter cannot safely reuse it and aborts.
Source
Thrown at src/Compatibility/Core.LegacyRenderers/Android/ListViewAdapter.cs:255
var cellIsBeingReused = false;
var layout = convertView as ConditionalFocusLayout;
if (layout != null)
{
cellIsBeingReused = true;
convertView = layout.GetChildAt(0);
}
else
{
layout = new ConditionalFocusLayout(_context) { Orientation = Orientation.Vertical };
_layoutsCreated.Add(layout);
}
if (((cachingStrategy & ListViewCachingStrategy.RecycleElement) != 0) && convertView != null)
{
var boxedCell = convertView as INativeElementView;
if (boxedCell == null)
{
throw new InvalidOperationException($"View for cell must implement {nameof(INativeElementView)} to enable recycling.");
}
cell = (Cell)boxedCell.Element;
ICellController cellController = cell;
cellController.SendDisappearing();
int row = position;
var group = 0;
var templatedItems = TemplatedItemsView.TemplatedItems;
if (_listView.IsGroupingEnabled)
group = templatedItems.GetGroupIndexFromGlobal(position, out row);
var templatedList = templatedItems.GetGroup(group);
if (_listView.IsGroupingEnabled)
{
if (row == 0)
templatedList.UpdateHeader(cell, group);View on GitHub (pinned to f377ff1c5e)
Solutions
- Switch the ListView to CachingStrategy=RetainElement (or omit the strategy) so views are not recycled and the cast is never attempted.
- Ensure any custom cell renderer returns a view that implements INativeElementView, or reuse/extend the built-in ViewCellContainer which already implements it.
- Migrate the ListView to CollectionView, which uses a modern adapter and does not depend on INativeElementView recycling contracts.
- If using a third-party cell renderer, verify it is compatible with RecycleElement; contact the vendor or wrap its output in an INativeElementView-implementing container.
Example fix
// before
var listView = new ListView(ListViewCachingStrategy.RecycleElement)
{
ItemTemplate = new DataTemplate(() => new MyCustomCell())
};
// after (option 1: disable recycling)
var listView = new ListView(ListViewCachingStrategy.RetainElement)
{
ItemTemplate = new DataTemplate(() => new MyCustomCell())
};
// after (option 2: make custom cell view implement INativeElementView)
class MyCellView : LinearLayout, INativeElementView
{
public Element Element => _cell;
} Defensive patterns
Strategy: validation
Validate before calling
// Before assigning a DataTemplate with a custom cell to a RecycleElement ListView,
// verify the cell's native view implements INativeElementView.
bool CanRecycleCell(Func<Cell> cellFactory)
{
var cell = cellFactory();
// For ViewCells the framework wraps in ViewCellContainer (INativeElementView);
// custom cells must implement it themselves.
var renderer = Platform.GetRenderer(cell.View);
return renderer?.View is INativeElementView;
} Type guard
static bool IsRecyclableCell(Cell cell)
{
if (cell is ViewCell vc && vc.View != null)
{
var r = Platform.GetRenderer(vc.View);
return r?.View is INativeElementView;
}
return false;
} Prevention
- Prefer CachingStrategy.RetainElement for custom cells unless you have verified INativeElementView support.
- Use the built-in ViewCellContainer-based cell hierarchy which already implements INativeElementView.
- Migrate to CollectionView which does not depend on the legacy recycling contract.
- Write an instrumented test that toggles RecycleElement and scrolls a large list with your custom cell to surface recycling errors early.
When it happens
Trigger: A ListView is created with CachingStrategy=RecycleElement and a DataTemplate whose cell produces a native view that does not implement INativeElementView. This happens with custom cell renderers that return a plain Android View, or when a third-party/legacy cell renderer bypasses the standard ViewCellContainer (which does implement INativeElementView). It can also surface after a Xamarin.Forms version upgrade that changed internal cell view types.
Common situations: Migrating an app from an old Xamarin.Forms version where a custom ViewCell renderer returned a raw ViewGroup. Mixing custom renderers that wrap but do not subclass the framework's cell container. Using RecycleElement with a custom cell type whose renderer was only ever tested under RetainElement.
Related errors
- ViewCell must have a {nameof(cell.View)}
- View for cell must implement INativeElementView to enable re
- ItemTemplate count has exceeded the limit of {ViewTypeCount}
- Element is not of type CheckBox
- Element is not of type ImageButton
AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13).
Data as JSON: /api/errors/831437c59ed367dc.
Report an issue: GitHub.