在Android的自定义视图 [英] Custom views in android

查看:98
本文介绍了在Android的自定义视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚开始学习如何制作自定义视图。我在屏幕的底部,并在其中一个小圆圈创建的绘制。布局工作完全正常,但有一个小问题,在不同的分辨率绘制裁剪。它工作正常S3但在其他设备上的东西是不同的。

下面是我的code:

  @覆盖
保护无效onMeasure(INT widthMeasureSpec,诠释heightMeasureSpec){
    INT childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
            MeasureSpec.getSize(widthMeasureSpec),MeasureSpec.EXACTLY);
    INT childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
            MeasureSpec.getSize(heightMeasureSpec),MeasureSpec.EXACTLY);
    setMeasuredDimension(childWidthMeasureSpec,childHeightMeasureSpec);
}
@覆盖
保护无效的onDraw(帆布油画){
    super.onDraw(画布);    可绘制outer_ring = getResources()getDrawable(R.drawable.outer_ring)。    的System.out.println(身高现在是:+(canvas.getHeight()));    矩形R1 =新的矩形();
    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(画布);    涂料粉刷=新的油漆(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,油漆);
}

应该是什么,这种观点同样出现在所有分辨率的解决方案

下面是我的布局:

 <?XML版本=1.0编码=UTF-8&GT?;
<的RelativeLayout的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
    机器人:layout_width =match_parent
    机器人:layout_height =match_parent
    机器人:方向=垂直>    < com.example.testing.CustomMenu
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT
        机器人:ID =@ + ID / MyView的
        />    <按钮
        机器人:ID =@ + ID /按钮1
        机器人:layout_width =WRAP_CONTENT
        机器人:layout_height =WRAP_CONTENT
        机器人:layout_centerHorizo​​ntal =真
        机器人:layout_centerVertical =真
        机器人:文字=按钮/>< / RelativeLayout的>


解决方案

修改

原来,提供给的onDraw 画布的大小是不保证的大小实际观看尺寸相同查看。它仅仅是保证足够大。你的情况,它太大了!

据<一个href=\"http://stackoverflow.com/questions/6652400/how-can-i-get-the-canvas-size-of-a-custom-view-outside-of-the-ondraw-method\">this问答,关键是使用尺寸在 onSizeChanged 返回作为最终的查看当前显示的尺寸。所以,你应该保留从 onSizeChanged 尺寸,并在的onDraw 用它们来知道你应该画到实际大小。的的,


  • childWidthMeasureSpec childHeightMeasureSpec 应成为其在 onSizeChanged

  • 的onDraw ,用它们来代替 canvas.getWidth()画布。的getHeight()分别。

虽然这种行为乍看起来有点奇怪,它可以让机器人来降低整理大小时,它使得画布重新分配的数量:如果查看缩小一个位(如:的有顶栏的外观)一切它告诉所有担心,实际尺寸小了些,而不是通过一个帆布释放持续和再创造循环。

可能不太显著,在你的java code,你要求查看您绘制的尺寸。在XML中,您可以设置这些尺寸为 WRAP_CONTENT 。这意味着,在查看的大小没有明确的设定。像这样的显示应要求它可以是最大尺寸,和决定它希望如何大给予的是,并设置其大小。这是明智的,以确保dimesnions由 CustomMenu 的大小设置为 match_patent 固定的,所以他们是固定的。

然而,在没有了,父查看给你一些界限。看来,这些边界可能,也可能不会,取前吧,这是很公平的帐户。

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>

解决方案

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.
  • In 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.

这篇关于在Android的自定义视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆