Reputation: 217
I just started learning on how to make custom views .I created a drawable at the bottom of the screen and a small circle within it. The layout works perfectly fine but there is a small issue , the drawable in different resolution is cropped . Its works fine in S3 but in other devices the things are different.
Here is my code :
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.EXACTLY);
int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.EXACTLY);
setMeasuredDimension(childWidthMeasureSpec,childHeightMeasureSpec);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
Drawable outer_ring = getResources().getDrawable(R.drawable.outer_ring);
System.out.println("Height now is : "+(canvas.getHeight()));
Rect r1 = new Rect();
r1.top = (canvas.getHeight()-outer_ring.getIntrinsicHeight());
r1.bottom = canvas.getHeight();
r1.left = (canvas.getWidth()-outer_ring.getIntrinsicWidth())/2;
r1.right = canvas.getWidth()/2 +outer_ring.getIntrinsicWidth()/2;
outer_ring.setBounds(r1);
outer_ring.draw(canvas);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.BLACK);
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(10.0f);
canvas.drawCircle(canvas.getWidth()/2, ((canvas.getHeight()-outer_ring.getIntrinsicHeight()/2)), 20, paint);
}
what should be the solution that this view appears same on all resolution
Here is my layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<com.example.testing.CustomMenu
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/myView"
/>
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="Button" />
</RelativeLayout>
Upvotes: 0
Views: 438
Reputation: 6084
Edit
It turns out the the size of the canvas provided to onDraw
isn't guaranteed to be the same size as the actual viewed size of the View
. It is merely guaranteed to be sufficiently large. In your case, it is too big!
According to this question and answer, the key is to use the sizes returned in onSizeChanged
as definitive for the current displayed size of the View
. So you should retain the dimensions from onSizeChanged
, and use them in onDraw
to know the actual size you should draw to. ie,:
childWidthMeasureSpec
and childHeightMeasureSpec
should become class variables which are set in onSizeChanged
.onDraw
, use them instead of canvas.getWidth()
and canvas.getHeight()
respectively.Whilst this behaviour seems a bit odd at first glance, it allows android to lower the number of canvas re-allocations it makes when sorting out sizes: If a View
shrinks a bit (eg. with the appearance of a top bar) all it does it tell all concerned that the actual size is a bit smaller, rather than going through a canvas release and re-creation loop.
Probably less significant, in your java code, you request the dimensions of the View
you are drawing. In the xml, you set those dimensions as wrap_content
. This means that there is no explicit setting of the size of the View
. A View like this should request the maximum size it can be, and the determine how large it wishes to be given that, and set that as its size. It's wiser to ensure that the dimesnions are fixed by setting the sizes of CustomMenu
to match_patent
, so that they are fixed.
However, in the absence of that, the parent View
has given you some bounds. It appears that these bounds may, or may not, take account of the top bar, which is fair enough.
Upvotes: 2
Reputation: 1803
Try using this.getHeight()
instead of canvas.getHeight()
and this.getWidth()
instead of canvas.getWidth()
.
(this
relates to the View
)
Upvotes: 0