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

  1. Switch the ListView to CachingStrategy=RetainElement (or omit the strategy) so views are not recycled and the cast is never attempted.
  2. Ensure any custom cell renderer returns a view that implements INativeElementView, or reuse/extend the built-in ViewCellContainer which already implements it.
  3. Migrate the ListView to CollectionView, which uses a modern adapter and does not depend on INativeElementView recycling contracts.
  4. 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

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


AI-assisted analysis of dotnet/maui@f377ff1c5e (2026-08-13). Data as JSON: /api/errors/831437c59ed367dc. Report an issue: GitHub.