Pedro Paulo
Pedro Paulo

Reputation: 390

Create dashed line in ListView Xamarin Forms

How can I create a dashed line to use as a separator for my list view?

Example:

enter image description here

Upvotes: 0

Views: 2826

Answers (4)

Pavlo Datsiuk
Pavlo Datsiuk

Reputation: 1118

Xamarin.Forms.Forms.SetFlags(new string[] { "Brush_Experimental", "Shapes_Experimental" });
                     
<Line Grid.Row="0"
      Grid.ColumnSpan="2"
      X2="10"
      Stroke="Red"
      StrokeThickness="0.8" 
      StrokeDashArray="1,8"
      Aspect="UniformToFill"
      HorizontalOptions="FillAndExpand"
      VerticalOptions="End"/>

Upvotes: 0

Luca Ziegler
Luca Ziegler

Reputation: 4164

You do it with SaskiSharp and a small custom view. This solution does not requires custom renderers.

  1. Install the following nuget packages to your Xamarin Forms project

    SkiaSharp
    SkiaSharp.Views.Forms
    
  2. Create a ContentView

    public class DashedLineView : ContentView
    {
        public Color LineColor
        {
           get; set;
        } = Color.Black;
    
        public float DashSize
        {
           get; set;
        } = 20;
    
        public float WhiteSize
        {
           get; set;
        } = 20;
    
        public float Phase
        {
           get; set;
        } = 0;
    
        public DashedLineView()
        {
           Content = new SKCanvasView();
           ((SKCanvasView)Content).PaintSurface += Canvas_PaintSurface;
        }
    
        private void Canvas_PaintSurface(object sender, SKPaintSurfaceEventArgs args)
        {
           SKImageInfo info = args.Info;
           SKSurface surface = args.Surface;
           SKCanvas canvas = surface.Canvas;
    
           canvas.Clear();
    
           SKPaint paint = new SKPaint
           {
              Style = SKPaintStyle.Stroke,
              Color = LineColor.ToSKColor(),
              StrokeWidth = HeightRequest > 0 ? (float)HeightRequest : (float)WidthRequest,
              StrokeCap = SKStrokeCap.Butt,
              PathEffect = SKPathEffect.CreateDash(new float[] { DashSize, WhiteSize }, Phase)
           };
    
           SKPath path = new SKPath();
           if (HeightRequest > 0)
           {
              // Horizontal
              path.MoveTo(0, 0);
              path.LineTo(info.Width, 0);
           }
           else
           {
              // Vertikal
              path.MoveTo(0, 0);
              path.LineTo(0, info.Height);
           }
    
           canvas.DrawPath(path, paint);
        }
     }
    
  3. Use it in XAML

    <views:DashedLineView
            VerticalOptions="Center"
            HorizontalOptions="Fill"
            LineColor="#f60"
            HeightRequest="10"
            DashSize="30"
            WhiteSize="50" />
    

Upvotes: 1

Wendy Zang - MSFT
Wendy Zang - MSFT

Reputation: 10978

You could do this in custom renderer of listview.

MyListViewRenderer.cs:

public class MyListViewRenderer : ListViewRenderer
{
    Context ctx;
    public MyListViewRenderer(Context context) : base(context)
    {
        ctx = context;
    }
    protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.ListView> e)
    {
        base.OnElementChanged(e);
        if (Control != null)
        {
            //var listView = Control as Android.Widget.ListView;
            Drawable drawable = Resources.GetDrawable(Resource.Drawable.DashedLines);               

            Control.DividerHeight = 20;
            Control.Divider = drawable;
            Control.SetLayerType(LayerType.Software,null);
        }
    }
}

Xaml:

<ContentPage.Content>
    <local:MyListView SeparatorVisibility="None">
        <local:MyListView.ItemsSource>
            <x:Array Type="{x:Type x:String}">
                <x:String>mono</x:String>
                <x:String>monodroid</x:String>
                <x:String>monotouch</x:String>
                <x:String>monorail</x:String>
                <x:String>monodevelop</x:String>
                <x:String>monotone</x:String>
               <x:String>monopoly</x:String>
                <x:String>monomodal</x:String>
                <x:String>mononucleosis</x:String>
            </x:Array>
        </local:MyListView.ItemsSource>
    </local:MyListView>

Result:

enter image description here

I have uploaded the project on GitHub, you could download from ListViewDashedLinesDemo folder for reference. https://github.com/WendyZang/Test.git

Upvotes: 1

Ganesan VG
Ganesan VG

Reputation: 176

You can achieve through renderer like below,

// PCL
public class BoxViewExt : BoxView
{

}

// Android
public class BoxViewExtRenderer : BoxRenderer
{
    public BoxViewExtRenderer(Context context) : base(context)
    {
    }

    protected override void OnDraw(Canvas canvas)
    {
        base.OnDraw(canvas);

        var paint = new Paint { StrokeWidth = 2, AntiAlias = true };
        paint.SetStyle(Paint.Style.Stroke);
        paint.SetPathEffect(new DashPathEffect(new[] { 6 * this.Context.Resources.DisplayMetrics.Density, 2 * this.Context.Resources.DisplayMetrics.Density }, 0));

        var p = new Path();
        p.LineTo(canvas.Width, 0);
        canvas.DrawPath(p, paint);
    }
}

Upvotes: 1

Related Questions