Я использую карты Google, и добавляю маркеры и кластеры. Я хочу, чтобы, когда пользователь щелкает по одному элементу или кластеру, информация, содержащаяся в объекте mapItem, должна отображаться в окне просмотра в нижней части экрана. Я могу получить информацию там, но только по второму щелчку значка карты. Есть ли способ сделать это обновление с первого клика?
Я смотрю на При первом щелчке Textview становится пустым, но при втором щелчке обновляется , но это решение не помогло мне, поскольку информация статична для самого фрагмента.
вот код моей основной деятельности:
package com.example.cpj.maptesting;
import android.Manifest;
import android.app.AlertDialog;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.content.ContextCompat;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.places.Place;
import com.google.android.gms.location.places.ui.PlaceAutocompleteFragment;
import com.google.android.gms.location.places.ui.PlaceSelectionListener;
import com.google.android.gms.maps.CameraUpdate;
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.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.maps.android.clustering.Cluster;
import com.google.maps.android.clustering.ClusterManager;
import java.util.ArrayList;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, LocationListener{
private GoogleMap mMap;
private static ClusterManager<MapItem> itemClusterManager;
private static ArrayList<MapItem> listOfMarkers = new ArrayList<>();
private ArrayList<MapItem> listForFragments = new ArrayList<>();
private LocationManager locationManager;
PlaceAutocompleteFragment placeAutocompleteFragment;
Marker marker;
private Context context;
Location location;
ViewPager mViewpager;
InfoPageAdapter mPagerAdapter;
int counter = 0;
SparseArray<Fragment> fragments = new SparseArray<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
gpsPermission();
// 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);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
placeAutocompleteFragment = (PlaceAutocompleteFragment) getFragmentManager().findFragmentById(R.id.place_autocomplete);
context = getApplicationContext();
setUpPagers();
if(!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
alertBuilder();
}
placeAutocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
@Override
public void onPlaceSelected(Place place) {
if(marker != null){
marker.remove();
}
moveCamera(place.getLatLng());
marker = mMap.addMarker(new MarkerOptions()
.position(place.getLatLng())
.title("" + place.getAddress())
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
}
@Override
public void onError(Status status) {
Log.d("Error status: " , status.toString());
}
});
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(final GoogleMap googleMap) {
mMap = googleMap;
setUpMap();
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED){
mMap.setMyLocationEnabled(true);
location = locationManager.getLastKnownLocation(locationManager.getBestProvider(new Criteria(), false));
if(location != null){
moveCamera(new LatLng(location.getLatitude(), location.getLongitude()));
}
}
mMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
@Override
public void onCameraMove() {
new dynamicallyAddMarkersTask().execute(mMap.getProjection().getVisibleRegion().latLngBounds);
}
});
mMap.setOnMyLocationButtonClickListener(new GoogleMap.OnMyLocationButtonClickListener() {
@Override
public boolean onMyLocationButtonClick() {
if(!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
alertBuilder();
}
return false;
}
});
setUpClusters();
}
@Override
public void onBackPressed() {
if (mViewpager.getCurrentItem() == 0) {
// If the user is currently looking at the first step, allow the system to handle the
// Back button. This calls finish() on this activity and pops the back stack.
super.onBackPressed();
} else {
// Otherwise, select the previous step.
mViewpager.setCurrentItem(mViewpager.getCurrentItem() - 1);
}
}
private void setUpClusters(){
itemClusterManager = new ClusterManager<>(this, getMap());
itemClusterManager.setAnimation(false);
itemClusterManager.clearItems();
listOfMarkers.clear();
getMap().setOnCameraIdleListener(itemClusterManager);
getMap().setOnMarkerClickListener(itemClusterManager);
itemClusterManager.setOnClusterClickListener(new ClusterManager.OnClusterClickListener<MapItem>() {
@Override
public boolean onClusterClick(Cluster<MapItem> cluster) {
setupClusterClicked(cluster);
listForFragments.addAll(cluster.getItems());
mViewpager.setCurrentItem(0);
infoPageFragment ipf = (infoPageFragment) mPagerAdapter.getFragments(0);
if(ipf != null){
ipf.setAdresse("Adresse: " + cluster.getItems().iterator().next().getTitle());
ipf.setNummer(1 + "/" + listForFragments.size());
}
return false;
}
});
itemClusterManager.setOnClusterItemClickListener(new ClusterManager.OnClusterItemClickListener<MapItem>() {
@Override
public boolean onClusterItemClick(MapItem mapItem) {
setupClusterItem();
mViewpager.setCurrentItem(0);
int position = mViewpager.getCurrentItem();
infoPageFragment ipf = (infoPageFragment) mPagerAdapter.getFragments(position);
if(ipf != null){
ipf.setAdresse("Adresse: " + mapItem.getTitle());
ipf.setNummer("");
}
return false;
}
});
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
mViewpager.setVisibility(View.GONE);
}
});
itemClusterManager.setRenderer(new CustomIcon(this, mMap, itemClusterManager));
addMapItem(new MapItem(56.162939, 10.203727, "Nabo", "Holde"));
addMapItem(new MapItem(56.162939, 10.203921, "Harald", "Plads"));
addMapItem(new MapItem(56.162939, 10.203921, "Jensen", "Plads1"));
addMapItem(new MapItem(56.162939, 10.203921, "Mogens", "Plads2"));
addMapItem(new MapItem(56.162939, 10.203921, "Jørgensen", "Plads3"));
addMapItem(new MapItem(56.162939, 10.203921, "Hansen", "Plads4"));
mViewpager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {}
@Override
public void onPageSelected(int position) {
infoPageFragment ipf;
for(MapItem mapItem : listForFragments){
ipf = (infoPageFragment) mPagerAdapter.getFragments(position);
mapItem = listForFragments.get(position);
int increment = position+1;
if(ipf != null){
String text = increment + "/" + listForFragments.size();
ipf.setAdresse("Adresse: " + mapItem.getTitle());
ipf.setNummer(text);
}
}
}
@Override
public void onPageScrollStateChanged(int state) {}
});
mPagerAdapter.notifyDataSetChanged();
}
@Override
public void onLocationChanged(Location location) {
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
moveCamera(latLng);
locationManager.removeUpdates(this);
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {}
@Override
public void onProviderEnabled(String s) {}
@Override
public void onProviderDisabled(String s) {}
private GoogleMap getMap() {
return mMap;
}
private void setUpMap(){
mMap.getUiSettings().setTiltGesturesEnabled(false);
mMap.getUiSettings().setRotateGesturesEnabled(false);
mMap.getUiSettings().setMapToolbarEnabled(false);
}
private void gpsPermission(){
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}
private void alertBuilder(){
final AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
alertDialog.setTitle("GPS setting");
alertDialog.setMessage("This app needs gps, to find the closet parking spots! \nGo to settings?");
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
context.startActivity(intent);
}
});
alertDialog.setNegativeButton("Not now", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {}
});
AlertDialog alert = alertDialog.create();
alert.show();
}
private void moveCamera(LatLng latLng){
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 16);
mMap.animateCamera(cameraUpdate);
}
private void addMapItem(MapItem item){
listOfMarkers.add(item);
itemClusterManager.addItem(item);
}
private void setupClusterItem(){
counter = 1;
mViewpager.setVisibility(View.VISIBLE);
mPagerAdapter.notifyDataSetChanged();
}
private void setupClusterClicked(Cluster<MapItem> cluster){
listForFragments.clear();
mViewpager.setVisibility(View.VISIBLE);
counter = cluster.getSize();
mPagerAdapter.notifyDataSetChanged();
}
private void setUpPagers(){
mViewpager = findViewById(R.id.viewPager);
mPagerAdapter = new InfoPageAdapter(getSupportFragmentManager());
mViewpager.setAdapter(mPagerAdapter);
}
private static class dynamicallyAddMarkersTask extends AsyncTask<LatLngBounds, Void, Void> {
@Override
protected Void doInBackground(LatLngBounds... bounds) {
itemClusterManager.clearItems();
for(MapItem mapItem: listOfMarkers){
if(bounds[0].contains(mapItem.getPosition())){
itemClusterManager.addItem(mapItem);
}
}
return null;
}
@Override
protected void onPostExecute(Void result){
itemClusterManager.cluster();
}
}
private class InfoPageAdapter extends FragmentStatePagerAdapter{
public InfoPageAdapter(android.support.v4.app.FragmentManager fm){
super(fm);
}
@Override
public Fragment getItem(int position) {
return new infoPageFragment();
}
@Override
public int getItemPosition(Object obj){
return POSITION_NONE;
}
@Override
public Object instantiateItem(ViewGroup viewGroup, int position){
Fragment fragment = (Fragment) super.instantiateItem(viewGroup, position);
fragments.put(position, fragment);
return fragment;
}
@Override
public void destroyItem(ViewGroup viewGroup, int position, Object object){
fragments.remove(position);
super.destroyItem(viewGroup, position, object);
}
public Fragment getFragments(int position){
return fragments.get(position);
}
@Override
public int getCount() {
return counter;
}
}
}
Это фрагмент
package com.example.cpj.maptesting;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
public class infoPageFragment extends Fragment {
TextView adresse, nummer;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View rootView = inflater.inflate(R.layout.info_page, container, false);
adresse = rootView.findViewById(R.id.adresse);
nummer = rootView.findViewById(R.id.nummer);
return rootView;
}
public void setAdresse(String value){
adresse.setText(value);
}
public void setNummer(String value){
nummer.setText(value);
}
}
activity_maps.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:weightSum="10"
tools:context=".MapsActivity">
<fragment
android:id="@+id/place_autocomplete"
android:name="com.google.android.gms.location.places.ui.PlaceAutocompleteFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="633dp" />
<LinearLayout
android:id="@+id/pagerLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="visible"
android:weightSum="1"
>
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:visibility="gone"/>
</LinearLayout>
</LinearLayout>
и info_page.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/info_page"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView style="?android:textAppearanceMedium"
android:padding="16dp"
android:id="@+id/adresse"
android:lineSpacingMultiplier="1.2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Adresse: "/>
<TextView style="?android:textAppearanceMedium"
android:id="@+id/nummer"
android:padding="16dp"
android:lineSpacingMultiplier="1.2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="right"
/>
</LinearLayout>
Я понимаю, что это как-то связано с жизненным циклом фрагмента, но я просто не могу понять, какой последний бит мне не хватает.
Спасибо за ответы.
пс. Пожалуйста, потерпите меня из-за неаккуратного кода. Я все еще новичок, когда дело доходит до разработки Android :).