Search code examples
listviewxamarin.androidxamarin.formsdatatemplatedivider

Xamarin forms Android - Create Custom ListView divider from DataTemplate (Convert DataTemplate into Drawable)


I am implementing a renderer for android ListView and i want to control the divider appearance. Therefore, i created a DataTemplate.

the problem is e.NewElement.SeperatorTemplate.CreateContent() returns View object.

and listView.Divider accepts Drawable object.

I need the conversion to be efficient so save it as an image is out of the question. Any ideas?


Solution

  • Found a solution using view's drawing cache:

                //Convert Android view into Drawable
    
                view.DrawingCacheEnabled = true;
                view.Layout(0, 0, (int)Math.Round(request.Request.Width * Density), (int)Math.Round(request.Request.Height * Density));                  
                view.BuildDrawingCache(true);
                var bitmap = Bitmap.CreateBitmap(view.GetDrawingCache(true));
                view.DrawingCacheEnabled = false;
                Drawable drawable = new BitmapDrawable(bitmap);
    

    Full code:

                //Get Xamarin forms view from DataTemplate
                Xamarin.Forms.View divider = (Xamarin.Forms.View)(e.NewElement.SeperatorTemplate?.CreateContent());
                if (divider != null)
                {
                    //get renderer
                    var dividerRenderer = Platform.CreateRenderer(divider);
    
                    //Measuring the element
                    SizeRequest request = dividerRenderer.Element.Measure(double.PositiveInfinity, double.PositiveInfinity);
    
                    //Measuring element Chilren
                    Xamarin.Forms.Layout.LayoutChildIntoBoundingRegion(dividerRenderer.Element, new Rectangle(0.0, 0.0, request.Request.Width, request.Request.Height));
    
                    ViewGroup view = dividerRenderer.ViewGroup; 
    
                    //Convert Android view into Drawable
                    view.DrawingCacheEnabled = true;
                    view.Layout(0, 0, (int)Math.Round(request.Request.Width * Density), (int)Math.Round(request.Request.Height * Density));    
                    view.BuildDrawingCache(true);
                    var bitmap = Bitmap.CreateBitmap(view.GetDrawingCache(true));
                    view.DrawingCacheEnabled = false;
    
                    //Set divider Drawable divider to native list divider
                    listView.Divider = new BitmapDrawable(bitmap);
                    listView.DividerHeight = (int)Math.Round(request.Request.Height * Density);
                }