英文:
How to loop a function and wait a second between every loop in google maps project in android studio?
问题
以下是您的代码的翻译部分:
import androidx.annotation.DrawableRes;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.view.View;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.Projection;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptor;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import java.util.Random;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
private double currLat = 32.671677;
private double currLng = 35.195678;
private Marker _marker;
private boolean _stopBWasNotPressed = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
private BitmapDescriptor bitmapDescriptorFromVector(Context context, @DrawableRes int vectorDrawableResourceId) {
// ...
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
Button stopB = (Button) findViewById(R.id.stopB);
stopB.setVisibility(View.GONE);
Button resetB = (Button) findViewById(R.id.resetB);
resetB.setVisibility(View.GONE);
LatLng home = new LatLng(currLat, currLng);
_marker = mMap.addMarker(new MarkerOptions().position(home).icon(bitmapDescriptorFromVector(this, R.drawable.car_icon)));
mMap.moveCamera(CameraUpdateFactory.newLatLng(home));
Button startB = (Button) findViewById(R.id.startB);
startB.setVisibility(View.VISIBLE);
startB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Button startB = (Button) findViewById(R.id.startB);
startB.setVisibility(View.GONE);
final Button stopB = (Button) findViewById(R.id.stopB);
stopB.setVisibility(View.VISIBLE);
while (_stopBWasNotPressed) {
new Handler().postDelayed(new Runnable() {
public void run() {
startMoving();
}
}, 1000);
}
}
});
}
public int generateRandomDirection(){
// ...
}
public void startMoving(){
// ...
}
public void stopButtonClick(View view) {
_stopBWasNotPressed = false;
Button stopB = (Button) findViewById(R.id.stopB);
stopB.setVisibility(View.GONE);
final Button resetB = (Button) findViewById(R.id.resetB);
resetB.setVisibility(View.VISIBLE);
resetB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
_marker.setVisible(false);
currLat = 32.671677;
currLng = 35.195678;
onMapReady(mMap);
}
});
}
}
请注意,翻译仅限于代码部分,不包括代码的解释或其他说明。如果您有任何进一步的问题,请随时提问。
英文:
I want to create a program that mark a place on the google map and every second from when I push the "Start" button the marker would jump a km to a random direction until I push the "Stop" button.
I want the marker to jump, wait a second, jump, wait a second and so on... Until I push the "Stop" button.
When I am using the "while" loop the program stuck even before the showing of the "Stop" button.
But if I don't use the loop it's working good. Can you help me please?
This is my code:
import androidx.annotation.DrawableRes;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.FragmentActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.view.View;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.Projection;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptor;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import java.util.Random;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
private double currLat = 32.671677;
private double currLng = 35.195678;
private Marker _marker;
private boolean _stopBWasNotPressed = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
// Setting the icon instead of the default marker.
private BitmapDescriptor bitmapDescriptorFromVector(Context context, @DrawableRes int vectorDrawableResourceId) {
Drawable background = ContextCompat.getDrawable(context, R.drawable.car_icon);
background.setBounds(0, 0, background.getIntrinsicWidth(), background.getIntrinsicHeight());
Drawable vectorDrawable = ContextCompat.getDrawable(context, vectorDrawableResourceId);
vectorDrawable.setBounds(40, 20, vectorDrawable.getIntrinsicWidth() + 40, vectorDrawable.getIntrinsicHeight() + 20);
Bitmap bitmap = Bitmap.createBitmap(background.getIntrinsicWidth(), background.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
background.draw(canvas);
vectorDrawable.draw(canvas);
return BitmapDescriptorFactory.fromBitmap(bitmap);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Hide the Stop button.
Button stopB = (Button) findViewById(R.id.stopB);
stopB.setVisibility(View.GONE);
// Hide the Reset button.
Button resetB = (Button) findViewById(R.id.resetB);
resetB.setVisibility(View.GONE);
// Add a marker in my home and move the camera.
LatLng home = new LatLng(currLat, currLng);
_marker = mMap.addMarker(new MarkerOptions().position(home).icon(bitmapDescriptorFromVector(this, R.drawable.car_icon)));
mMap.moveCamera(CameraUpdateFactory.newLatLng(home));
// Show the Start button.
Button startB = (Button) findViewById(R.id.startB);
startB.setVisibility(View.VISIBLE);
startB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// Hide the Start button.
Button startB = (Button) findViewById(R.id.startB);
startB.setVisibility(View.GONE);
// Show the Stop button.
final Button stopB = (Button) findViewById(R.id.stopB);
stopB.setVisibility(View.VISIBLE);
while (_stopBWasNotPressed) {
// Making the program wait a second until it moving the marker again.
new Handler().postDelayed(new Runnable() {
public void run() {
startMoving();
}
}, 1000); // 1 second.
}
}
});
}
// This func generates a random number to use as a direction.
public int generateRandomDirection(){
final int min = 1;
final int max = 4;
final int random = new Random().nextInt((max - min) + 1) + min;
return random;
}
// This func makes the new location and sends it to the animateMarker func.
public void startMoving(){
int directionNumber = generateRandomDirection();
final LatLng toPos;
switch(directionNumber) {
case 1:
toPos = new LatLng((currLat + 0.01), currLng); // North.
_marker.setPosition(toPos);
break;
case 2:
toPos = new LatLng((currLat - 0.01), currLng); // South.
_marker.setPosition(toPos);
break;
case 3:
toPos = new LatLng(currLat, (currLng + 0.01)); // East.
_marker.setPosition(toPos);
break;
default:
toPos = new LatLng(currLat, (currLng - 0.01)); // West.
_marker.setPosition(toPos);
break;
}
}
public void stopButtonClick(View view) {
_stopBWasNotPressed = false; // Stops the while loop.
// Hide the Stop button.
Button stopB = (Button) findViewById(R.id.stopB);
stopB.setVisibility(View.GONE);
// Show the Reset button.
final Button resetB = (Button) findViewById(R.id.resetB);
resetB.setVisibility(View.VISIBLE);
resetB.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
_marker.setVisible(false);
currLat = 32.671677;
currLng = 35.195678;
onMapReady(mMap);
}
});
}
}
答案1
得分: 0
我搜索了一下,发现不能同时使用 while 循环和 delay 函数,所以我将代码更改为以下形式:
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
while (_stopBWasNotPressed) {
try {
Thread.sleep(1000); // 使程序等待一秒钟后继续执行。
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
@Override
public void run() {
startMoving();
}
});
}
}
};
Thread myThread = new Thread(runnable); // 为标记移动创建一个线程。
myThread.start();
英文:
I searched a bit and I found that I can't use the while loop and the delay function together so I changed it to this:
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
while (_stopBWasNotPressed) {
try {
Thread.sleep(1000); // Making the program wait a second until it continues.
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
@Override
public void run() {
startMoving();
}
});
}
}
};
Thread myThread = new Thread(runnable); // Creating a thread for the marker movement.
myThread.start();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论