Change a value depending on drag of speed on Android - android

I am trying to change the value of a number based on sliding my finger. I am currently using ACTION_MOVE to change the value when I drag across my view but if I drag to fast the number barely changes. If I drag slowly I can get the correct number.
Is there a way to make the change quicker depending on the speed of the motion. I am looking into Velocity Tracker but this only returns the speed of the move and I need to make the change while dragging my finger.
Is there an optimization needed to detect ACTION_MOVE in real-time?

More like pseudo code right now, but Here is what I would do:
Extend the image view to check if the event x value is between the starting x value of the image view and the width as such:
private void checkFingerPosition(int eventXPosition) {
if(eventXPosition > this.X && eventXPosition < this.x + this.getWidth())
imageInterface.showImage(this.getDrawable());
}
I would create the interface that your activity would have to implement
public interface ImageInterface {
public void showImage(Drawable drawable);
}
In your activity, implement the ImageInterface like so
implements ImageInterface
#Override
public void showImage(Drawable drawable) {
//TODO - show drawable here
}
Then take your touch event ACTION_MOVE, report the x value to all you image views like so:
ACTION_MOVE:
for(ExtendedImageView extendedImageView : ExtendedImageViewArray) {
entendedImageView.checkFingerPosition(event.X);
}

Related

Detect everytime an image is zoomed in or zoomed out

I am using the photoview library of chris banes to handle all zoom events for my gallery.
I want to detect if the image has been zoomed in or has been zoomed out by the user without overriding all those double tap,and touch event methods.Is there an efficient way to achieve this?
To answer my own question:-
I found a much better way to implement zoom detection which works for pinch zoom as well as double tap(any zooming event, without having to override each method).Found it nowhere on the web to detect a zoom event.If there's a much more efficient way, please let me know :)
(Also I am using chris banes photoview library to handle the zooming.)
So to detect a zooming event,get the rectangle of the current photoview and when a zoom event happens , OnMatrixChangeListener gets called and there you compare the rectangles to see .
(Now simply using this listener to handle a zooming event won't work, because the listener gets called, everytime you change your image,(in case you're using it in a gallery) ,it also gets called when the orientation of the screen is changed and also when simple no-zoom intending touches are made to the screen.)
Also, when the screen orientation changes,sometimes the photoview returns a 0 rectangle,so you have to check for that as well,here's my code:-
if (savedInstanceState.getBoolean(Constants.ZOOM)) {
photoViewAttacher = new PhotoViewAttacher(backgroundImage);
mWindowRect = new RectF(photoViewAttacher.getDisplayRect());
photoViewAttacher.setOnMatrixChangeListener(new PhotoViewAttacher.OnMatrixChangedListener() {
#Override
public void onMatrixChanged(RectF rect) {
//need to differentiate between screen orientation
if (mWindowRect.left == 0 && mWindowRect.top == 0 && mWindowRect.right == 0 && mWindowRect.bottom == 0) {
mWindowRect = new RectF(rect);
}
if (Math.abs(mWindowRect.left - rect.left) < 2 && Math.abs(mWindowRect.top - rect.top) < 2 && Math.abs(mWindowRect.right - rect.right) < 2 && Math.abs(mWindowRect.bottom - rect.bottom) < 2) {
viewPager.setLocked(false);
thumbnailsContainer.startAnimation(appear);
thumbnailsContainer.setClickable(true);
} else {
viewPager.setLocked(true);
thumbnailsContainer.startAnimation(disappear);
thumbnailsContainer.setClickable(false);
}
Log.i("ZOOM", "default rect: " + mWindowRect);
Log.i("ZOOM", "zoom rect: " + rect);
}
});
}
I can see a bunch of listeners, that can be notified, when a certain event on a PhotoView occurrs.
Refer to:
IPhotoView
Here I can see the listeners:
void setOnDoubleTapListener(GestureDetector.OnDoubleTapListener newOnDoubleTapListener);
void setOnScaleChangeListener(PhotoViewAttacher.OnScaleChangeListener onScaleChangeListener);
void setOnSingleFlingListener(PhotoViewAttacher.OnSingleFlingListener onSingleFlingListener);
Hope this helps.

android divide image into sub images ,recognizing

I want to divide the image into sub images and when I click on a part of the image will give me the name of the region, for example, this is my question how to recognize a region from the image, or how to divide the image into sub-images and use it in imageViews
And thank you in advance
In my opinion #fractalwrench's idea is quite good for your case. Basic steps are listed below.
Subclass Android ImageView. For example, MultiRegionImageView.
Override its onTouchEvent method. (This method gets called whenever user touches the view)
User touches the image and thereby onTouchEvent is called and provides the exact touch point (x, y).
Declare another method or interface which determines at which region a given point is. For example, getRegionByPoint(int x, int y)
If you would like to highlight that region boundaries, you could use paths. First off, you should define paths and save them into a raw file (XML, for example), then using region ID, fetch its path and finally draw that path over the main image.
For drawing a path over the main image, you should also override onDraw method of ImageView class and use canvas.drawPath();
public class MultiRegionImageView extends ImageView {
RegionProvider mRegionProvider;
int mId = -1;
private Paint mPaint;
public MultiRegionImageView(Context context) {
super(context);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
mId = mRegionProvider.getRegionIdByPoint(event.getX(), event.getY());
return super.onTouchEvent(event);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if(mId != -1) {
canvas.drawPath(mRegionProvider.getRegionBoundaryPath(mId), mPaint);
}
}
public interface RegionProvider{
int getRegionIdByPoint(float x, float y);
Path getRegionBoundaryPath(int id);
}
}
You should only need one ImageView to display the map. If you override onTouchEvent(MotionEvent e), you can get the position which is being touched in the View. If you store the position and shape of each region in some sort of List, you can check whether a touch event is within a region (and display whatever text you need to).

Detecting touch inside a irregular shape in ImageView

I have an ImageView which has a transparent drawable with a circle at the center like (http://wallpaperswide.com/circle_outline-wallpapers.html). Just that the circle is red, and the surrounding are not coloured but are transparent, it is a .png image. So now I will implement Canvas.ondraw(), and when while tracing the user goes outside the circle, the drawing should restart.
The doubt is:
1. How do I detect the boundaries of this image without hardcoding.
2. How do I detect that the user has clicked outside this, as this is not a regular rectangle.
I am doing this to help students trace alphabets, so I want the answer to be generic on the basis of any image in the shape of a letter.
Can it be done this way? If not, what better way can you suggest?
i'd go the easy route: just draw the image and check the colour of the point the user touched. if the alpha channel transparent, the user moved out.
the following code is untested (and very rough). i have no idea if the getDrawingCache trick works.
public class FooBar extends ImageView {
Bitmap b = null;
public FooBar(Context context) {
super(context);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
b = getDrawingCache(true);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_MOVE)
check((int) event.getX(), (int) event.getY());
return super.onTouchEvent(event);
}
private void check(int x, int y) {
if (b != null && Color.alpha(b.getPixel(x, y)) >= 0)
onMovedOutOfShape();
}
private void onMovedOutOfShape() {
Toast.makeText(getContext(), "You're out", Toast.LENGTH_SHORT).show();
}
}
What you're after is almost the same thing as "collision detection for irregular shapes". Googling on that will result in a zillion hits.
But if I had the problem to do, I'd probably bring in one of the game engines/frameworks such as Box2D, AndEngine, libGDX, or BatteryTech. I'd combine a few simple rectangles and curves to build up reactive places over each of my letter images and then use of of the library's pre-optimized collision detection algorithms to do the heavy lifting. I'd also at least look through their open source code to learn how they do their detection.

Scrolling a childscene in AndEngine

I have a problem scrolling my childscene. I have created a CameraScene which i am trying to scroll with a touch event. My childscene is not scrolling, however, if i scroll on the camera attached to the engine the parent scene scrolls fine.
So how do i get my child scene to scroll without the objects attached to myparents scene scrolls along?
public StatsScene(Context context, VertexBufferObjectManager vbo) {
super(new SmoothCamera(0, 0, WITDH, HEIGHT, 0, SPEEDY, 0));
this.setOnSceneTouchListener(new IOnSceneTouchListener() {
#Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
if(pSceneTouchEvent.getAction() == MotionEvent.ACTION_DOWN) {
mTouchY = pSceneTouchEvent.getMotionEvent().getY();
}
else if(pSceneTouchEvent.getAction() == MotionEvent.ACTION_MOVE) {
float newY = pSceneTouchEvent.getMotionEvent().getY();
mTouchOffsetY = (newY - mTouchY);
float newScrollX = getCamera().getCenterX();
float newScrollY = getCamera().getCenterY() - mTouchOffsetY;
getCamera().setCenter(newScrollX, newScrollY);
mTouchY = newY;
}
return true;
}
});
}
I'm not really into AndEngine and I'm not sure if I get your problem right (in your code is nothing about "myparents" or "childscene"), but when something is attached to your scene, then this implies it will move with it. You could scroll your children in the other direction to maintain their position, but that could get you into trouble in the longterm. If it is possible, try to seperate your scrolling scene and your objects, meaning, that they shouldn't be children of each other. Instead, if you want them to keep them related, give them a common parent. If you move one object now, the siblings won't. Hope that helps.
From your description I would think that your parent scene is the one getting your the input so I'm guessing, please correct me if I'm wrong, that you are setting your child scene something like this:
mMainScene.attachChild(mChildScene);
In this case you will have to deal with deviating the input to the child instead of the parent. However, you have a few options here:
If your child scene occupies full screen and you don't need to worry about updating/drawing your parent scene, simply swap scenes with
mEngine.setScene(mChildScene);
If you do need to keep drawing and updating your parent scene check the MenuScene pre-made class and Scene.setChildScene() method, there is one example on how using this in the AndengineExamples project I think. Using this class will let you take the input on the child scene but still drawing and updating your main scene, it even let's you set your child in a modal way.

Previous coordinates of a touched object

I'm programming with Processing, what i need is the equivalent of pmouseX/Y but for touch, but I can't use pmouse because I use multi-touch and I need previous coordinates of each touched point. I don't know if I've made myself clear, to do an example I need to know initial and final coordinates of a swipe
I currently use to get initial coordinates:
public boolean surfaceTouchEvent(MotionEvent me) {
float x0=me.getX(0);
float y0=me.getY(0);
....
....
return super.surfaceTouchEvent(me);
}
I'm not sure if I get your right here, since this seems to be very basic programming, but I'll try.
Just use an ArrayList and add each position there. For different touches, you might want to use a HashMap, like this:
HashMap<MotionEvent, ArrayList<Point2D.Float>> touches = new HashMap<MotionEvent, ArrayList<Point2D.Float>>();
public boolean surfaceTouchEvent(MotionEvent me)
{
float x0=me.getX(0);
float y0=me.getY(0);
if (!touches.containsKey(me))
{
touches.add(me, new ArrayList<Point2D.Float>());
}
else
{
// get previous position
Point2D.Float prevpos = touches.get(me).get(touches.get(me).size() - 1);
}
touches.get(me).add(new Point2D.Float(x0, y0));
....
}
Didn't test this, but that's basically how it would work.

Categories

Resources