【问题标题】:Gesture detection in an Android Live WallpaperAndroid 动态壁纸中的手势检测
【发布时间】:2011-05-10 16:23:53
【问题描述】:

我有一个动态壁纸,我想在其中添加手势,但我似乎无法找到实际添加监听器的位置。什么是动态壁纸中的“视图”,我可以添加 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);
        }
    }
}

提前致谢

服从

【问题讨论】:

  • 注意,这个动态壁纸的手势代码受到this线程的严重影响

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


【解决方案1】:

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

【讨论】:

  • 嗨,乔治。感谢您的回复和对动态壁纸工作原理的精彩解释 - 这对我的帮助无穷无尽。我实际上是在上下滑动之后,所以我基本上不得不使用立方体示例中的触摸示例来滚动我自己的手势。再次感谢
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    您可以将MotionEventonTouchEvent 传递给GestureDetector.SimpleOnGestureListener 以检测双击等,然后使用onCommand 方法作为Muzei does 确认该事件是针对壁纸的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多