So this is a weird thing I want to do that would look amazing in my app, but for the life of me cannot figure out how.
Let's say I have a background on my screen like so:
I then add a view to it that can have any number of subviews/content. This view naturally obscures the background:
So far so good. Now comes the tricky part. I want to implement something that will allow me to "see through" part of this view. Essentially it will make the view appear invisible but only in one specific area. Here is what it would look like:
I have not found any way to do this so far.
You could use the Bitmap Masking technique to accomplish what you want. Something like the below in your onDraw() method.
Paint paint = new Paint();
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
setLayerType(LAYER_TYPE_HARDWARE,paint); // if hardware acceleration is on
// canvas.saveLayer(0, 0, canvas.getWidth(), canvas.getHeight(), paint); // Use this if hardware acceleration is off.
canvas.drawRect(200, 200, 400, 400, paint); // This will be HOLE in the VIEW
For more info read this: https://stackoverflow.com/a/33483016/4747587
Henry mentioned a good solution. Another easy solution is often to just use a PNG-drawable or a 9-patch-drawable. If the area of your overlay is always the same the PNG gives you full flexibility in what you want to have as transparent and the rest stays as you define it. You can scale the PNG or - if you want only specific areas to scale, use a 9-patch-drawable.
Related
As I am a beginner of Android developement, I need someone to give me an answer or any comments on my question.
When I draw a simple rectangle on a view with the following code, the rectangle doesn't show in the way in which I would expect.
canvas.drawLine(0, 0, getWidth(), getHeight(), framePaint);
wrong
But when I changed it like this, it shows properly.
canvas.drawRect(1, 0, getWidth(), getHeight()-1, framePaint);
Correct
That looks like the left and the bottom lines are clipped out of the view.
I was expecting that the position of view starts zero-indexed such as 0 ~ (size of view)-1. Do I understand wrong or did i do something wrong?
The framePaint is configured like this;
framePaint = new Paint();
framePaint.setColor(Color.rgb(255,0,0));
framePaint.setStrokeWidth(1);
framePaint.setStyle(Paint.Style.STROKE);
Here's what happens:
When you subtract one from the total pixels, it draws the line(s) in the image, not outside of it.
Also the "1" at the start also helps the code stay in the canvas.
You may want to try replacing the 1's in the code with 2's, as the canvas uses an extra pixel to automatically remove "aliasing".
let's get straight to the point, I was making an android game and I decided to try and use some more android methods like Rect and Path so I can experiment and learn how they work. (in the past I used only bitmaps to draw graphics)
As I was making the game I noticed some weird coloring on my rects, so I tried a lot of things, I made sure my rects are initialized properly and I also tried to simplify my code to make sure the problem was caused there.
For debug purposes my code draws a white square on the top left side of the screen, a black on the top right, and a gray one on the bottom, this is the code:
Paint pGray, pWhite, pBlack;
public myClass()
{
paintGray = new Paint();
paintGray.setARGB(255, 125, 125, 125);
paintWhite = new Paint();
paintWhite.setARGB(255, 255, 255, 255);
paintBlack = new Paint();
paintBlack.setARGB(255, 0, 0, 0);
}
public void draw(Canvas canvas)
{
canvas.drawRect(0, screenHeight/2, screenWidth, screenHeight, paintGray);
canvas.drawRect(0, 0, screenWidth/2, screenHeight/2, paintWhite);
canvas.drawRect(screenWidth/2, 0, screenWidth, screenHeight/2, paintBlack);
}
(I don't know if it matters but it runs on another Thread)
When I run it on my phone and save a screenshot using Android Studio the screenshot looks like this:
which is t he desired result, the problem is that my phone doesn't display the graphics properly and here is a photo:
As you can see the gray square has 2 colors inside it, a darker and a lighter one. It happens on both phones that I have and I have no idea what it is, even weirder is that saving the screenshot doesn't show this problem!!
I also noticed the colorization changes based on the white square, if I make it bigger or smaller the gray square changes its color where the white box ends.
Another thing I noticed is that these lines of "decolorization" (with multiple white boxes, multiple lines appear) on the gray square is vertical on landscape mode, but on portrait it becomes horizontal.
I've been torturing my self for so much time with this, I have commented out my whole application to try and see why it happens, if I'm missing something or anyone knows anything please let me know!
I don't think it's a software bug. My guess would be that that's the way the display is rendering colors.
I have this image that comes back from an API, which represents the users avatar:
However, my graphics department has designed the app to mask the image to make it look like this at runtime (to match our existing design of sharp edges, etc):
Notice the small edge cutout on the bottom left?
I'd love to be able to create a custom ImageView that handled this for me. Unfortunately I'm not sure how to go about doing that. How can I create the bottom image in a custom ImageView. Is this possible? Do I mask it? If so, how?
Thanks!
Using Path and xfer modes to draw on canvas can do the trick. Check this answer how to draw pic to Closed curve area
I think the easiest way to do is to use 2 ImageViews, one with the photo and other above it with a mask for the photo, in your case it would be all transparent except the bottom left to create the cutout with the background color.
You may be able to use android.graphics.Path to draw the complex shape you want. I found this very helpful for a simple custom View, but it seems like you can do a lot with it:
http://developer.android.com/reference/android/graphics/Path.html
Simple code sample for a shaded rectangle:
private Path mRectanglePath;
...
// draw the path
mRectanglePath = new Path();
mRectanglePath.addRect(mLeft, mTop, mRight, mBottom, Path.Direction.CW);
// draw the fill
Paint paint = new Paint();
paint.setColor(Color.RED);
paint.setAlpha(64);
canvas.drawPath(mRectanglePath, paint);
I want a cylindrical, spider web like layout:
I know that I can use canvas to draw this but I also need all portions to be clickable, and canvas is very hard to handle touch for all portion.
Ideas?
can i want layout like spider...
Yes you can want it. But if you want to actually create that layout then you cannot do it with the standard android widgets.
If you want to make it then I would suggest drawing it on a Canvas manually and using the onTouchListener to catch the key presses.
I am not sure but i hope this can help you ...
The Path class holds a set of vector-drawing commands such as lines,
rectangles, and curves. Here’s an example that defines a circular path:
circle = new Path();
circle.addCircle(150, 150, 100, Direction.CW);
This defines a circle at position x=150, y=150, with a radius of 100
pixels. Now that we’ve defined the path, let’s use it to draw the circle’s
outline plus some text around the inside:
private static final String QUOTE = "Now is the time for all " +
"good men to come to the aid of their country." ;
canvas.drawPath(circle, cPaint);
canvas.drawTextOnPath(QUOTE, circle, 0, 20, tPaint);
You can see the result in this Figure
If you want to get really fancy, Android provides a number of PathEffect
classes that let you do things such as apply a random permutation to a
path, cause all the line segments along a path to be smoothed out with
curves or broken up into segments, and create other effects.
How do you create an animated dashed or dotted border of an arbitrary shape in Android? In XML (preferred) or programmatically.
See picture below for an example.
Have you seen the PathEffects API demo?
http://developer.android.com/resources/samples/ApiDemos/src/com/example/android/apis/graphics/PathEffects.html
It produces precisely an animated line and you can just adjust the path to the edge of your view to create a border. For example:
Define a path by your view parameters / arbitrary shape:
Path path = new Path();
path.addRect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom(), Path.Direction.CW);
Then create a dashed PathEffect with:
PathEffect pe = new DashPathEffect(new float[] {10, 5, 5, 5}, phase);
Then set the associate it with a Paint object and draw:
mPaint.setPathEffect(pe);
canvas.drawPath(path, mPaint);
EDIT: The animated effect comes from continuously changing the phase and redrawing. In the API demo it calls invalidate() in the onDraw() method (which triggers onDraw()...)
XML... I guess not possible. But you can use a custom view or a SurfaceView and handle the drawing by yourself. Have fun with that :)
Could you use some form of two 9patch images as a background frame around the image file you want to present, one in each of two layouts. The images would differ in terms of the placement of the dashed elements. Interchange the views rapidly (might need a delay) and you might get the effect you want. Don't really know how effective that would be though in terms of being able to let the user continue using the app and chewing battery...