简体   繁体   English

为什么画布的大小与onDraw中的视图大小不同? (Android)

[英]Why canvas is not the same size as view in onDraw? (Android)

I tried with this 我尝试了这个

@Override
protected void onDraw(Canvas canvas)
{
    Log.e("TEST", "canvas width: " + canvas.getWidth() + "");
    Log.e("TEST", "view width: " + this.getWidth() + "");

    Log.e("TEST", "canvas height: " + canvas.getHeight() + "");
    Log.e("TEST", "view height: " + this.getHeight() + "");
    super.onDraw(canvas);
    Log.e("TEST", "canvas width: " + canvas.getWidth() + "");
    Log.e("TEST", "view width: " + this.getWidth() + "");

    Log.e("TEST", "canvas height: " + canvas.getHeight() + "");
    Log.e("TEST", "view height: " + this.getHeight() + "");
}

And this is the result: 结果如下:

canvas width: 320
view width: 480
canvas height: 533
view height: 300
canvas width: 320
view width: 480
canvas height: 533
view height: 300

Part from my main.xml 部分来自我的main.xml

    android:layout_width="480px"
    android:layout_height="300px"

According to my Log prints and part of my xml, size of view is correct. 根据我的日志打印和我的xml的一部分,视图的大小是正确的。 My device is 480x800 and both width and height divided by Log results give 1.5 (800/533=1.5 and 480/320=1.5), so it seems I get Canvas from entire screen to draw on. 我的设备是480x800,宽度和高度均除以Log结果得出1.5(800/533 = 1.5和480/320 = 1.5),因此看来我可以从整个屏幕上绘制画布了。 Why is this, and why is it so small and what should I do to draw in normal way? 为什么会这样,为什么会这么小,我应该怎么做才能正常绘制呢?

SuitUp, SuitUp,

The view-managed canvas object will likely always be different from your screen size. 视图管理的画布对象可能总是与您的屏幕尺寸不同。 A lot depends on from which object you are using the above logic. 在很大程度上取决于您使用上述逻辑的对象。 The reason for this is that Android creates a new canvas or reuses the old one depending on how your parents and children are rendered and where in the cycle of processing it is being called. 原因是Android会创建新的画布或重用旧的画布,具体取决于您的父母和孩子的渲染方式以及在处理周期中的何处调用它。 Things get even stranger when you override the behavior and change the views dynamically (especially if you do so DURING the layout/measure/draw cycle. 当您覆盖行为并动态更改视图时,事情变得更加陌生(尤其是如果您在布局/度量/绘制周期中这样做的话)。

Why is this, and why is it so small... 为什么这样,为什么这么小...

The canvas's size is based on the layout parameters of the object that it is in. If you override onMeasure or onLayout, the canvas will readjust only what is necessary to readjust. 画布的大小基于其所在对象的布局参数。如果覆盖onMeasure或onLayout,则画布将仅重新调整需要进行调整的内容。 If you are having problems with the canvas size, you really want to look at your layout parameters for the view that you are drawing in. Sometimes it will be bigger and sometimes it will be smaller. 如果您在画布大小方面遇到问题,您确实要查看要绘制的视图的布局参数。有时它会更大,有时会更小。 It will only ever be the same size as the screen in a top level View/ViewGroup that has match_parent (or fill_parent ) for both the layout_width and layout_height in an Activity that is fullscreen (no notification bar) and not using the Theme.Dialog style. 它只会与全屏活动(无通知栏)且不使用Theme.Dialog样式的Activity中的layout_widthlayout_height都具有match_parent (或fill_parent )的顶级View / ViewGroup中的屏幕大小相同。 。

... what should I do to draw in normal way? ...我应该怎么做才能正常绘制?

That depends on what you mean by normal and what your needs are. 这取决于您通常所说的是什么以及您的需求是什么。 If you are trying to manage the entire UI manually, then you have to take control of the top level object. 如果尝试手动管理整个UI,则必须控制顶级对象。 This is normally done by extending the top-level view so that you can override the behavior. 这通常是通过扩展顶级视图来完成的,以便您可以覆盖行为。 Launchers do this by overriding the top-level FrameLayout and then its child views. 启动程序通过覆盖顶级FrameLayout及其子视图来实现此目的。 Mind you, this can be costly as you CAN draw things off of the screen if you have a big enough canvas. 请注意,如果您有足够大的画布,可以从屏幕上画东西,这可能会很昂贵。

MOST programs utilize child Views and simply override the way that they draw, understanding that a child View should not control the way that a parent View draws. MOST程序利用子视图并简单地覆盖它们的绘制方式,因为要了解子视图不应控制父视图的绘制方式。 In this case, the canvas is small and limited, but it optimizes the logic and allows the object to moved accordingly while keeping the rendering stable. 在这种情况下,画布很小且受限制,但是它可以优化逻辑并允许对象相应地移动,同时保持渲染稳定。

Games make use of a fullscreen SurfaceView in order to accomplish their needs. 游戏使用全屏SurfaceView来满足其需求。 This provides a very flexible canvas with prioritization on the manual and ever-changing presentation. 这提供了一个非常灵活的画布,并且在手动和不断变化的演示文稿上具有优先级。 There are a number of examples and tutorials showing how to do this. 有许多示例和教程显示了如何执行此操作。 Simply search in Google for SurfaceView . 只需在Google中搜索SurfaceView

In general, for most Views, the default rendering and drawing methods can be utilized in their object oriented nature. 通常,对于大多数视图,可以以其面向对象的性质使用默认的渲染和绘制方法。 Properly utilizing functions like onMeasure and onLayout often achieves the desired results. 正确使用onMeasure和onLayout之类的功能通常可以达到所需的结果。 Without knowing more about your particular needs, this is the best advice that can be given. 在不了解您的特殊需求的情况下,这是可以提供的最佳建议。

More Information (unsure about relevancy) 更多信息(不确定相关性)

Understanding how Android renders Views can be crucial to achieving desirable results. 了解Android如何呈现视图对于实现理想结果至关重要。 So much has gone into the engine that it must account for multiple screens, and different ways to render the same View given many different parameters. 引擎已经投入了太多东西,它必须考虑多个屏幕,并且在给定许多不同参数的情况下,呈现同一View的方法也不同。 I would research how to utilize Layout parameters to cut down on the amount of work you have to do. 我将研究如何利用Layout参数来减少您要做的工作量。 Further, there is a lot of information on the relationships between onMeasure, onLayout and onDraw. 此外,关于onMeasure,onLayout和onDraw之间的关系,有很多信息。 In many circumstances simply applying the right parameters to the correct Views will make a huge difference in the amount of control that you have to take in order to render your object correctly. 在许多情况下,仅将正确的参数应用于正确的视图将极大地改变为正确呈现对象而必须采取的控制量。

Hope this helps, 希望这可以帮助,

FuzzicalLogic 模糊逻辑

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM