Have a look at my code below.
ShapeDrawable shapeDrawable = new ShapeDrawable(new RectShape());
shapeDrawable.getPaint().setColor(Color.parseColor("#5a2705"));
shapeDrawable.getPaint().setStyle(Style.STROKE);
shapeDrawable.getPaint().setAntiAlias(true);
shapeDrawable.getPaint().setStrokeWidth(2);
shapeDrawable.getPaint().setPathEffect(new CornerPathEffect(10));
I am applying this as background to my LinearLayout, but the edges are not smooth. How can I fix this?
Here is the screenshot of how it looks.
Using a programmatically-created shape drawable as a View background results in the outer half of your stroke width getting cropped off (for reasons I don't know). Look closely at your image and you'll see that your stroke is only 1 pixel wide, even though you requested 2. That is why the corners look ugly. This effect will be much more apparent if you try a bigger stroke and radius such as 10 and 40, respectively.
Either use an XML drawable, which doesn't seem to have this problem, like in Harshit Jain's answer, or do the following if you must (or prefer to) use a programmatic solution.
Solution: Use a layer list to inset the rectangle by the amount that is being clipped (half the stroke width), like this:
float strokeWidth = 2;
ShapeDrawable shapeDrawable = new ShapeDrawable(new RectShape());
shapeDrawable.getPaint().setColor(Color.parseColor("#5a2705"));
shapeDrawable.getPaint().setStyle(Style.STROKE);
shapeDrawable.getPaint().setAntiAlias(true);
shapeDrawable.getPaint().setStrokeWidth(strokeWidth);
shapeDrawable.getPaint().setPathEffect(new CornerPathEffect(10));
Drawable[] layers = {shapeDrawable};
LayerDrawable layerDrawable = new LayerDrawable(layers);
int halfStrokeWidth = (int)(strokeWidth/2);
layerDrawable.setLayerInset(0, halfStrokeWidth, halfStrokeWidth, halfStrokeWidth, halfStrokeWidth);
Then use the layerDrawable as your background. Here is a screen shot of the result of the above code:
You can try creating a separate xml file with a layout of the rounded rectangle. Such as:
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="color_here"/>
<stroke android:width="5dp" android:color="color_here"/>
<corners android:radius="2dp"/>
</shape>
You can tune this to your liking and use this XML file as a background in your main XML.
You can also try using 9Patch which should already come with your SDK
To cater such background requirement I prefer using 9-patch drawable.
Below are the pointer to get going with creating and using 9-patch drawable resources:
Developer Doc: http://developer.android.com/tools/help/draw9patch.html
Another explanation: http://radleymarx.com/blog/simple-guide-to-9-patch/
Online tool to create 9-patch images. (Note: Modify the file extension to *.9.png while saving the image)
You might want to consider checking this out.
Rounded Image Views by Vince
I have solved this issue in a very simple way,
I was looking for a code which can be done programmatically and not via xml,
Here is the code:
GradientDrawable shape = new GradientDrawable();
shape.setCornerRadius(10);
shape.setColor(Color.WHITE);
shape.setStroke(2, Color.parseColor("#996633"));
You can set this like this : view.setBackgroundDrawable(shape);
The answer posted by #Tenfour04 might also solve the issue but i havent tried as such.
Hope it helps someone.
You may try using selector like this . This solution is the best you just need to set this selector to the background of the layout.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#color/white" />
<stroke android:width="1dp" android:color="#color/grey" />
<padding android:left="10dp" android:top="10dp" android:right="10dp" android:bottom="10dp" />
<corners android:radius="15dp" />
<gradient
android:angle="90"
android:startColor="#color/white"
android:centerColor="#color/grey"
android:endColor="#color/white"
android:type="linear" />
</shape>
Choose color of your own.
Cheers!
I've encountered this problem recently and came up with a different solution. IMHO the best solution is to create your own Shape implementation and use it to create a ShapeDrawable.
Below is a simple implementation of rounded rectangle, that will allow you to inset it's border.
class InsetRoundRectShape(
private var radiusArray: FloatArray = floatArrayOf(0f, 0f, 0f, 0f, 0f, 0f, 0f, 0f),
private var inset: RectF = RectF()
): RectShape() {
private var innerRect: RectF = RectF()
private var path: Path = Path()
constructor(radius: Float, inset: RectF): this(floatArrayOf(radius, radius, radius, radius, radius, radius, radius, radius), inset)
constructor(radius: Float, inset: Float): this(radius, RectF(inset, inset, inset, inset))
init {
if (radiusArray.size < 8) {
throw ArrayIndexOutOfBoundsException("radius array must have >= 8 values")
}
}
override fun draw(canvas: Canvas, paint: Paint) {
canvas.drawPath(path, paint)
}
override fun getOutline(outline: Outline) {
super.getOutline(outline)
val radius = radiusArray[0]
if(radiusArray.any { it != radius }) {
outline.setConvexPath(path)
return
}
val r = rect()
outline.setRoundRect(ceil(r.left).toInt(), ceil(r.top).toInt(), floor(r.right).toInt(), floor(r.bottom).toInt(), radius)
}
override fun onResize(w: Float, h: Float) {
super.onResize(w, h)
val r = rect()
path.reset()
innerRect.set(r.left + inset.left, r.top + inset.top, r.right - inset.right, r.bottom - inset.bottom)
if(innerRect.width() <= w && innerRect.height() <= h) {
path.addRoundRect(innerRect, radiusArray, Path.Direction.CCW)
}
}
override fun clone(): InsetRoundRectShape {
val shape = super.clone() as InsetRoundRectShape
shape.radiusArray = radiusArray.clone()
shape.inset = RectF(inset)
shape.path = Path(path)
return shape
}
}
Create ShapeDrawable like this
//Inset has to be half of strokeWidth
ShapeDrawable(InsetRoundRectShape(10f, 4f)).apply {
this.paint.color = Color.BLUE
this.paint.style = Paint.Style.STROKE
this.paint.strokeWidth = 8.dp
this.invalidateSelf()
}
Related
I am using this image:
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="32dp"
android:height="39dp"
android:viewportWidth="32"
android:viewportHeight="39">
<path
android:pathData="M15.8575,6.5831L15.8575,1.0031C15.8575,0.1031 14.7775,-0.3369 14.1575,0.3031L6.5575,7.8831C6.1575,8.2831 6.1575,8.9031 6.5575,9.3031L14.1375,16.8831C14.7775,17.5031 15.8575,17.0631 15.8575,16.1631L15.8575,10.5831C23.3175,10.5831 29.2175,17.4231 27.5775,25.1631C26.6375,29.7031 22.9575,33.3631 18.4375,34.3031C11.2975,35.8031 4.9375,30.9031 3.9775,24.2831C3.8375,23.3231 2.9975,22.5831 2.0175,22.5831C0.8175,22.5831 -0.1425,23.6431 0.0175,24.8431C1.2575,33.6231 9.6175,40.1231 19.0775,38.2831C25.3175,37.0631 30.3375,32.0431 31.5575,25.8031C33.5375,15.5431 25.7375,6.5831 15.8575,6.5831Z"
android:strokeWidth="1"
android:fillColor="#fff"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M-34,-30h100v100h-100z"
android:strokeWidth="1"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>
as drawableStart in a button
android:drawableStart="#drawable/ic_restart"
I am using focus navigation, so in onFocusChanged of the button I am enlarging it with this extension:
fun View.enlarge(turnOn: Boolean) {
if (turnOn) {
translationZ = 1f
scaleX = 1.2f
scaleY = 1.2f
} else {
translationZ = 0f
scaleX = 1.0f
scaleY = 1.0f
}
}
It works very well, however the drawable is pixelated after I enlarge it even though it is xml. The image loses its quality. What is causing this and how can I avoid it and keed the image looking good?
EDIT: tried different approach according to answer below, but was not successful
override fun onFocusChanged(gainFocus: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
if (gainFocus) {
imageView.layoutParams.height = 60
imageView.layoutParams.width = 60
} else {
imageView.layoutParams.height = 50
imageView.layoutParams.width = 50
}
}
or
override fun onFocusChanged(gainFocus: Boolean, direction: Int, previouslyFocusedRect: Rect?) {
if (gainFocus) {
imageView.drawable.setBounds(0,0,60,60)
} else {
imageView.drawable.setBounds(0,0,50,50)
}
}
None of these two methods are working. This time the icon is pixelated when made smaller.
What is still wrong with VectorDrawable?
Using Scale X/Y to enlarge your views make them lose quality, instead increase the width and height, since you're using a vector drawable it would scale properly with it, to do this in code, use the layout param of the view... but note that the drawable of a button does not scale with the button so you should try something else like an image button or a linear layout with the drawable beside the button.
Is there a wat to make a indicator like this?
it has some pointed arrow down like in the selected item?
The only solution I could find is to grab the source code of the original TabLayout and customize it, according your needs.
In fact, all you need to do to get this custom pointing arrow is to override SlidingTabStrip's void draw(Canvas canvas) method. Unfortunately, SlidingTabStrip is private inner class inside TabLayout.
Luckily, all support library code is open, so we can create our own TabLayoutWithArrow class. I replaced the standard void draw(Canvas canvas) by this one to draw the arrow:
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
// i used <dimen name="pointing_arrow_size">3dp</dimen>
int arrowSize = getResources().getDimensionPixelSize(R.dimen.pointing_arrow_size);
if (mIndicatorLeft >= 0 && mIndicatorRight > mIndicatorLeft) {
canvas.drawRect(mIndicatorLeft, getHeight() - mSelectedIndicatorHeight - arrowSize,
mIndicatorRight, getHeight() - arrowSize, mSelectedIndicatorPaint);
canvas.drawPath(getTrianglePath(arrowSize), mSelectedIndicatorPaint);
}
}
private Path getTrianglePath(int arrowSize) {
mSelectedIndicatorPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mSelectedIndicatorPaint.setAntiAlias(true);
int leftPointX = mIndicatorLeft + (mIndicatorRight - mIndicatorLeft) / 2 - arrowSize*2;
int rightPointX = leftPointX + arrowSize*2;
int bottomPointX = leftPointX + arrowSize;
int leftPointY = getHeight() - arrowSize;
int bottomPointY = getHeight();
Point left = new Point(leftPointX, leftPointY);
Point right = new Point(rightPointX, leftPointY);
Point bottom = new Point(bottomPointX, bottomPointY);
Path path = new Path();
path.setFillType(Path.FillType.EVEN_ODD);
path.setLastPoint(left.x, left.y);
path.lineTo(right.x, right.y);
path.lineTo(bottom.x, bottom.y);
path.lineTo(left.x, left.y);
path.close();
return path;
}
Of course, the background, the particular design of the indicator can be improved/adjust according your needs.
To make my custom TabLayoutWithArrow, I had to copy these files into my project:
AnimationUtils
TabLayout
ThemeUtils
ValueAnimatorCompat
ValueAnimatorCompatImplEclairMr1
ValueAnimatorCompatImplHoneycombMr1
ViewUtils
ViewUtilsLollipop
To have transparency behind the arrow, you just need to set this Shape-drawable, as a background for the TabLayoutWithArrow :
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:bottom="#dimen/pointing_arrow_size">
<shape android:shape="rectangle" >
<solid android:color="#FFFF00" />
</shape>
</item>
<item android:height="#dimen/pointing_arrow_size"
android:gravity="bottom">
<shape android:shape="rectangle" >
<solid android:color="#00000000" />
</shape>
</item>
</layer-list>
And the actual usage is:
<klogi.com.viewpagerwithdifferentmenu.CustomTabLayout.TabLayoutWithArrow
android:id="#+id/tabLayout"
android:background="#drawable/tab_layout_background"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
I've uploaded the whole project (the TabLayoutWithArrow + one-page app which is using it) to my dropbox - feel free to check it out.
I hope, it helps
now it doesn't work, tintmanager class is removed from support library 23.2.0 , I managed same functionality by changing background drawable at runtime inside for loop detecting clicked position , PS : check this question and answer I am using same library : https://github.com/astuetz/PagerSlidingTabStrip/issues/141
Here is the code for anyone requiring an upward triangle using #Konstantin Loginov code
private Path getTrianglePath(int arrowSize) {
mSelectedIndicatorPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mSelectedIndicatorPaint.setAntiAlias(true);
mSelectedIndicatorPaint.setColor(Color.WHITE);
int leftPointX = mIndicatorLeft + (mIndicatorRight - mIndicatorLeft) / 2 - arrowSize * 1 / 2;
int mTopX = leftPointX + arrowSize;
int mTopY = getHeight() - arrowSize;
int rightPointX = leftPointX + arrowSize * 2;
int leftPointY = getHeight();
Point left = new Point(leftPointX, leftPointY);
Point right = new Point(rightPointX, leftPointY);
Point bottom = new Point(mTopX, mTopY);
Path path = new Path();
path.setFillType(Path.FillType.EVEN_ODD);
path.setLastPoint(left.x, left.y);
path.lineTo(right.x, right.y);
path.lineTo(bottom.x, bottom.y);
path.lineTo(left.x, left.y);
path.close();
return path;
}
I've got a collapsing toolbar with an imageview. When extended, it looks like this:
When collapsed, it looks like this:
I know that according to the guidelines, the toolbar should be of the primary color while collapsed, but i like the way i've set it up, and would like to keep it like that.
However, obviously, the toolbar title won't be visible if the image has a lot of white in it. So, is there a way i can blur/dim the background so that the toolbar title is visible at all times?
Edit: The image in question, is loaded from the internet using Picasso.
If you are using Picasso to display the image, then you can leverage the Transformation object in Picasso's builder and create a Blur effect class with something like this:
public class BlurEffect implements Transformation {
private static final int UP_LIMIT = 25;
private static final int LOW_LIMIT = 1;
protected final Context context;
private final int blurRadius;
public BlurEffect(Context context, int radius) {
this.context = context;
if (radius < LOW_LIMIT) {
this.blurRadius = LOW_LIMIT;
} else if (radius > UP_LIMIT) {
this.blurRadius = UP_LIMIT;
} else {
this.blurRadius = radius;
}
}
#Override public Bitmap transform(Bitmap source) {
Bitmap blurredBitmap;
blurredBitmap = Bitmap.createBitmap(source);
RenderScript renderScript = RenderScript.create(context);
Allocation input =
Allocation.createFromBitmap(renderScript, source,
Allocation.MipmapControl.MIPMAP_FULL,
Allocation.USAGE_SCRIPT);
Allocation output = Allocation.createTyped(renderScript, input.getType());
ScriptIntrinsicBlur script =
ScriptIntrinsicBlur.create(renderScript,
Element.U8_4(renderScript));
script.setInput(input);
script.setRadius(blurRadius);
script.forEach(output);
output.copyTo(blurredBitmap);
return blurredBitmap;
}
#Override public String key() {
return "blurred";
}
}
Then you can use it from Picasso in this way, the more value in second parameter in the constructor, then blurer:
Picasso.with(appBarImage.getContext())
.load(track.getUrl())
.transform(new BlurEffect(this, 10))
.into(appBarImage);
My not optimal solution to this problem was to overlap two images, the normal and the blurred one, and change the alpha of the blurred one. When expanded, the alpha is 0. When collapsed its alpha is one. I used
AppBarLayout.addOnOffsetChangedListener
to get the scroll event. In my case
appBarLayout.addOnOffsetChangedListener((view, verticalOffset) -> {
if (mScrollRange == 0) {
mScrollRange = appBarLayout.getTotalScrollRange();
}
ViewCompat.setAlpha(mBlurredImage,
(float) (1 - Math.pow(((mScrollRange + verticalOffset) / (float) mScrollRange), 4)));
});
It is not ideal but it does its work
Ok, So, i just ended up using android:tint in the layout file in order to add a grayish tint to the image.For reference, the tint value i set is #55000000. This seems to make the title visible even on entirely white backgrounds.
You could use Blurry library
Blurry is an easy blur library for Android
// from Bitmap
Blurry.with(context).from(bitmap).into(imageView);
//use with Picasso
Blurry.with(MainActivity.this)
.radius(10)
.sampling(8)
.async()
.capture(findViewById(R.id.image_veiw))
.into((ImageView) findViewById(R.id.image_veiw));
You can use scrim for this. create gradient file in drawable folder.
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="-90"
android:startColor="#00000000"
android:centerColor="#00000000"
android:endColor="#4d000000"
android:type="linear" />
</shape>
After creating the above file add an extra view to your layout like this
<FrameLayout>
<ImageView>
<View
android:background="#drawable/nameOfAboveFile"/>
<TexTView>
</FrameLayout>
I want to create Hexagon shape for my project so I want to create that shape in .xml format so how can i create.
The best solution for you would be use VectorDrawable:
Hexagon shape as vector drawable:
<vector android:height="24dp" android:viewportHeight="628.0"
android:viewportWidth="726.0" android:width="27dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#00ffffff"
android:pathData="m723,314c-60,103.9 -120,207.8 -180,311.8 -120,0 -240,0 -360,0C123,521.8 63,417.9 3,314 63,210.1 123,106.2 183,2.2c120,0 240,0 360,0C603,106.2 663,210.1 723,314Z"
android:strokeColor="#000000" android:strokeWidth="4"/>
</vector>
Update(28:07.2016):
To support API below Lollipop use support library http://android-developers.blogspot.com/2016/02/android-support-library-232.html remember to use VectorDrawableCompat instead VectorDrawable
if you want output like this
if you want full hexagon
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="512dp"
android:height="512dp"
android:viewportWidth="512"
android:viewportHeight="512">
<path
android:fillColor="#000000"
android:pathData="m485.291,129.408 l-224,-128c-3.285,-1.877 -7.296,-1.877
-10.581,0l-224,128c-3.328,1.899 -5.376,5.44 -5.376,9.259v234.667c0,3.819 2.048,7.36
5.376,9.259l224,128c1.643,0.939 3.456,1.408 5.291,1.408s3.648,-0.469
5.291,-1.408l224,-128c3.328,-1.899 5.376,-5.44 5.376,-9.259v-234.667c-0.001,-3.819
-2.049,-7.36 -5.377,-9.259z" />
</vector>
While most solutions would involve including the ShapeImageView (which is a great library, btw), you can always write your own logic to create a custom hexagon shaped layout.
All you need to do is define the properties of the Path object and then use that in the onDraw() method of the layout using the Canvas.
This is how you would create the hexagon path.
float midx = getWidth() / 2;
float midy = getHeight() / 2;
Path p = new Path();
p.moveTo(midx, midy);
p.lineTo(midx+150, midy + 220);
p.lineTo(midx, midy + 220);
p.lineTo(midx-150, midy + 220);
p.lineTo(midx-300, midy);
p.lineTo(midx-150, midy-220);
p.lineTo(midx+150, midy-220);
p.lineTo(midx+300, midy);
p.lineTo(midx+150, midy + 220);
return p;
Now, in your custom hexagon layout, use this path in onDraw().
#Override
protected void onDraw(Canvas canvas) {
Path clipPath = new Path();
clipPath.addPath(p); //p is the path you created above
canvas.clipPath(clipPath);
canvas.drawColor(Color.RED); //optional
super.onDraw(canvas)
}
Once you have your custom layout ready, you can set the background of the layout to any drawable you want (just as you would do for any other layouts).
You can use VectorDrawable (VectorDrawableCompat for old version) https://developer.android.com/studio/write/vector-asset-studio.html. You can easialy import shape from .svg files.
Is there a wat to make a indicator like this?
it has some pointed arrow down like in the selected item?
The only solution I could find is to grab the source code of the original TabLayout and customize it, according your needs.
In fact, all you need to do to get this custom pointing arrow is to override SlidingTabStrip's void draw(Canvas canvas) method. Unfortunately, SlidingTabStrip is private inner class inside TabLayout.
Luckily, all support library code is open, so we can create our own TabLayoutWithArrow class. I replaced the standard void draw(Canvas canvas) by this one to draw the arrow:
#Override
public void draw(Canvas canvas) {
super.draw(canvas);
// i used <dimen name="pointing_arrow_size">3dp</dimen>
int arrowSize = getResources().getDimensionPixelSize(R.dimen.pointing_arrow_size);
if (mIndicatorLeft >= 0 && mIndicatorRight > mIndicatorLeft) {
canvas.drawRect(mIndicatorLeft, getHeight() - mSelectedIndicatorHeight - arrowSize,
mIndicatorRight, getHeight() - arrowSize, mSelectedIndicatorPaint);
canvas.drawPath(getTrianglePath(arrowSize), mSelectedIndicatorPaint);
}
}
private Path getTrianglePath(int arrowSize) {
mSelectedIndicatorPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mSelectedIndicatorPaint.setAntiAlias(true);
int leftPointX = mIndicatorLeft + (mIndicatorRight - mIndicatorLeft) / 2 - arrowSize*2;
int rightPointX = leftPointX + arrowSize*2;
int bottomPointX = leftPointX + arrowSize;
int leftPointY = getHeight() - arrowSize;
int bottomPointY = getHeight();
Point left = new Point(leftPointX, leftPointY);
Point right = new Point(rightPointX, leftPointY);
Point bottom = new Point(bottomPointX, bottomPointY);
Path path = new Path();
path.setFillType(Path.FillType.EVEN_ODD);
path.setLastPoint(left.x, left.y);
path.lineTo(right.x, right.y);
path.lineTo(bottom.x, bottom.y);
path.lineTo(left.x, left.y);
path.close();
return path;
}
Of course, the background, the particular design of the indicator can be improved/adjust according your needs.
To make my custom TabLayoutWithArrow, I had to copy these files into my project:
AnimationUtils
TabLayout
ThemeUtils
ValueAnimatorCompat
ValueAnimatorCompatImplEclairMr1
ValueAnimatorCompatImplHoneycombMr1
ViewUtils
ViewUtilsLollipop
To have transparency behind the arrow, you just need to set this Shape-drawable, as a background for the TabLayoutWithArrow :
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:bottom="#dimen/pointing_arrow_size">
<shape android:shape="rectangle" >
<solid android:color="#FFFF00" />
</shape>
</item>
<item android:height="#dimen/pointing_arrow_size"
android:gravity="bottom">
<shape android:shape="rectangle" >
<solid android:color="#00000000" />
</shape>
</item>
</layer-list>
And the actual usage is:
<klogi.com.viewpagerwithdifferentmenu.CustomTabLayout.TabLayoutWithArrow
android:id="#+id/tabLayout"
android:background="#drawable/tab_layout_background"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
I've uploaded the whole project (the TabLayoutWithArrow + one-page app which is using it) to my dropbox - feel free to check it out.
I hope, it helps
now it doesn't work, tintmanager class is removed from support library 23.2.0 , I managed same functionality by changing background drawable at runtime inside for loop detecting clicked position , PS : check this question and answer I am using same library : https://github.com/astuetz/PagerSlidingTabStrip/issues/141
Here is the code for anyone requiring an upward triangle using #Konstantin Loginov code
private Path getTrianglePath(int arrowSize) {
mSelectedIndicatorPaint.setStyle(Paint.Style.FILL_AND_STROKE);
mSelectedIndicatorPaint.setAntiAlias(true);
mSelectedIndicatorPaint.setColor(Color.WHITE);
int leftPointX = mIndicatorLeft + (mIndicatorRight - mIndicatorLeft) / 2 - arrowSize * 1 / 2;
int mTopX = leftPointX + arrowSize;
int mTopY = getHeight() - arrowSize;
int rightPointX = leftPointX + arrowSize * 2;
int leftPointY = getHeight();
Point left = new Point(leftPointX, leftPointY);
Point right = new Point(rightPointX, leftPointY);
Point bottom = new Point(mTopX, mTopY);
Path path = new Path();
path.setFillType(Path.FillType.EVEN_ODD);
path.setLastPoint(left.x, left.y);
path.lineTo(right.x, right.y);
path.lineTo(bottom.x, bottom.y);
path.lineTo(left.x, left.y);
path.close();
return path;
}