Reputation: 390
How can I create a dashed line to use as a separator for my list view?
Example:
Upvotes: 0
Views: 2826
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
Reputation: 4164
You do it with SaskiSharp and a small custom view. This solution does not requires custom renderers.
Install the following nuget packages to your Xamarin Forms project
SkiaSharp
SkiaSharp.Views.Forms
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);
}
}
Use it in XAML
<views:DashedLineView
VerticalOptions="Center"
HorizontalOptions="Fill"
LineColor="#f60"
HeightRequest="10"
DashSize="30"
WhiteSize="50" />
Upvotes: 1
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:
I have uploaded the project on GitHub, you could download from ListViewDashedLinesDemo folder for reference. https://github.com/WendyZang/Test.git
Upvotes: 1
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