Android动态壁纸中的手势检测

时间:2011-05-10 16:23:54

标签: android gesture-recognition gestures live-wallpaper gesturedetector

我有一个动态壁纸,我想添加手势,但我似乎无法找到实际添加听众的位置。什么被认为是动态壁纸中的'视图',我可以添加setOnGestureListener()来取悦?

这是我的引擎的代码

class HexClockEngine extends Engine
{
    private static final int SWIPE_MIN_DISTANCE = 120;
    private static final int SWIPE_MAX_OFF_PATH = 250;
    private static final int SWIPE_THRESHOLD_VELOCITY = 200;
    private static final float LINE_WIDTH = 275f;
    private static final float TEXT_SIZE_DP = 70f;
    private static final String TAG = "WallpaperEngine";

    private final   Handler     _handler        = new Handler();
    private final   Paint       _borderPaint    = new Paint();
    private final   Paint       _shadowPaint    = new Paint();
    private final   Paint       _textPaint      = new Paint();
    private final   Runnable    _draw       = new Runnable() {
                                public void run()
                                {
                                    drawFrame();
                                }
                            };
    class HexGestureListener extends SimpleOnGestureListener
    {
        @Override 
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) 
        {
            Log.i("fling", TAG);

            try
            {
                if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                    return false;

                if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY)
                {
                    Log.i(TAG, "swipe left");
                    return true;
                }
                else if (e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY)
                {
                    Log.i(TAG, "swipe right");
                    return true;
                }
            }
            catch (Exception e)
            {
                Log.e(TAG, e.toString());
            }

            return false;
        }

        @Override
        public boolean onDown(MotionEvent e) 
        {
            Log.i(TAG, "onDown");
            return true;
        }
    }
    private GestureDetector         _gestureDetector;
    private View.OnTouchListener    _gestureListener;

    private         Rect            _border;
    private         Rect            _screenBounds;
    private         boolean         _isVisible;
    private final   float           _scale;


    HexClockEngine()
    {
        DisplayMetrics metrics = new DisplayMetrics();
        Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
        display.getMetrics(metrics);

        // initialise drawables
        _scale = metrics.density;

        Log.i(TAG, "adding gestures");
        _gestureDetector = new GestureDetector(new HexGestureListener());
        _gestureListener = new View.OnTouchListener()
        {
            public boolean onTouch(View v, MotionEvent e)
            {
                if (_gestureDetector.onTouchEvent(e)) return true;
                else return false;
            }
        };

    }

    @Override
    public void onCreate(SurfaceHolder surfaceHolder)
    {
        super.onCreate(surfaceHolder);
        surfaceHolder.setFormat(android.graphics.PixelFormat.RGBA_8888);
        setTouchEventsEnabled(true);
    }

    @Override
    public void onDestroy()
    {
        super.onDestroy();
        _handler.removeCallbacks(_draw);
    }

    @Override
    public void onVisibilityChanged(boolean visible)
    {
        _isVisible = visible;

        if (_isVisible)
        {
            drawFrame();
        }
        else
        {
            _handler.removeCallbacks(_draw);
        }
    }

    @Override
    public void onSurfaceChanged(SurfaceHolder holder, int format,
            int width, int height)
    {
        super.onSurfaceChanged(holder, format, width, height);

        drawFrame();
    }

    @Override
    public void onSurfaceCreated(SurfaceHolder holder)
    {
        super.onSurfaceCreated(holder);
    }

    @Override
    public void onSurfaceDestroyed(SurfaceHolder holder)
    {
        super.onSurfaceDestroyed(holder);
        _isVisible = false;
        _handler.removeCallbacks(_draw);
    }

    @Override
    public void onOffsetsChanged(float xOffset, float yOffset, float xStep,
            float yStep, int xPixels, int yPixels)
    {

        drawFrame();
    }


    void drawFrame()
    {
        final SurfaceHolder holder = getSurfaceHolder();

        Canvas c = null;
        try
        {
            c = holder.lockCanvas();

            if (c != null)
            {
                // draw something
            }
        }
            finally
        {
            if (c != null)
                holder.unlockCanvasAndPost(c);
        }

        _handler.removeCallbacks(_draw);

        if (_isVisible)
        {
            _handler.postDelayed(_draw, 1000);
        }
    }
}

提前致谢

奥比

3 个答案:

答案 0 :(得分:2)

动态壁纸与普通的Android内容有些不同。你没有得到一个观点。你得到的只是一个画布,你必须以不同的方式构建...基本上你正在与启动器协调。 SDK中的Cube示例是一个很好的出发点:它在onCreate中启用触摸事件,然后覆盖onTouchEvent方法。请记住,您通过这种方式获得的任何手势也将由启动器处理。如果您只需要简单的屏幕点击,最好使用onCommand并按照here所述检查android.wallpaper.tap。

答案 1 :(得分:1)

我遇到了同样的问题,我通过在每次调用onTouchEvent时在数组中添加触摸事件找到了我的壁纸的解决方法,然后我通过轮询处理数组中的数据。它远非最佳解决方案,但它适用于我需要的壁纸。然而,拥有完整的手势监听器会很棒,因为它可以提供很大的灵活性。

答案 2 :(得分:0)

您可以将MotionEventonTouchEvent传递到GestureDetector.SimpleOnGestureListener以检测双击等,然后使用onCommand确认该事件是否适用于壁纸方法为Muzei does