how to programmatically move a mapView (osmdroid) - java

I have a LinearLayout with a mapView, zoomIn button, zoomOut button.
the app receives touchevents and it is supposed to manage the LinearLayout children with the given information (X coordinate, Y coordinate , type of touch event)
I am able to zoomIn and ZoomOut with the following code, but I am not able to move the map:
#Override
public boolean onTouch(View arg0, MotionEvent event) {
int action = event.getAction();
switch(action)
{
case MotionEvent.ACTION_DOWN:
savedTouchedX = event.getX();
savedTouchedY = event.getY();
break;
case MotionEvent.ACTION_MOVE:
doPanning(event, mapView);
break;
case MotionEvent.ACTION_UP:
doPanning(event, mapView);
savedTouchedX = -1;
savedTouchedY = -1;
break;
default:
break;
}
return true;
}
});
//move mapView
private boolean doPanning(MotionEvent e, MapView mapView)
{
if(savedTouchedX >= 0 && savedTouchedY >= 0)
{
IGeoPoint mapCenter = mapView.getMapCenter();
GeoPoint panToCenter = new GeoPoint((int)(mapCenter.getLatitudeE6() + (e.getY() - savedTouchedY) * 1E5),(int)(mapCenter.getLongitudeE6() - (e.getX() - savedTouchedX) * 1E5));
mapView.getController().setCenter(panToCenter);
}
savedTouchedX = e.getX();
savedTouchedY = e.getY();
return true;
}
....
public void lookForButton(String msg){
String[] strArray = msg.split(" ");
final MotionEvent m;
int x=Integer.valueOf(strArray[1]);
int y=Integer.valueOf(strArray[2]);
int type=Integer.valueOf(strArray[3]);
switch (type){
case 2:
m = MotionEvent.obtain(226707,226707,0/*ACTION_DOWN*/,x,y,0);
runOnUiThread(new Runnable() {
public void run() {
memecontentView.dispatchTouchEvent(m);
}
});
break;
case 3:
m = MotionEvent.obtain(226707,226707,1/*ACTION_UP*/,x,y,0);
runOnUiThread(new Runnable() {
public void run() {
memecontentView.dispatchTouchEvent(m);
}
});
break;
case 5:
m = MotionEvent.obtain(226707,226707,2/*ACTION_MOVE*/,x,y,0);
runOnUiThread(new Runnable() {
public void run() {
memecontentView.dispatchTouchEvent(m);
}
});
break;
}
}
public void ZoomInButton(View v){
mapView.getController().zoomIn();
}
public void ZoomOutButton(View v){
mapView.getController().zoomOut();
}
How can I programmatically move mapview with the given information (X coordinate, Y coordinate , type of touch event)?

You can call mapView.scrollTo(x, y).
Another possibility is mapView.getController().animateTo() (with animation) or mapView.getController().setCenter() (without animation).
It takes an IGeoPoint as a parameter which you can instantiate with your coordinates:
new GeoPoint(latitude, longitude)

Related

Android: how to reduce trigger duration of onSingleTapConfirmed?

I have got a view where I use :
class GestureTap extends GestureDetector.SimpleOnGestureListener {
#Override
public boolean onSingleTapConfirmed(MotionEvent e) {
}
}
I think that onSingleTapConfirmed is launched after a too long duration.
Is it possible to reduce this duration ?
Thanks.
The duration is a final value, you can not change it.
so,you may adjust your code strategy,like this:
int MOVE_RANGE= 100;
int TIME_LONG_PRESS = 1000;
Runnable r = Runnable();
#Override
public boolean onTouch(View v, MotionEvent event) {
int x = (int) event.getX();
int y = (int) event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_UP:
handler.removeCallbacks(r);
break;
case MotionEvent.ACTION_MOVE:
if (Math.abs(mLastMotionX - x) > TOUCH_MAX|| Math.abs(mLastMotionY - y) > TOUCH_MAX) {
//Beyond the long press range
handler.removeCallbacks(r);
}
break;
case MotionEvent.ACTION_DOWN:
handler.removeCallbacks(r);
mLastMotionX = x;
mLastMotionY = y;
// Start counting
handler.postDelayed(r, TIME_LONG_PRESS );
break;
}
return true;
}

Resize ImageView with only one finger movement instead of two

I'm trying to change an ImageView's height with only one finger movement (upside or downside). The code below changes height with two fingers (like pinching or reverse). How can I modify this code to do what I want? Thanks.
public class MainActivity extends Activity {
private ImageView iv;
private Matrix matrix = new Matrix();
private float scale = 1f;
private ScaleGestureDetector SGD;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
iv = iv=(ImageView)findViewById(R.id.imageView);
SGD = new ScaleGestureDetector(this, new ScaleListener());
}
public boolean onTouchEvent(MotionEvent ev) {
SGD.onTouchEvent(ev);
return true;
}
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener
{
#Override
public boolean onScale(ScaleGestureDetector detector) {
scale *= detector.getScaleFactor();
scale = Math.max(0.1f, Math.min(scale, 5.0f));
matrix.setScale(1, scale);
iv.setImageMatrix(matrix);
return true;
}
}
}
Use GestureDetector for scroll:
#Bind(R.id.container)
ViewGroup container;
#Bind(R.id.image)
ImageView image;
private GestureDetectorCompat detector;
private float yscale = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
ButterKnife.bind(this);
image.setScaleType(ImageView.ScaleType.MATRIX);
detector = new GestureDetectorCompat(this, new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
Matrix m = new Matrix();
yscale += distanceY / container.getHeight();
m.setScale(1, yscale, 0, 0);
image.setImageMatrix(m);
return true;
}
});
}
#Override
public boolean onTouchEvent(MotionEvent event) {
return detector.onTouchEvent(event);
} detector.onTouchEvent(event);
}
change
public boolean onTouchEvent(MotionEvent ev) {
SGD.onTouchEvent(ev);
return true;
}
to
public boolean onTouchEvent(MotionEvent ev) {
switch(ev.getActionMasked()) {
case MotionEvent.ACTION_DOWN, case MotionEvent.ACTION_UP:
SGD.onTouchEvent(ev);
break;
return true;
}
This code snipet should help you to detect up and down
private VelocityTracker mVelocityTracker = null;
#Override
public boolean onTouchEvent(MotionEvent event) {
int index = event.getActionIndex();
int action = event.getActionMasked();
int pointerId = event.getPointerId(index);
switch(action) {
case MotionEvent.ACTION_DOWN:
if(mVelocityTracker == null) {
// Retrieve a new VelocityTracker object to watch the velocity of a motion.
mVelocityTracker = VelocityTracker.obtain();
}
else {
// Reset the velocity tracker back to its initial state.
mVelocityTracker.clear();
}
// Add a user's movement to the tracker.
mVelocityTracker.addMovement(event);
break;
case MotionEvent.ACTION_MOVE:
mVelocityTracker.addMovement(event);
// When you want to determine the velocity, call
// computeCurrentVelocity(). Then call getXVelocity()
// and getYVelocity() to retrieve the velocity for each pointer ID.
mVelocityTracker.computeCurrentVelocity(1000);
// Log velocity of pixels per second
// Best practice to use VelocityTrackerCompat where possible.
Log.d("", "X velocity: " +
VelocityTrackerCompat.getXVelocity(mVelocityTracker,
pointerId));
Log.d("", "Y velocity: " +
VelocityTrackerCompat.getYVelocity(mVelocityTracker,
pointerId));
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
// Return a VelocityTracker object back to be re-used by others.
mVelocityTracker.recycle();
break;
}
return true;
}

Rotating an image with onTouchListener without scaling it

I have got this simple code to rotate an image with onTouchListener, but it seems to be zooming in and out on the image as well. I am really new to using onTouchListener. Could someone tell me what is happening, or how to fix this. Anything helps thanks:)
public class MainActivity extends Activity implements OnTouchListener {
private ImageView dialer;
private float y=0;
public boolean onTouch(View v, MotionEvent event) {
double r=Math.atan2(event.getX()-dialer.getWidth()/2, dialer.getHeight()/2-event.getY());
int rotation=(int)Math.toDegrees(r);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
//x=event.getX();
y=event.getY();
updateRotation(rotation);
break;
case MotionEvent.ACTION_UP:
break;
}//switch
return true;
}//onTouch
private void updateRotation(double rot){
float newRot= new Float(rot);
Bitmap bitmap=BitmapFactory.decodeResource(getResources(),R.drawable.round_button_big);
Matrix matrix= new Matrix();
matrix.postRotate(newRot,bitmap.getWidth()/2,bitmap.getHeight()/2);
if(y>250){
Bitmap reDrawnBitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
dialer.setImageBitmap(reDrawnBitmap);
}
else{
Bitmap reDrawnBitmap=Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
dialer.setImageBitmap(reDrawnBitmap);
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dialer = (ImageView) findViewById(R.id.image);
dialer.setOnTouchListener(this);
}//onCreate
}
Try to use this code on touch event:
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// reset the touched quadrants
for (int i = 0; i < quadrantTouched.length; i++) {
quadrantTouched[i] = false;
}
allowRotating = false;
startAngle = getAngle(event.getX(), event.getY());
break;
case MotionEvent.ACTION_MOVE:
double currentAngle = getAngle(event.getX(), event.getY());
rotateDialer((float) (startAngle - currentAngle));
startAngle = currentAngle;
break;
case MotionEvent.ACTION_UP:
allowRotating = true;
break;
}
// set the touched quadrant to true
quadrantTouched[getQuadrant(event.getX() - (dialerWidth / 2), dialerHeight - event.getY() - (dialerHeight / 2))] = true;
detector.onTouchEvent(event);
return true;
And here you can find an example :http://code.tutsplus.com/tutorials/android-sdk-creating-a-rotating-dialer--mobile-8868

Want to drop a View onto another View in android

Hey Friends help me to achieve the objective. I am newbie to the android development and the only thing I want to do is that I am trying to drag a button and drop it onto the other View(i.e RelativeLayout) the very first thing I have done the code for the drag.
rootView = inflater.inflate(R.layout.fragment_game_map,container,false);
button1 = (Button) rootView.findViewById(R.id.button1);
button1.setOnLongClickListener(new View.OnLongClickListener() {
#Override
public boolean onLongClick(View v) {
ClipData.Item item = new ClipData.Item((CharSequence)v.getTag());
String[] mimeTypes = {ClipDescription.MIMETYPE_TEXT_PLAIN};
ClipData dragData = new ClipData(v.getTag().toString(),mimeTypes, item);
View.DragShadowBuilder myShadow = new View.DragShadowBuilder(button1);
v.startDrag(dragData,myShadow,null,0);
return true;
}
});
button1.setOnDragListener(new View.OnDragListener() {
#Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_STARTED:
layoutParams = (RelativeLayout.LayoutParams) v.getLayoutParams();
Log.d(TAG, "Action is DragEvent.ACTION_DRAG_STARTED");
// Do nothing
break;
case DragEvent.ACTION_DRAG_ENTERED:
Log.d(TAG, "Action is DragEvent.ACTION_DRAG_ENTERED");
int x_cord = (int) event.getX();
int y_cord = (int) event.getY();
break;
case DragEvent.ACTION_DRAG_EXITED:
Log.d(TAG, "Action is DragEvent.ACTION_DRAG_EXITED");
x_cord = (int) event.getX();
y_cord = (int) event.getY();
layoutParams.leftMargin = x_cord;
layoutParams.topMargin = y_cord;
v.setLayoutParams(layoutParams);
break;
case DragEvent.ACTION_DRAG_LOCATION:
Log.d(TAG, "Action is DragEvent.ACTION_DRAG_LOCATION");
x_cord = (int) event.getX();
y_cord = (int) event.getY();
break;
case DragEvent.ACTION_DRAG_ENDED:
Log.d(TAG, "Action is DragEvent.ACTION_DRAG_ENDED");
// Do nothing
break;
case DragEvent.ACTION_DROP:
Log.d(TAG, "ACTION_DROP event");
// Do nothing
break;
default:
break;
}
return true;
}
});
button1.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
ClipData data = ClipData.newPlainText("", "");
View.DragShadowBuilder shadowBuilder = new View.DragShadowBuilder(button1);
button1.startDrag(data, shadowBuilder, button1, 0);
button1.setVisibility(View.INVISIBLE);
return true;
}
else
{
return false;
}
}
});
return rootView;
}
but the second thing I don't have Idea to do.. that is I want to drop it onto the RelativeLayout but the RelativeLayout can only allow one button to be drop on it.
You missing the point of DragLiatenr. DragListenr listen to event of dragging, and handle them properly, so if your RelativeLayout not register to DragEvent he can't handle them.
Actually for what you asking you just need to listen for ACTION_DROP, and return true for all the others events.
Your could should like something like:
final RelativeLayout container; //You need to initialize your Relativelayout here
container.setOnDragListener(new View.OnDragListener() {
#Override
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DROP:
Log.d(TAG, "ACTION_DROP event");
((ViewGroup)v.getParent()).removeView(v); //you must first remove view from it former container
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
container.addView(v, params); // of course you need to modify params for your need
return true;
break;
default:
return true;
}
}
});
Also why you put onTouchListenr you never use?

Android OnTouchListener interferes OnClickListener

I have got an Activity with a function, where I can create a new ImageView.
I would like to move the ImageView, so implemented a new OnTouchListener. That is working great, but I would also like to add a LongClickListener and here is my problem:
My LongClickListener starts one time when I am moving the ImageView.
What can I do to fix this?
public ImageView neuesDefaultBild(int x, int y, int id){
ImageView iv=new ImageView(this);
iv.setImageResource(R.drawable.usericon);
iv.setId(id);
iv.setX(x);
iv.setY(y);
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
params.width=180;
params.height=130;
iv.setLayoutParams(params);
iv.setLongClickable(true);
iv.setFocusable(true);
iv.setFocusableInTouchMode(true);
iv.setEnabled(true);
iv.setOnTouchListener(new View.OnTouchListener(){
public boolean onTouch(View v, MotionEvent event) {
boolean defaultResult = v.onTouchEvent(event);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
//Get the coords from the Event
int x_cord = (int) event.getRawX();
int y_cord = (int) event.getRawY();
v.setX(x_cord-90);
v.setY(y_cord-130);
return true;
default:
return defaultResult;
}
return false;
}
});
iv.setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View v) {
Toast.makeText(getApplicationContext(), "Long!!", Toast.LENGTH_SHORT).show();
return false;
}
});
return iv;
}
OnclickListener can be set using OnTouchListener itself
Just set a flag
private int boolean onClick;
switch (event.getAction())
{
case MotionEvent. ACTION_DOWN:
{
onClick = true;
break ;
}
case MotionEvent. ACTION_MOVE:
{
onClick = false;
break ;
}
case MotionEvent. ACTION_UP:
{
if(onClick)
{
//Call your own click listener
}
break;
}
}

Categories

Resources