触摸屏幕时图像会出现像素化

发布于 2024-12-29 13:43:34 字数 378 浏览 1 评论 0原文

我正在 Android 上用 HTML/JS 构建一个小游戏。我的 HTC Desire (Android 2.2) 遇到问题。当我触摸屏幕时,所有图像看起来都是像素化的,而当触摸结束时它们就会变得不像素化。

这是一个屏幕截图:

在此处输入图像描述

右侧是触摸屏幕时的情况。有人可以帮我找出导致此问题的原因吗?

注意:

  • 如果不触摸屏幕,动画期间不会出现问题
  • 我在 LG 540 Android 2.1 上没有这个问题
  • 触摸时图像的颜色数量似乎受到限制
  • 我正在使用 Phonegap

I'm building a little game in HTML/JS on Android. I'm running into a problem on my HTC Desire (Android 2.2). When I touch the screen, all the images look pixelated and they get un-pixelated when the touch ends.

Here is a screenshot:

enter image description here

On the right it's when the screen is being touched. Can someone help me figure out what's causing this issue?

Notes:

  • No problems during the animations if the screen is not touched
  • I don't have this problem on my LG 540 Android 2.1
  • it seems images get a restricted number of colors when it's being touched
  • I'm using Phonegap

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

猫烠⑼条掵仅有一顆心 2025-01-05 13:43:34

据我所知,“像素化”行为是针对滚动所做的优化(在 Froyo 及以上版本中)。如果渲染被简化,那么像滑动滚动动画这样的事情就需要更少的处理。

如果您需要完整的浏览器功能,我不确定您能提供多大帮助。

不过,既然你说你正在制作游戏,我可能有一个解决方法。我希望你的游戏不需要滚动(一个全屏),所以滚动优化是没有必要的。

我用 WebView 做了一个简单的测试。正如您所提到的,点击后,渲染会被简化,并且事情看起来有点不对劲。然后,一旦单击某些内容(WebView 知道不再发生滚动),事情就会恢复正常。

我通过用 FrameLayout 替换 WebView 来修改我的布局。 FrameLayout 包含 WebView 和一个不可见的 Button(位于顶部)。该按钮捕获所有触摸事件。然后,我有选择地选择 WebView 应该需要什么类型的事件,并将它们传递给 WebView。如果触地和触地发生的时间很接近,中间没有任何移动,就没有滚动的理由,所以我没有看到任何“像素化”行为。

因为这个示例最简单,所以我选择检测“MotionEvent.ACTION_UP”事件,当它完成时,我首先发送一个向下的事件,以便它模拟真实的点击。您当然可以在 ACTION_DOWN 上触发,但如果用户滑动或其他操作,您会得到不止一个,而且我想让这里的逻辑保持简单。您可以根据需要进行自定义,并且可能需要足够的工作,甚至在某些情况下启用滚动。我希望下面的代码足以传达我认为有效的内容。

WebView wv = new WebView(this);
View dummyView = new Button(this);
dummyView.setBackgroundColor(0x00000000);
dummyView.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            MotionEvent down = MotionEvent.obtain(100, 100,
                MotionEvent.ACTION_DOWN, event.getX(),
                event.getY(), 0);
            wv.onTouchEvent(down);
            wv.onTouchEvent(event);
        }
        return false;
    }
});
FrameLayout fl = new FrameLayout(this);
fl.addView(wv);
fl.addView(dummyView);
topLayout.addView(fl);

编辑:
如果您不想编辑 PhoneGap 源代码,您也许可以执行以下操作来更改 PhoneGap 布局...它未经测试,但似乎应该有效:

@Override
public void onCreate(Bundle arg0) {
    super.onCreate(arg0);
    super.loadUrl("file:///android_asset/www/index.html");
    // Get the "root" view from PhoneGap
    LinearLayout droidGapRoot = super.root;
    // Create a new "root" that we can use.
    final LinearLayout newRoot = new LinearLayout(this);
    for (int i = 0; i < droidGapRoot.getChildCount(); i++) {
        // Move all views from phoneGap's LinearLayout to ours.
        View moveMe = droidGapRoot.getChildAt(i);
        droidGapRoot.removeView(moveMe);
        newRoot.addView(moveMe);
    }
    // Create an invisible button to overlay all other views, and pass
    // clicks through.
    View dummyView = new Button(this);
    dummyView.setBackgroundColor(0x00000000);
    dummyView.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // Only pass "UP" events to the specific view we care about, but
            // be sure to simulate a valid "DOWN" press first, so that the
            // click makes sense.
            if (event.getAction() == MotionEvent.ACTION_UP) {
                MotionEvent down = MotionEvent.obtain(100, 100,
                        MotionEvent.ACTION_DOWN, event.getX(),
                        event.getY(), 0);
                newRoot.onTouchEvent(down);
                newRoot.onTouchEvent(event);
            }
            return false;
        }
    });
    // Layer the views properly
    FrameLayout frameLayout = new FrameLayout(this);
    frameLayout.addView(newRoot);
    frameLayout.addView(dummyView);
    // Add our new customized layout back to the PhoneGap "root" view.
    droidGapRoot.addView(frameLayout);
}

As far as I can tell, that "pixelated" behavior is an optimization made for scrolling (in Froyo and above). If the rendering is simplified, it makes things like the fling scroll animation require less processing.

If you need full browser functionality, I'm not sure you can help it much.

Since you've said you're making a game, however, I might have a workaround. I'm hoping your game doesn't need scroll (one full screen), so the scrolling optimization isn't necessary.

I've done a simple test with a WebView. On tap, as you mentioned, the rendering gets simplified, and things look a little off. Then once something is clicked (the WebView knows no more scrolling is taking place), things go back to normal.

I modified my Layout by replacing a WebView, with a FrameLayout. The FrameLayout contains the WebView and an invisible Button (on top). This Button grabs all the touch events. Then, I selectively choose what types of events the WebView should need, and pass them to the WebView. If a touch down and touch up happen close together, with no movement in betweeen, there's no reason for scrolling, so I haven't seen any of that "pixelated" behavior.

Because it was simplest for this example, I've chosen to detect the "MotionEvent.ACTION_UP" event, and when it's complete, I send a down first, so that it simulates a real click. You could certainly trigger on ACTION_DOWN, but you'll get more than one of those if the user swipes or something, and I wanted to keep the logic here simple. You can customize as you see fit, and probably with enough work, even enable scrolling in some cases. I hope the code below is enough to relay what I think works.

WebView wv = new WebView(this);
View dummyView = new Button(this);
dummyView.setBackgroundColor(0x00000000);
dummyView.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            MotionEvent down = MotionEvent.obtain(100, 100,
                MotionEvent.ACTION_DOWN, event.getX(),
                event.getY(), 0);
            wv.onTouchEvent(down);
            wv.onTouchEvent(event);
        }
        return false;
    }
});
FrameLayout fl = new FrameLayout(this);
fl.addView(wv);
fl.addView(dummyView);
topLayout.addView(fl);

EDIT:
If you don't want to edit PhoneGap source, you might be able to do something like the following to change the PhoneGap layout... It's untested, but seems like it should work:

@Override
public void onCreate(Bundle arg0) {
    super.onCreate(arg0);
    super.loadUrl("file:///android_asset/www/index.html");
    // Get the "root" view from PhoneGap
    LinearLayout droidGapRoot = super.root;
    // Create a new "root" that we can use.
    final LinearLayout newRoot = new LinearLayout(this);
    for (int i = 0; i < droidGapRoot.getChildCount(); i++) {
        // Move all views from phoneGap's LinearLayout to ours.
        View moveMe = droidGapRoot.getChildAt(i);
        droidGapRoot.removeView(moveMe);
        newRoot.addView(moveMe);
    }
    // Create an invisible button to overlay all other views, and pass
    // clicks through.
    View dummyView = new Button(this);
    dummyView.setBackgroundColor(0x00000000);
    dummyView.setOnTouchListener(new OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            // Only pass "UP" events to the specific view we care about, but
            // be sure to simulate a valid "DOWN" press first, so that the
            // click makes sense.
            if (event.getAction() == MotionEvent.ACTION_UP) {
                MotionEvent down = MotionEvent.obtain(100, 100,
                        MotionEvent.ACTION_DOWN, event.getX(),
                        event.getY(), 0);
                newRoot.onTouchEvent(down);
                newRoot.onTouchEvent(event);
            }
            return false;
        }
    });
    // Layer the views properly
    FrameLayout frameLayout = new FrameLayout(this);
    frameLayout.addView(newRoot);
    frameLayout.addView(dummyView);
    // Add our new customized layout back to the PhoneGap "root" view.
    droidGapRoot.addView(frameLayout);
}
仅此而已 2025-01-05 13:43:34

我遇到了同样的问题。您可以尝试的一件事是将 android:hardwareAccelerated="true" 添加到标签中应用程序的清单中。这对我来说解决了问题,但是现在整个应用程序在我的设备上看起来整体上有点像素化,所以这可能不是最好的解决方案。

I'm running into this same issue. One thing you could try is adding android:hardwareAccelerated="true" to your app's manifest in the tag. This stopped the problem for me, however now the whole app seems a little more pixelated overall on my device, so this might not be the best solution.

卖梦商人 2025-01-05 13:43:34

检查两次您的图像的 CSS 大小(以像素为单位)是否与文件本身相同。似乎有某种关联。如果我拍摄一张大图像并使用与设备相关的生成的 CSS 重新缩放它,我就会看到问题。否则,它要么不呈现,要么不可见。不确定最初的问题是否已在最新的 Android 中得到解决,但我仍然支持 2.3,所以希望它有所帮助。

Check twice if your images have the same size in CSS in pixels as the files themselves. It seems to be somehow related. If I take a large image and re-scale it with a device-dependent generated CSS, I see the problem. Otherwise it's either not presented or not visible. Not sure if the original problem has been fixed in the latest Androids, but I still support 2.3, so hope it helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文