Android images and buttons - android

What should I use if I want to have buttons on an image? I mean, being able to click on certain points of an image and see some info.
What if I want to display text on that points? Imagine I am having a map of my neighbor for example, and I want some info to be displayed (for example my home). And if someone press on my home he could see further details, like my name, my phone and so on. The image(aka the map) will be stable, it wont change, like a background.

You'll have to implement the method onTouch from the interface OnTouchListener. For example:
OnTouchListener listener = new OnTouchListener() {
#Override
public false onTouch(View v, MotionEvent event) {
if(!event.getAction() == MotionEvent.ACTION_DOWN)
return false; //If the touch event was not putting the finger down on the screen, return false(Actions may be move, up, and so on)
final float x = event.getX();
final float y = event.getY();
if(x and y are in some range)
doFirstThing();
else if(x and y are in another range..)
doSecondThing();
//... and so on...
//In the end, you must return a boolean saying whether you "consumed" the event - if you handled the event or not.
}
}
And don't forget to set the listener as the OnTouchListener for your ImageView!
imageView.setOnTouchListener(listener);

I believe for what you are trying to achieve you don't need to use buttons. Instead, create a custom view, in your onDraw method draw the images and handle the onTouch events as Jong suggested. Once you detected a click on your home for example, you could create another view with info about it and display it to user.
For info on how to create custom view you may refer to this queestion for example. Google around for it

Related

Android How to detect swipe between two touch points on image view

I have an Imageview with different number of touch points on them. It basically an app which is detecting the swipe between 2 touch points and not allowing the user to swipe any other point or in or out of other direction. It should constrict user to just swipe between two touch points.
Just take a look at following picture:
Now the user should start swiping from point 1 to point 2. if the swipe is not started from starting point 1, it should not color the path between point 1 and point 2.
But if the user successfully swipe between the point 1 and point 2 now swipe between point 2 to 3 should be enabled. Thus user should go through Point 1 to 2, Point 2 to 3 , Point 3 to 4 , point 4 to point 5 to complete round 1.
Please tell me how to achieve this functionality . I know about gestures, gesture overlay etc but none of them fits to my condition as they uses general touch events and gesture directions.
Please suggest me the way to achieve this and keep in mind I want to make this app to be able to run on all type of devices , so I can simply give the hard coded x,y values.
Edit : on Demand
I am posting the link of the app on play store who has same functionality , But I do not know How they are achieving this functionality .
https://play.google.com/store/apps/details?id=al.trigonom.writeletters
If each touch point can be created as individual views(e.g. ImageView), then you can create an inViewInBounds() function.
I used code from here to create code where I needed to detect finger press movement over multiple imageViews:
Rect outRect = new Rect();
int[] location = new int[2];
//Determine if a touch movement is currently over a given view.
private boolean inViewInBounds(View view, int x, int y){
view.getDrawingRect(outRect);
view.getLocationOnScreen(location);
outRect.offset(location[0], location[1]);
return outRect.contains(x, y);
}
To use this function, on a parent view to all those child touch points, set the Click and Touch Listeners:
//This might look redundant but is actually required: "The empty OnClickListener is required to keep OnTouchListener active until ACTION_UP"
parentView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {}
});
//All the work gets done in this function:
parentView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int)event.getRawX();
int y = (int)event.getRawY();
// ** myTouchPoint might be an array that you loop through here...
if ( inViewInBounds(myTouchPoint, x, y) ) doLogic(myTouchPoint);
return false;
}
});
The code above only shows detecting when one of your views are 'touched'.
if none are 'touched' but a view is 'active' (e.g. When a touch is detected, set a variable like: viewLastTouched = myTouchPoint) then you would call something like drawingLine(viewLastTouched, x, y) function - for whatever it needed to do to draw the line and/or detect boundaries etc.
They are not using android native java code to build this app.
The app is running with this code
import Runtime.MMFRuntime;
public class Main extends MMFRuntime {
}
This in turn is from https://github.com/ClickteamLLC/android/blob/master/docs/index.md
This is used to package apps / games written using - http://www.clickteam.com/clickteam-fusion-2-5

Is there a offset between onTouchEvent and onTouchListener?

I have developed a game that shoots when player touches the screen by using onTouchListener for my custom SurfaceView and Thread.
But now I want to change the approach and instead of onTouchListener I added onTouchEvent to the SurfaceView o my Activity.
The problem is that I get some kind of offset when I click on the emulator.
Everything is working great, except that offset keeps appearing and I don't understand why.
Also let me mention that my app is running in landscape mode, maybe this is relevant.
I suspect that it isn't working properly because onTouchListener was added to the view and depended on it, but onTouchEvent doesn't depend on the view.
Also my view doesn't have any padding or margin properties, it is full-screen view (fill_parent).
Does anyone have any ideas on this?
I have done my application, and everything works correctly now, but i still do not know what the problem was.
After lots of debugging of my application the onTouchEvent returned random Y values that were always higher than the ones that the onTouchListener returned. And i am not sure why this is hapening since my view that recognizes the onTouchListener is a full-screen view.
So i figured out a way to get passed this by doing some math.
The first function that the android calls is the onTouch method which gives the correct values but just for one touch. I needed it to give right values even on the MotionEvent.ACTION_MOVE so i noticed that MotionEvent.ACTION_MOVE is actually doing correctly depending on the first touch recognized by the onTouchEvent.
So i just got the coordinate Y from the onTouch and the different coordinate with the offset from onTouchEvent calculated the difference and in every onTouchEvent from there, until the user lifts up their finger, i just subtract that difference and that gives me the correct value.
If anyone else has this problem, and doesn't know how to fix it, here is my code, maybe it will be helpful.
#Override
public boolean onTouchEvent(MotionEvent arg1) {
/*you can only touch when the thread is running*/
if(game.state() != STATE_PAUSE){
if(arg1.getAction() == MotionEvent.ACTION_DOWN){
coordinateX = arg1.getX();
coordinateY = arg1.getY();
differenceY = Math.abs(coordinateY - touchedY);
coordinateY = coordinateY - differenceY;
shootingIsOkay = true;
game.setDrawCircle(coordinateX,coordinateY);
}
if(arg1.getAction() == MotionEvent.ACTION_MOVE){
coordinateX = arg1.getX();
coordinateY = arg1.getY();
coordinateY = coordinateY - differenceY;
shootingIsOkay = true;
game.setDrawCircle(coordinateX,coordinateY);
}
if(arg1.getAction() == MotionEvent.ACTION_UP){
shootingIsOkay = false;
}
}
return false;
}
And the onTouch method that is called from the onTouchListener that depends on the view is just simple, here:
#Override
public boolean onTouch(View arg0, MotionEvent arg1) {
touchedY = arg1.getY();
return false;
}
If anyone knows how to fix this problem, please post your answer, i am very curious why this is happening

How to start a new scene while touchevent in libgdx

I am developing a small agme in android with libgdx. I placed an actor as button. I want to navigate to other screen while clicking on that actor. How is this possible.
Thanks in advance
You just need to add a InputListener to your Actor:
actor.addListener( new InputListener {
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
game.setScreen(new OtherScreen());
return true;
}
});
Here you give the Actor an InputListener (there are many other methods you need to override). This InputListener reacts on touch down methods and if it is touched, you set the games Screen (you need to have the game instance somewhere, so that you are able to set its Screen) to the OtherScreen.
The Actor must be touchable (setTouchable(true)) and visible (setVisible(true)), to recieve the Events.
Hope it helps.

Dragging objects using ACTION_MOVE

I am trying to make all my drawn Sprites dragable for a little game. It should be able to touch anywhere and the sprites should move the same distance, the finger moves.
With the following method they will move on an ACTION_MOVE event, but only very slow, a shorter distance and sometimes they dont:
addToX/Y only adds the gap to the coordinates of the sprites
#Override
public boolean onTouchEvent(MotionEvent evt){
switch(evt.getAction()){
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
if(getHistorySize() > 0){
for(int i = 1, n = evt.getHistorySize(); i < n; i++){
int calcX = (int) getHistoricalX(i) - (int) getHistoricalX(i-1);
int calcY = (int) getHistoricalY(i) - (int) getHistoricalY(i-1);
for(Sprite sprite : spriteList) {
sprite.addToX(calcX);
sprite.addToY(calcY);
}
}
}
return true;
}
Any ideas on this?
Assuming your Sprite class is an (potentially-indirect) extension of android.view.View, then you can use setOnDragListener() to define an onDrag() override for them. Then you can use startDrag(...) on them to begin the drag. This is typically triggered by a long-press gesture on the view to be dragged, but in your case you can trigger it from within onTouchEvent() in ACTION_MOVE once (or even ACTION_DOWN). See here for more details on these methods.
Also, with respect to the code you posted, one issue with it that probably explains why it doesn't always work is that you are only using the historical points (which may or may not have accumulated on any particular call to onTouchEvent()). Whether or not getHistorySize() is greater than 0, you should still also use evt.getX() and evt.getY() on each call to onTouchEvent(). But of course, if you use the drag listener approach I suggested instead, you won't need to worry about this.
Update per comment
If you want to move all of the sprites at once, you can put the sprites into a full-screen FrameLayout and attach a GestureDetector that uses a GestureDetector.SimpleOnGestureListener to capture onScroll() callbacks and then calls scrollTo() on the FrameLayout. When the parent FrameLayout scrolls, all of its children sprites will appear to move together.

android need advice to start develop using gestures

I have a canvas.DrawText. I want to use gestures to dynamically change the text color and font. This is all working nice using a popup view class. But I want to make this more direct maybe using Fling scroll.
There are millions of colors and by sliding finger on the screen I thought I could increase/decrease the colorInteger and send it to paint.setColor(colorInteger ); before I draw. I have tried all day using various methods.
I have public boolean onTouchEvent(MotionEvent event) {
I know I must catch the x/y in MotionEvent.ACTION_DOWN
Wanted to use the screen left edge for color change and screen right for Font change. I have 21 ttf fonts.
The thing is, I see there is the OnGestureListener onscroll implementation but that will disable my onTouchEvent right? I have lots of movement going on in there.
public boolean onTouchEvent(MotionEvent event) {
Any idea?
You can use GestureDetector. Implement a GestureDetector.OnGestureListener and catch gestures there.
class MyActivity extends Activity implements GestureDetector.OnGestureListener {
// ....
gestureDetector = new GestureDetector(getContext(), this);
Provide GestureDetector with touch events like this:
#Override
public boolean onTouchEvent(MotionEvent event) {
if (gestureDetector.onTouchEvent(event))
return true;
else return super.onTouchEvent(event);
}
In GestureDetector.OnGestureListener's onDown you must return true if you want to process this gesture. E.g. then the user puts his finger donw in a specified area return true, and false otherwise. If false is returned here, complicated sequences (like fling or scroll) started with this event will not be detected.

Categories

Resources