Positioning and zooming Google map inside RecyclerView - java

Part of my application uses RecyclerView with CardView elements, and every CardView element contains Google Map which draws specific route. On every map I am zooming and positioning route inside of map so it can fill whole view but problems arrive when I begin to scroll and every next CardView doesn't position my route inside a map but leaves it unzoomed and unpositioned. Picture is below:
Im using onBindViewHolder to setup map and route drawing and then I'm using zoomToLatLng to zoom the map
#Override
public void onBindViewHolder(RouteViewHolder holder, int position) {
holder.destination.setText(routesCV.get(position).getDestination());
holder.startingPoint.setText(routesCV.get(position).getStartingPoint());
GoogleMap gMap = holder.map.getMap();
if (gMap != null) {
ArrayList<PointModel> mapPosition = routesCV.get(position).getPoints();
ArrayList<LatLng> points = new ArrayList<LatLng>();
for (PointModel item : mapPosition) {
points.add(new LatLng(item.getLatitude(),item.getLongitude()));
}
for (LatLng item : points) {
gMap.addMarker(new MarkerOptions().position(item));
}
zoomMapToLatLngBounds(holder.linearlayout, gMap, points);
}
}
Zoom method:
private void zoomMapToLatLngBounds(final LinearLayout layout,final GoogleMap mMap, final ArrayList<LatLng> bounds){
LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder();
for (int i=0; i<bounds.size(); i++) {
boundsBuilder.include(bounds.get(i));
}
final LatLngBounds boundsfinal = boundsBuilder.build();
final ViewTreeObserver vto = layout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#SuppressWarnings("deprecation")
#Override
public void onGlobalLayout() {
layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(boundsfinal, 25));
}
});
From logs public void onGlobalLayout() doesnt even execute. Do u know what might be the problem ? Tnx!

I made a OnMapLoadedCallback() function to position the map. It works now!

Related

changing getMap to GetMapAsync

I am trying to create an interactive infoWindow based on one of the answers from Stack Overflow.
However, I am getting an error with getMap() used in the code. Although I've tried with getMapAsync(), I'm unable to resolve the problem. Please help me. If any new code is available for an interactive infowindow with a button, then please share the code.
public class MainActivity extends AppCompatActivity {
private ViewGroup infoWindow;
private TextView infoTitle;
private TextView infoSnippet;
private Button infoButton1, infoButton2;
private OnInfoWindowElemTouchListener infoButtonListener;
static final LatLng latlng1 = new LatLng(28.5355, 77.3910);
static final LatLng latlng2 = new LatLng(28.6208768, 77.3726377);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final SupportMapFragment mapFragment = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
final MapWrapperLayout mapWrapperLayout = (MapWrapperLayout)findViewById(R.id.map_relative_layout);
final GoogleMap googleMap = mapFragment.getMap();
// MapWrapperLayout initialization
// 39 - default marker height
// 20 - offset between the default InfoWindow bottom edge and it's content bottom edge
mapWrapperLayout.init(googleMap, getPixelsFromDp(this, 39 + 20));
// We want to reuse the info window for all the markers,
// so let's create only one class member instance
this.infoWindow = (ViewGroup)getLayoutInflater().inflate(R.layout.custom_infowindow, null);
this.infoTitle = (TextView)infoWindow.findViewById(R.id.nameTxt);
this.infoSnippet = (TextView)infoWindow.findViewById(R.id.addressTxt);
this.infoButton1 = (Button)infoWindow.findViewById(R.id.btnOne);
this.infoButton2 = (Button)infoWindow.findViewById(R.id.btnTwo);
// Setting custom OnTouchListener which deals with the pressed state
// so it shows up
this.infoButtonListener = new OnInfoWindowElemTouchListener(infoButton1, getResources().getDrawable(R.drawable.btn_bg), getResources().getDrawable(R.drawable.btn_bg)){
#Override
protected void onClickConfirmed(View v, Marker marker) {
// Here we can perform some action triggered after clicking the button
Toast.makeText(MainActivity.this, "click on button 1", Toast.LENGTH_SHORT).show();
}
};
this.infoButton1.setOnTouchListener(infoButtonListener);
infoButtonListener = new OnInfoWindowElemTouchListener(infoButton2, getResources().getDrawable(R.drawable.btn_bg),getResources().getDrawable(R.drawable.btn_bg)){
#Override
protected void onClickConfirmed(View v, Marker marker) {
Toast.makeText(getApplicationContext(), "click on button 2", Toast.LENGTH_LONG).show();
}
};
infoButton2.setOnTouchListener(infoButtonListener);
/*infoWindow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Toast.makeText(getApplicationContext(), "click on infowindow", Toast.LENGTH_LONG).show();
}
});*/
googleMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {
#Override
public View getInfoWindow(Marker marker) {
return null;
}
#Override
public View getInfoContents(Marker marker) {
// Setting up the infoWindow with current's marker info
infoSnippet.setText(marker.getTitle());
infoTitle.setText(marker.getSnippet());
infoButtonListener.setMarker(marker);
// We must call this to set the current marker and infoWindow references
// to the MapWrapperLayout
mapWrapperLayout.setMarkerWithInfoWindow(marker, infoWindow);
return infoWindow;
}
});
// Let's add a couple of markers
googleMap.addMarker(new MarkerOptions()
.position(latlng1)
.title("Source")
.snippet("Comapny Name")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
googleMap.addMarker(new MarkerOptions()
.position(latlng2)
.title("Destination")
.snippet("AmisunXXXXXX")
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE)));
//googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latlng, 15));
googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latlng1, 10));
}
public static int getPixelsFromDp(Context context, float dp) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int)(dp * scale + 0.5f);
}
}
The error is coming because Google has removed getMap(), but I dont know the alternative solution for this.
UPDATE
Define private GoogleMap gMapand implement OnMapReadyCallback in your main Activity and implement onMapReady method
in onMapReady you should write this line
gMap = googleMap, then you can do what you want in onMapReady
getting current location
custom setting for your map
and ...
now it's time to use this lines in your OnCreate method
SupportMapFragment supportMapFragment = (SupportMapFragment)
getSupportFragmentManager().findFragmentById(R.id.map);
supportMapFragment.getMapAsync(this);
it should solve your problem, hope it helped you

how to get direction to the shortest path outside circle in google maps android, when my current location is inside 2 or more circles?

How to get direction to the nearest location outside circle if the blue dots is the current location?
1[1
and how to display markers ONLY around the current location in radius 2000m? I have stored the mapping lanslide in database and it displays when the app launch and it needs 7-9 seconds to load these markers. now i need to display only around the current location in order the app going smooth.
[these are the mapping dots of lanslide]
im doing my final projet, and I have a fEature which is really difficult.
Im on my android project, making a warning application on android about lanslide disaster, I do the mapping dots of lanslide locations and collect about 150 couples of lattitudes and longitudes and put it on database.
I assume if the user inside a circle, they are in lanslide location and they are not safe
the red zone radius is 2KM from the center of circle.
the orange zone radius is 1km from the center of circle.
the yellow zone radius is 500m from the center of circle
when the app is launch, the map will show up and animate the camera to my current location.
and then the app will tell the user if they are safe or not.
if the user OUTSIDE THE CIRCLE, then the user is safe. but,
if the current location inside the circle, then the user is not safe.
WHEN THE USER IS NOT SAFE, THE APP will give direction to shortest path outside the circle.
My app is almost done, except the last feature, I'm out of idea how to figure it out,
HOW THE APP CAN GIVE THE DIRECTION TO THE SHORTEST PATH OUTSIDE A CIRCLE??
unfortunately, how can the app will get direction to the shorthest outside circle for user if the CURRENT LOCATION inside 3 or mores circle ? and what google's libarry i can use for solve this?
how to get direction outside many circles? please help me.
enter image description here
this is my code:
public class MenuMaps extends Fragment implements OnMapReadyCallback {
private static MenuMaps instance = null;
private SupportMapFragment sMapFragment;
private MapView mMapView;
SupportMapFragment mapFragment;
private GoogleMap mMap;
private String[] id, desa, status_des;
boolean markerD[];
private Double latitude, longitude;
private Circle mCircle;
private Marker mMarker;
LatLng lokasisekarang;
boolean mapReady = false;
private GoogleApiClient client;
private GoogleApiClient client2;
public static MenuMaps getInstance() {
if (instance == null) {
instance = new MenuMaps();
Log.d( "MenuMaps", "getInstance");
}
return instance;
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState)
{
Log.d("MenuMaps", "OnCreateView");
View inflatedView = inflater.inflate(R.layout.menu_maps, container, false);
MapsInitializer.initialize(getActivity());
mMapView = (MapView) inflatedView.findViewById(R.id.map);
mMapView.onCreate(savedInstanceState);
mMapView.getMapAsync(this);
Button btnMap = (Button) inflatedView.findViewById(R.id.btnMap);
btnMap.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mapReady)
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
}) ;
Button btnSatellite = (Button) inflatedView.findViewById(R.id.btnSatellite);
btnSatellite.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mapReady)
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
}
});
Button btnHybrid = (Button) inflatedView.findViewById(R.id.btnHybrid);
btnHybrid.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(mapReady)
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
}
});
return inflatedView;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getActivity().setTitle("Menu Maps");
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onStop() {
super.onStop();
}
#Override
public void onResume() {
mMapView.onResume();
super.onResume();
}
#Override
public void onPause() {
super.onPause();
mMapView.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
mMapView.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mMapView.onLowMemory();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public void getLokasi() {
Log.d("desaStatus", "getLokasi");
String url = "http://dharuelfshop.com/skripsi/desaStatus.php/";
StringRequest request = new StringRequest(url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("desaStatus", response);
Gson gson = new Gson();
try {
JSONObject objinduk = new JSONObject(response);
List<DesaStatus> listDesaStatus = gson.fromJson(objinduk.getString("desaStatus"), new TypeToken<List<DesaStatus>>() {
}.getType());
Circle circleTerdekat = null;
Float distanceTerdekat = null;
for (DesaStatus desaStatus : listDesaStatus
) {
Log.d("desaStatus", desaStatus.toString());
LatLng center = new LatLng(desaStatus.lat_bcn,
desaStatus.long_bcn);
MarkerOptions markerOptions = new MarkerOptions()
.position(center)
.title("Desa : " + desaStatus.nama_des)
.snippet("Status : " + desaStatus.jenis_status)
.icon(BitmapDescriptorFactory
.defaultMarker(desaStatus.kode_warna));
mMarker = mMap.addMarker(markerOptions);
CircleOptions CircleOptions = new CircleOptions()
.center(center)
.radius(desaStatus.radius)//in meters
.strokeColor(Color.parseColor(desaStatus.warna_radius))
.strokeWidth(2)
.fillColor(Color.parseColor(desaStatus.warna_radius));
mCircle = mMap.addCircle(CircleOptions);
//hitung distance dan Status circle
float[] distance = new float[2];
Location.distanceBetween( lokasisekarang.latitude, lokasisekarang.longitude,
mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance);
if (circleTerdekat == null) {
circleTerdekat = mCircle;
distanceTerdekat = distance[0];
} else {
if (distance[0] < distanceTerdekat ) {
distanceTerdekat = distance[0];
circleTerdekat = mCircle;
}
}
}
Log.d("circleTerdekat", "center: " + circleTerdekat.getCenter().latitude + " " + circleTerdekat.getCenter().longitude );
if( distanceTerdekat > circleTerdekat.getRadius() ){
Toast.makeText(getContext(), "You are safe, distance from center: " + distanceTerdekat + " radius: " + circleTerdekat.getRadius(), Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getContext(), "You are not safe, distance from center: " + distanceTerdekat + " radius: " + circleTerdekat.getRadius() , Toast.LENGTH_LONG).show();
}
} catch (JSONException error) {
Log.d("desaStatusError", error.toString());
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setTitle("Error woy");
//Message
builder.setMessage("Error " + error); //+ error diganti sama (VolleyError error)
//Message
//builder.setIcon()
builder.setPositiveButton("Refreshh", new DialogInterface.OnClickListener() {
#Override //O nya huruf gede
public void onClick(DialogInterface dialog, int which) {
getLokasi();
}
});
AlertDialog alert = builder.create();
alert.show();
}
});
// menambah request ke request queue
VolleyRequest.getInstance().addToRequestQueue(request);
}
public void getCurrentLocation() {
GpsTracker gps = new GpsTracker(getActivity());
if (gps.canGetLocation()) { // gps enabled
//Getting longitude and latitude
latitude = gps.getLatitude();
longitude = gps.getLongitude();
lokasisekarang = new LatLng(latitude, longitude);
drawMarkerWithCircle(lokasisekarang);
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(lokasisekarang, 14f));
// \n is for new line
//Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
}
else {
// can't get location
// GPS or Network is not enabled
// Ask user to enable GPS/network in settings
gps.showSettingsAlert();
//gps.stopUsingGPS();
}
}
private void drawMarkerWithCircle(LatLng lokasisekarang) {
MarkerOptions markerOptions = new MarkerOptions()
.position(lokasisekarang)
.title("You are here")
.snippet("here")
.icon(BitmapDescriptorFactory
.defaultMarker(HUE_BLUE));
mMarker = mMap.addMarker(markerOptions);
CircleOptions circleOptions = new CircleOptions()
.center(lokasisekarang)
.radius(2000)
.strokeWidth(2)
.strokeColor(Color.BLUE)
.fillColor(Color.parseColor("#500084d3"));
mMap.addCircle(circleOptions);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mapReady = true;
mMap = googleMap;
getCurrentLocation();
getLokasi();
if (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true); // buat enable button location
}}
In order to show directions you need 2 points the origin and destination. The origin in this case will be your user's location.
Finding the destination point:
1) Currently you are storing the centre of these circular zones and their radii (500m, 1km etc). In addition to these you can easily calculate for each circle 4 'safe' points that lie along 4 directions (say N,S,E,W) and store them.
2) These points divide your circle into 4 quadrants. Now all you need to do is find which quadrant of the circle the user's current location is in and compare the distance between the points forming the quadrant and choose the lower of the two as your destination.
3) Use the Google Maps Directions API to show directions .
If you want to increase the accuracy of the algorithm all you need to do is increase the number of directions which will effectively divide your circle into more smaller parts and the destination will be more optimal.
Here '4' was just an arbitrary number . You can have different number based on number of safe points you choose and that will determine the accuracy of the algorithm
EDIT: Handling multiple circles intersecting is also easy. All you need to do then is instead of calculating the shortest for 1 circle you calculate for all the circles where the point lies and then find the min distance
Algorithm:
1) For each circle choose 'n' safe points. These 'n' points will form n - 1 sectors in the circle.
2) Get the current location of the user ( say A) and find all the circles where this point is included.
3) For each circle where pt A lies, calculate sector in which it lies. Say it lies on sector formed by points X_i and Y_i. Calculate the distance AX_i and AY_i.
4) Choose the minimum across all distances AX_i, AY_i and show navigation instructions for those points
It doesn't matter if the markers appear visually close to each other.. You're not going to visually find the direction the computing device is going to do it. Lat/Long values have a very high order of precision anyway.

Google Maps Android API utility library: Add a circle around the marker, when marker becomes visible

I am working on Android application which makes use of Google Maps and Google Maps Android API Utility Library. By making use of the utility library I got the clustered markers. But I want to show circle around the marker, when markers become visible.
Following is the code I am using to add clustered markers:
public class ClusterMarkersFragment {
public GoogleMap map;
private ClusterManager<MarkerItem> fenceClusterManager;
public static ClusterMarkersFragment newInstance () {
ClusterMarkersFragment clusterMarkersFragment = new
ClusterMarkersFragment();
return clusterMarkersFragment;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate( R.layout.fragment_cluster_marker_map,
container, false );
map = ((SupportMapFragment) getChildFragmentManager()
.findFragmentById( R.id.view_map )).getMap();
map.setMyLocationEnabled(false);
fenceClusterManager = new ClusterManager<MarkerItem>(getActivity(), map);
map.setOnCameraChangeListener(fenceClusterManager);
addClusterItems(getListofLatLngPairs());
return view;
}
private List< LatLngPair > getListofLatLngPairs () {
// returns the list from database
}
private void addClusterItems(List<LatLngPair> latLngPairs) {
for (LatLngPair latLngPair : latLngPairs) {
MarkerItem markerItem = new MarkerItem(latLngPair.lat, latLngPair.lng, (int) latLngPair);
fenceClusterManager.addItem(markerItem);
}
}
}
Following are the screenshots
When Clustered
When Cluster rendered current behavior
Desired Behavior
Try this:
private void addcircleAroundMarker() {
GoogleMap mapView;
// circle settings
int radiusM = RADIUS OF CIRCLE;
double latitude = CENTER LATITUDE;
double longitude = CENTER LONGITUDE;
LatLng latLng = new LatLng(latitude,longitude);
// draw circle
// diameter
int d = 500;
Bitmap bm = Bitmap.createBitmap(d, d, Config.ARGB_8888);
Canvas c = new Canvas(bm);
Paint p = new Paint();
p.setColor(getResources().getColor(R.color.green));
c.drawCircle(d/2, d/2, d/2, p);
BitmapDescriptor bmD = BitmapDescriptorFactory.fromBitmap(bm);
mapView.addGroundOverlay(new GroundOverlayOptions().
image(bmD).
position(latLng,radiusM*2,radiusM*2).
transparency(0.4f));
}

Display ImagesViews with animation issue

I want to display ImageViews in GridView using animation. I can display them and apply animation correctly.
But issue is that, if I apply animation on ImageView1 and then to ImageView2 (before animation on ImageView1 is ended) then animation on ImageView1 gets interrupted and ImageView1 is directly set to final state.
Note that I download image using ThreadPoolExecutor with 2 threads. Whenever an image is done downloading, I call addImage(image) method of below ImageAdapter which in turn adds image in GridView and GridView is refreshed to display latest set of images. And Here, while rendering, new image is displayed with animation and this animation(I guess) interrupts animation of currently animating images.
ImageAdapter :
public class ImageAdapter extends BaseAdapter {
private Context mContext;
private List<Bitmap> images;
private ArrayList<Integer> colors;
private boolean[] alreadyLoadedIndexes;
Animation animation;
AnimatorSet animator;
public void addImage(Bitmap img) {
images.add(img);
notifyDataSetChanged();
}
public void setAnimation(Animation animation) {
this.animator = null;
this.animation = animation;
}
public void setAnimator(AnimatorSet animation) {
this.animation = null;
this.animator = animation;
}
public void resetImages() {
images.clear();
notifyDataSetChanged();
alreadyLoadedIndexes = null;
alreadyLoadedIndexes = new boolean[20];
}
// Constructor
public ImageAdapter(Context c) {
mContext = c;
images = new ArrayList<Bitmap>();
colors = new ArrayList<Integer>();
colors.add(Color.CYAN);
colors.add(Color.BLUE);
colors.add(Color.GRAY);
colors.add(Color.YELLOW);
colors.add(Color.MAGENTA);
alreadyLoadedIndexes = new boolean[20];
}
#Override
public int getCount() {
return 20;
}
#Override
public Object getItem(int position) {
return 20;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView = new ImageView(mContext);
imageView
.setBackgroundColor(colors.get((int) ((Math.sqrt(position) + 2 * position) % 5)));
// If image at index 'position' is available
if (images.size() > position) {
// If loading this image first time then only apply animation
if (!alreadyLoadedIndexes[position]) {
// If animation is specified
if (this.animation != null) {
imageView.setImageBitmap(images.get(position));
imageView.startAnimation(animation);
}
// If animator set is specified
else if (this.animator != null) {
imageView.setImageBitmap(null);
imageView.setBackgroundColor(colors.get((int) ((Math
.sqrt(position) + 2 * position) % 5)));
animator.setTarget(imageView);
animator.start();
Log.e("", "setting image after " + animator.getDuration()
/ 2);
new Handler().postDelayed(
new runnable(imageView, images.get(position)), 500);
} else {
// Use default animation if nothing is specified.
imageView.setImageBitmap(images.get(position));
animation = AnimationUtils.loadAnimation(mContext,
R.anim.fade_in);
imageView.startAnimation(animation);
}
} else {
imageView.setImageBitmap(images.get(position));
}
alreadyLoadedIndexes[position] = true;
}
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setLayoutParams(new GridView.LayoutParams(150, 150));
return imageView;
}
class runnable implements Runnable {
ImageView image;
Bitmap bitmap;
public runnable(ImageView img, Bitmap bitmap) {
this.image = img;
this.bitmap = bitmap;
}
#Override
public void run() {
Log.e("", "setting image.");
image.setImageBitmap(bitmap);
}
}
}
try layout animation controlor for GridView, it will animate the views item by item with respect to time duration. check this link ,
Have you tried to apply the animation outside adapter getView method like:
mGridView.getChildAt(childIndexNeededToAnimate).startAnimation(animation);
These child views are independent and not being recycled anymore since they are already drawn.
You have some alternative.
First you can use Animation in your adapter class if you don't want to change your code.
For that check this.
In your adapter class inside the getView you have to call animation like this ,
Animation animation = null;
animation = AnimationUtils.loadAnimation(context, R.anim.push_left_in);
animation.setDuration(500);
convertView.startAnimation(animation);
return convertView;
Second you should use GridLayoutAnimationController in which A layout animation controller is used to animated a grid layout's children.
Sample 1
Sample 2
Just a guess. I'm neither sure if it will help nor if I read your code right. I suppose the problem is harder than I guess.
However, you are using the same animation object for every item. Maybe you should create a new animation for each item. This could be the reason why your animation stops when you launch a new one because the new call just reuse and restarts it.
Good luck.
You problem is notifyDataSetChanged(); it interrupt the animation. Try calling it when the animation is finished.

onMarkerClick using switch Case

I want to make marker Application using Google Maps but . I Have problem about onMarkerClick using switch Case, Iam using array to add Marker to My Application and when marker OnCLick he can call different Activity for each marker .I Have problom about that.. How I can using onMarkerClick with switch case for my application..??? Please Help . Here is My Code :
public static final String TAG = markerbanyak.TAG;
final LatLng CENTER = new LatLng(43.661049, -79.400917);
class Data {
public Data(float lng, float lat, String title, String snippet, String icon) {
super();
this.lat = (float)lat;
this.lng = (float)lng;
this.title = title;
this.snippet = snippet;
this.icon = icon;
}
float lat;
float lng;
String title;
String snippet;
String icon;
}
Data[] data = {
new Data(-79.400917f,43.661049f, "New New College Res",
"Residence building (new concrete high-rise)", "R.drawable.mr_kun"),
new Data(-79.394524f,43.655796f, "Baldwin Street",
"Here be many good restaurants!", "R.drawable.mr_kun"),
new Data(-79.402206f,43.657688f, "College St",
"Lots of discount computer stores if you forgot a cable or need to buy hardware.", "R.drawable.mr_kun"),
new Data(-79.390381f,43.659878f, "Queens Park Subway",
"Quickest way to the north-south (Yonge-University-Spadina) subway/metro line", "R.drawable.mr_kun"),
new Data(-79.403732f,43.666801f, "Spadina Subway",
"Quickest way to the east-west (Bloor-Danforth) subway/metro line", "R.drawable.mr_kun"),
new Data(-79.399696f,43.667873f, "St George Subway back door",
"Token-only admittance, else use Spadina or Bedford entrances!", "R.drawable.mr_kun"),
new Data(-79.384163f,43.655083f, "Eaton Centre (megamall)",
"One of the largest indoor shopping centres in eastern Canada. Runs from Dundas to Queen.", "R.drawable.mr_kun"),
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.peta);
SupportMapFragment supportMapFragment = (SupportMapFragment)
getSupportFragmentManager().findFragmentById(R.id.map);
// Getting a reference to the map
mMap = supportMapFragment.getMap();
Marker kuningan = mMap.addMarker(new MarkerOptions()
.position(KUNINGAN)
.title("Kuningan")
.snippet("Kuningan ASRI")
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.mr_kun)));
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(KUNINGAN, 2));
// Zoom in, animating the camera.
mMap.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
}
public void wisata(){
if (mMap==null) {
Log.d(TAG, "Map Fragment Not Found or no Map in it!!");
return;
}
for (Data d : data) {
LatLng location = new LatLng(d.lat, d.lng);
Marker wisata =mMap.addMarker(new MarkerOptions()
.position(location)
.title(d.title)
.snippet(d.snippet)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.mr_wis)));
// Let the user see indoor maps where available.
mMap.setIndoorEnabled(true);
// Enable my-location stuff
mMap.setMyLocationEnabled(true);
// Move the "camera" (view position) to our center point.
mMap.moveCamera(CameraUpdateFactory.newLatLng(CENTER));
// Then animate the markers while the map is drawing,
// since you can't combine motion and zoom setting!
final int zoom = 14;
mMap.animateCamera(CameraUpdateFactory.zoomTo(zoom), 2000, null);
mMap.setOnMarkerClickListener(new OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker v) {
// TODO Auto-generated method stub
//(PLEASE HELP ME !!! :))
return false;
}
});
}
}
#Override
public boolean onMarkerClick(Marker v) {
// TODO Auto-generated method stub
//(PLEASE HELP ME !!! :))
if(v.getTitle().contains("New New College Res")){
// do if marker has this title
}else if(v.getTitle().contains("Baldwin Street")){
// do if marker has this title
} // and so on
return false;
}
});
Marker class if final so you can't extend it and add your own attributes. You will have to handle this using your own logic.
You can do this in two ways.
You already have a Data list with all marker data.
1) You could try to set "snippet" attribute of Marker with your array index of Data array and on onMarkerClick you can get Snippet change it back to int and that would be your Data Array's index. So you can get that your clicked Marker and it's Data object and do whatever you want to do.
2) Use HashMap.
It will look something like this
HashMap<Marker, Integer> hashMap = new HashMap<Marker, Integer>();
// now even in your loop where you are adding markers. you can also add that marker to this hashmap with the id of Data array's index.
hashMap.add(marker, indexOfDataArray);
// final in your onMarkerClick, you can just pass marker to hashMap and get indexOfDataArray and base of that do whatever you want to do.
int id = hashMap.get(marker);

Categories

Resources