Android 动态壁纸中的手势检测
我有一个动态壁纸,我想向其中添加手势,但我似乎找不到实际添加监听器的位置。我可以添加 setOnGestureListener() 来添加 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);
}
}
}
提前致谢
obie
I have a Live Wallpaper which I'd like to add gestures to but I can't seem to find where to actually add the listener. What is considered the 'view' in a live wallpaper which i can add setOnGestureListener() to please?
here is the code for my engine
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);
}
}
}
Thanks in advance
obie
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
动态壁纸的工作原理与普通 Android 的东西有些不同。你看不到风景。你得到的只是一块画布,你必须以不同的方式构建事物......本质上你是在与启动器协调。 SDK 中的 Cube 示例是一个很好的起点:它在 onCreate 中启用触摸事件,然后重写 onTouchEvent 方法。请记住,您通过这种方式获得的任何手势也将由启动器处理。如果您需要的只是简单的屏幕点击,那么更好的做法是使用 onCommand 并按照所述检查 android.wallpaper.tap 此处。
Live wallpaper works somewhat differently from normal Android stuff. You don't get a view. All you get is a canvas, and you have to structure things differently...essentially you are coordinating with the launcher. The Cube example in the SDK is a good point of departure: it enables touch events in onCreate, and then overrides the onTouchEvent method. Bear in mind that any gestures you get this way will also be processed by the launcher. If all you need is simple screen taps, it is better practice to use onCommand and check for android.wallpaper.tap as described here.
我遇到了同样的问题,我找到了壁纸的解决方法,方法是每次调用 onTouchEvent 时在数组中添加触摸事件,然后通过轮询处理数组中的数据。它远非最佳解决方案,但它可以满足我在壁纸中的需要。然而,拥有完整的手势侦听器会很棒,因为它将提供很大的灵活性。
I've had the same problem, i found a workaround for my wallpaper by adding a touch event in an array each time the onTouchEvent is called, then i process the data in the array via polling. It is far from an optimal solution but it works for what i need in the wallpaper. However it would be great to have the full gestures listener as it would allow for great flexibility.
您可以将
MotionEvent
从onTouchEvent
传递到GestureDetector.SimpleOnGestureListener
来检测双击等,然后确认该事件适用于使用onCommand
方法作为 Muzei是的。You can pass the
MotionEvent
fromonTouchEvent
to aGestureDetector.SimpleOnGestureListener
to detect double taps, etc, and then confirm that the event is intended for the wallpaper using theonCommand
method as Muzei does.