Fixed
Status Update
Comments
on...@onyxmueller.net <on...@onyxmueller.net> #2
[Comment deleted]
on...@onyxmueller.net <on...@onyxmueller.net> #3
I've stumbled across this same issue, but in a different form. When using a shape drawable with a stroke declaration for creating a dashed line, ICS renders a solid line. Here's an example of the drawable:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android " android:shape="line">
<stroke
android:color="@android:color/white"
android:dashGap="5dp"
android:dashWidth="5dp"/>
</shape>
To work around this, I disabled hardware acceleration for the view using the drawable. You can do this in both code and XML.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="
<stroke
android:color="@android:color/white"
android:dashGap="5dp"
android:dashWidth="5dp"/>
</shape>
To work around this, I disabled hardware acceleration for the view using the drawable. You can do this in both code and XML.
sw...@gmail.com <sw...@gmail.com> #4
[Comment deleted]
du...@gmail.com <du...@gmail.com> #5
I've seen the same problem on ICS (4.0.4) Target SDK 15
zo...@gmail.com <zo...@gmail.com> #6
I am seeing a similar problem where I am able to draw a dotted line on an EVO with gingerbread, but not able to draw dotted line on a nexus S with ICS.
In my case setting hardwareAccelerated="false" or "true" makes no difference.
In my case setting hardwareAccelerated="false" or "true" makes no difference.
pr...@gmail.com <pr...@gmail.com> #7
Turning of hardware acceleration for the view worked for me.
public static void disableHardwareRendering(View v) {
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
v.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
}
public static void disableHardwareRendering(View v) {
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
v.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
}
dj...@gmail.com <dj...@gmail.com> #8
I have the problem too. Meizu MX 4 core, android 4.0.3.
When android:hardwareAccelerated="true", it cannot draw dotted line.
When android:hardwareAccelerated="true", it cannot draw dotted line.
zo...@gmail.com <zo...@gmail.com> #9
yep using View.setLayerType(View.LAYER_TYPE_SOFTWARE, null) worked for me.
hy...@donarproject.org <hy...@donarproject.org> #10
You can still use hardware acceleration for drawing dashed lines. Instead of using canvas.drawLine() use canvas.drawPath(). Works on Galaxy nexus 4.1.1 and Asus tf700t 4.0.3.
st...@gmail.com <st...@gmail.com> #11
Bug still present on 4.2
da...@gmail.com <da...@gmail.com> #12
drawPath works fine for me, but drawLine not. Thx for help
ro...@android.com <ro...@android.com>
br...@gmail.com <br...@gmail.com> #13
yep,#6 works for me.
ji...@gmail.com <ji...@gmail.com> #14
I did have a similar problem over here, I was developping a chart and tests on Emulator works just fine with dotted lines but on a Samsung Galaxyy Note2 and a Nexus S not, so my code to get this adressed was:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View myView = new MyView(this);
setContentView(myView);
.....
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
....
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View myView = new MyView(this);
setContentView(myView);
.....
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
....
}
no...@gmail.com <no...@gmail.com> #15
This is still an issue on JB. Disabling hw acceleration "fixes" it.
os...@gmail.com <os...@gmail.com> #16
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) {
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
worked for me, thanks!
myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
worked for me, thanks!
go...@umito.nl <go...@umito.nl> #17
Could somebody point me in the direction of a working implementation using drawPath?
Will this manually require me to calculate distances of dots and create a path with lines and gaps? Cause just using a path with a line, and using the same paint with the DashPathEffect has no effect.
Will this manually require me to calculate distances of dots and create a path with lines and gaps? Cause just using a path with a line, and using the same paint with the DashPathEffect has no effect.
go...@umito.nl <go...@umito.nl> #18
[Comment deleted]
go...@umito.nl <go...@umito.nl> #19
Never mind, I had stroketype wrong.
Solution:
dotPaint.setPathEffect(new DashPathEffect(new float[]{dotLength,dotLength},0));
dotPaint.setStyle(Style.STROKE); //Important!
Path path = new Path();
path.moveTo(startXY[0], startXY[1]);
path.lineTo(endXY[0], endXY[1]);
canvas.drawPath(path, dotPaint);
Tested on 2.3 and 4.2
Solution:
dotPaint.setPathEffect(new DashPathEffect(new float[]{dotLength,dotLength},0));
dotPaint.setStyle(Style.STROKE); //Important!
Path path = new Path();
path.moveTo(startXY[0], startXY[1]);
path.lineTo(endXY[0], endXY[1]);
canvas.drawPath(path, dotPaint);
Tested on 2.3 and 4.2
ou...@gmail.com <ou...@gmail.com> #20
setLayerType(View.LAYER_TYPE_SOFTWARE, null); worked for me on 4.0.3
bi...@gmail.com <bi...@gmail.com> #21
if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB)
{
v.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
This is not working for me in Galaxy Nexus 4.2.1, Whole view is not drawn.
{
v.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
}
This is not working for me in Galaxy Nexus 4.2.1, Whole view is not drawn.
fg...@gmail.com <fg...@gmail.com> #22
Not fixed yet on Android 5.0.1 -_____-. I had a view in my XML with a dashed line (shape drawable) and I had to android:layerType="software" to it, otherwise it will be drawn as solid line.
al...@gmail.com <al...@gmail.com> #23
Still not working for 5.1. Impressive!
su...@impigertech.com <su...@impigertech.com> #24
Solution:
dotPaint.setPathEffect(new DashPathEffect(new float[]{dotLength,dotLength},0));
dotPaint.setStyle(Style.STROKE); //Important!
Path path = new Path();
path.moveTo(startXY[0], startXY[1]);
path.lineTo(endXY[0], endXY[1]);
canvas.drawPath(path, dotPaint);
This fixes the problem, but performance is too slow.
dotPaint.setPathEffect(new DashPathEffect(new float[]{dotLength,dotLength},0));
dotPaint.setStyle(Style.STROKE); //Important!
Path path = new Path();
path.moveTo(startXY[0], startXY[1]);
path.lineTo(endXY[0], endXY[1]);
canvas.drawPath(path, dotPaint);
This fixes the problem, but performance is too slow.
ku...@gmail.com <ku...@gmail.com> #25
Verified still broken on MNC Preview
ka...@gmail.com <ka...@gmail.com> #26
Hi, draw solid line use this code. Its working all version of android
mPaint.setPathEffect(null);
mPaint.setPathEffect(null);
cc...@android.com <cc...@android.com> #27
Dashed lines/path effects aren't currently supported when drawing HW accelerated lines. See https://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported
A few different options to work around this:
A) Drawing a path, like what's suggested in #20. Note though that alterations to the path (such as resetting, or adding new lines) may be expensive if the path is large.
B) Using a software layer, as suggested in #21. Note though that updating the view content can be expensive, since it's being drawn by the CPU, and uploaded to the GPU each frame that it is changed. Additionally, if the view is too large to be uploaded to the GPU (See Canvas#getMaximumBitmapHeight() / getMaximumBitmapWidth()), it will not be drawn.
C) generating the dashes manually using drawLines, with a line for each dash.
A few different options to work around this:
A) Drawing a path, like what's suggested in #20. Note though that alterations to the path (such as resetting, or adding new lines) may be expensive if the path is large.
B) Using a software layer, as suggested in #21. Note though that updating the view content can be expensive, since it's being drawn by the CPU, and uploaded to the GPU each frame that it is changed. Additionally, if the view is too large to be uploaded to the GPU (See Canvas#getMaximumBitmapHeight() / getMaximumBitmapWidth()), it will not be drawn.
C) generating the dashes manually using drawLines, with a line for each dash.
ku...@gmail.com <ku...@gmail.com> #28
In some cases you can try to use rectangle shape with negative bottom inside of layer list instead of line:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android ">
<item android:bottom="-10dp">
<shape
android:shape="rectangle">
<stroke
android:width="1dp"
android:color="@color/dull_gray"
android:dashGap="3dp"
android:dashWidth="5dp" />
</shape>
</item>
</layer-list>
<ImageView
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@drawable/bg_request_section_horizontal_divider" />
<layer-list xmlns:android="
<item android:bottom="-10dp">
<shape
android:shape="rectangle">
<stroke
android:width="1dp"
android:color="@color/dull_gray"
android:dashGap="3dp"
android:dashWidth="5dp" />
</shape>
</item>
</layer-list>
<ImageView
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@drawable/bg_request_section_horizontal_divider" />
ce...@gmail.com <ce...@gmail.com> #29
+1 here. Having the same problem trying to draw dotted background in a renderer of a recyclerview, I get the line solid. Solved using myView.setLayerType(View.LAYER_TYPE_SOFTWARE, null); in the renderer of the wanted view
<rotate xmlns:android="http://schemas.android.com/apk/res/android "
android:fromDegrees="90"
android:toDegrees="90">
<shape
android:shape="line">
<stroke
android:width="@dimen/dotted_line_dot_size"
android:color="@color/white_transparent_40"
android:dashGap="@dimen/dotted_line_dot_separation"
android:dashWidth="@dimen/dotted_line_dot_size" />
</shape>
</rotate>
<rotate xmlns:android="
android:fromDegrees="90"
android:toDegrees="90">
<shape
android:shape="line">
<stroke
android:width="@dimen/dotted_line_dot_size"
android:color="@color/white_transparent_40"
android:dashGap="@dimen/dotted_line_dot_separation"
android:dashWidth="@dimen/dotted_line_dot_size" />
</shape>
</rotate>
va...@gmail.com <va...@gmail.com> #30
Also seeing this on Marshmallow.
[Deleted User] <[Deleted User]> #31
And Lollipop, and Nougat. Can't believe this has not been fixed yet. What gives?
ku...@google.com <ku...@google.com>
xp...@gmail.com <xp...@gmail.com> #32
Oreo now, not fixed ((
jr...@google.com <jr...@google.com> #33
setPathEffect for lines is documented as being unsupported in HW acceleration: https://developer.android.com/guide/topics/graphics/hardware-accel.html#unsupported
If you must have dashed lines you can use software rendering as a workaround at a performance cost, but the recommendation would be to avoid dashed lines. They are relatively slow to draw and unfriendly to GPU acceleration, which is so far why this hasn't been added.
If you must have dashed lines you can use software rendering as a workaround at a performance cost, but the recommendation would be to avoid dashed lines. They are relatively slow to draw and unfriendly to GPU acceleration, which is so far why this hasn't been added.
ku...@google.com <ku...@google.com> #34
Is there a way we can raise this at compile or runtime so that users know why it is not showing up as expected?
jr...@google.com <jr...@google.com> #35
Since it's an option set on Paint that only doesn't work when passed to a Canvas method when the Canvas has isHardwareAccelerated() as true checking this at compile time is non-trivial, if it's possible at all. We wouldn't be able to easily distinguish between draws to other Canvas types.
We could certainly throw an exception at runtime, but that would be a breaking compatibility change that would be behind a targetSdkVersion check. My belief would be that end-users would rather have an app with solid lines instead of an app that crashes, and it's easy to miss things so I'd be leery of that change at this point in time given the behavior is many years old now.
We could certainly throw an exception at runtime, but that would be a breaking compatibility change that would be behind a targetSdkVersion check. My belief would be that end-users would rather have an app with solid lines instead of an app that crashes, and it's easy to miss things so I'd be leery of that change at this point in time given the behavior is many years old now.
cg...@gmail.com <cg...@gmail.com> #36
Dashed lines have been a standard part of graphics API's for a very long time, because they are appropriate for applications such as scientific graphing etc., and solid lines are not a visual substitute. Having coded accelerated dotted line algorithms in the past, I'm a bit perplexed as to why they can't be GPU accelerated - don't GPU's support pattern masks ?
But instead of silently drawing solid lines, how about automatically falling back to the software rendering ?
But instead of silently drawing solid lines, how about automatically falling back to the software rendering ?
jr...@google.com <jr...@google.com> #37
Added to P (give the P DP1 a try if you haven't yet!)
jr...@google.com <jr...@google.com> #38
Re #36: If you just want a basic pattern mask you can do that with a BitmapShader, like so:
override fun onDraw(canvas: Canvas) {
val p = Paint()
p.shader = createDashShader(Color.BLUE)
p.strokeWidth = 10F
canvas.drawLine(0F, 300F, 500F, 300F, p)
}
fun createDashShader(@ColorInt color: Int): Shader {
val p = Paint()
p.style = Paint.Style.FILL_AND_STROKE
p.strokeWidth = 1F
p.color = color
p.pathEffect = DashPathEffect(floatArrayOf(20f, 20f), 0f)
var mask = Bitmap.createBitmap(40, 1, Bitmap.Config.ARGB_8888);
var canvas = Canvas(mask)
canvas.drawLine(0F, 0F, 40F, 0F, p)
canvas.setBitmap(null)
return BitmapShader(mask, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT)
}
override fun onDraw(canvas: Canvas) {
val p = Paint()
p.shader = createDashShader(Color.BLUE)
p.strokeWidth = 10F
canvas.drawLine(0F, 300F, 500F, 300F, p)
}
fun createDashShader(@ColorInt color: Int): Shader {
val p = Paint()
p.style = Paint.Style.FILL_AND_STROKE
p.strokeWidth = 1F
p.color = color
p.pathEffect = DashPathEffect(floatArrayOf(20f, 20f), 0f)
var mask = Bitmap.createBitmap(40, 1, Bitmap.Config.ARGB_8888);
var canvas = Canvas(mask)
canvas.drawLine(0F, 0F, 40F, 0F, p)
canvas.setBitmap(null)
return BitmapShader(mask, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT)
}
da...@gmail.com <da...@gmail.com> #39
What breathtaking arrogance. Fixed! It's not fixed, it's been "disinvented". As others have said this feature is important in various applications to distinguish between lines on graphs and diagrams. As usual with Android the hardware acceleration was added by ignoring backwards compatibility (unless it was simply badly implemented) and then later, much later, after countless developers have stumbled into the error the documentation was mangled to explain the problem. If the error is now "fixed" it was "fixed" years ago because you've not changed anything for many years. One wonders whether you get performance bonuses for "fixing" bugs and have worked out that this is an easier option than actually doing something about the problem.
wo...@gmail.com <wo...@gmail.com> #40
I don't see what's arrogance here. What action do you expect to be taken here?
If I understand correctly, the DashPathEffect works without hardware acceleration now on Android P.
I mean it's great news: Add a (if(Build.SDK....) check and the performance overhead is gone for devices running P and above.
If I understand correctly, the DashPathEffect works without hardware acceleration now on Android P.
I mean it's great news: Add a (if(Build.SDK....) check and the performance overhead is gone for devices running P and above.
sh...@gmail.com <sh...@gmail.com> #41
Having the same issue when using Jetpack Compose on Android 8 AVD emulator, trying to draw dashed line but it becomes straight instead, disabling hardware acceleration helps but makes app less smooth, Android 12 and 13 don't have this issue. From discussion above looks like it won't be fixed for older Android versions. It causes unexpected bugs for many developers and for sure has to be mentioned in documentation when using PathEffect.dashPathEffect
, I think even OptIn lint annotation is necessary
Description
Flipping the manifest's hardwareAccelerated flag in the application tag causes this to work:
hardwareAccelerated="false" ---> dotted line
hardwareAccelerated="true" ---> solid line
Sample code:
AndroidManifest.xml:
<application
android:hardwareAccelerated="true"
android:icon="@drawable/ic_launcher"
TestView.java
protected void onDraw(Canvas canvas) {
Paint p = new Paint();
p.setStyle(Paint.Style.FILL_AND_STROKE);
p.setStrokeWidth(10);
p.setColor(Color.RED);
p.setPathEffect(new DashPathEffect(new float[] {20, 20}, 0));
canvas.drawLine(0, 300, 500, 300, p);
}
I've tried this on two different ICS devices and also a production Galaxy Tab 8.9 (running 3.2).