Images get pixelated when the screen is touched

早过忘川 提交于 2019-12-04 06:28:34

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);
}

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.

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!