java - Android MapView 从 searchView 加载位置

标签 java android android-mapview

当用户单击按钮或在 searchView 中提交搜索时,mapView 是否可以加载标记。当用户提交数据时,我无法获取要显示的标记位置。当用户提交信息时,它会提取纬度和经度,但不会立即更新 View 模型中的位置。

public class SearchFragment extends Fragment implements OnMapReadyCallback {
private static final String TAG = "SearchFragment";

private SearchViewModel searchViewModel;
private LatLng location;
private Marker marker;

//UI
private MapView mapView;
private SearchView searchView;
private TextView cityTv, countryTv, regionTv, ispTv, timezoneTv, postalTv, countryCallingCodeTv;

private static final String MAPVIEW_BUNDLE = "MAPVIEW_BUNDLE";


public View onCreateView(@NonNull LayoutInflater inflater,
                         ViewGroup container, final Bundle savedInstanceState) {
    Log.d(TAG, "onCreateView: ");
    final View view = inflater.inflate(R.layout.fragment_search, container, false);

    searchView = view.findViewById(R.id.search_searchview);
    cityTv = view.findViewById(R.id.city_input_textview);
    countryTv = view.findViewById(R.id.country_input_textview);
    regionTv = view.findViewById(R.id.region_input_textview);
    ispTv = view.findViewById(R.id.isp_input_textview);
    timezoneTv = view.findViewById(R.id.timezone_input_textview);
    postalTv = view.findViewById(R.id.postal_input_textview);
    countryCallingCodeTv = view.findViewById(R.id.countrycallingcode_input_textview);


    Bundle mapViewBundle = null;
    if (savedInstanceState != null) {
        mapViewBundle = savedInstanceState.getBundle(MAPVIEW_BUNDLE);
    }
    mapView = view.findViewById(R.id.location_mapview);
    mapView.onCreate(mapViewBundle);


    searchViewModel = ViewModelProviders.of(this).get(SearchViewModel.class);


    searchView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View view) {
            searchView.setIconified(false);
            //returns result from search view
            getSearchViewResults(view);

        }
    });

    return view;
}

@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    Bundle mapViewBundle = outState.getBundle(MAPVIEW_BUNDLE);
    if (mapViewBundle == null) {
        mapViewBundle = new Bundle();
        outState.putBundle(MAPVIEW_BUNDLE, mapViewBundle);
    }
    mapView.onSaveInstanceState(mapViewBundle);
}


//retrieves the search results from searchView and passes information to searchviewmodel
public void getSearchViewResults(final View view) {
    searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            Log.d(TAG, "onQueryTextSubmit: ");

            //TODO: add input validation to make sure addres is correct
            //TODO: if incorrect display toast message saying input is invalid
            searchViewModel.getIpAddress(query);
            //observer to observe data change and display search results in textview
            observeSearchView();
            mapView.getMapAsync(SearchFragment.this);


            return false;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            return false;
        }
    });
}


private void observeSearchView() {

    searchViewModel.getIpLocation().observe(SearchFragment.this, new Observer<IPLocation>() {

        @Override
        public void onChanged(IPLocation ipLocation) {
            cityTv.setText(ipLocation.getCity());
            countryTv.setText(ipLocation.getCountry());
            regionTv.setText(ipLocation.getRegion());
            ispTv.setText(ipLocation.getOrg());
            timezoneTv.setText(ipLocation.getTimezone());
            countryCallingCodeTv.setText(ipLocation.getCountryCallingCode());
            postalTv.setText(ipLocation.getPostal());
            location = new LatLng(ipLocation.getLatitude(), ipLocation.getLongitude());

            //  Toast.makeText(getContext(), "Lat: " + location, Toast.LENGTH_SHORT).show();


        }
    });
}


//displays the lat/lon of entered address
@Override
public void onMapReady(GoogleMap googleMap) {
    Log.d(TAG, "onMapReady: ");


    //test adds marker in sydney and moves the camera to location
    if (searchViewModel.getResult()) {


        try {

            marker = googleMap.addMarker(new MarkerOptions().position(location).title("Location"));
            marker.setPosition(location);
            googleMap.moveCamera(CameraUpdateFactory.newLatLng(location));
            googleMap.getMinZoomLevel();

        } catch (Exception e) {
            Toast.makeText(getContext(), "Exception: " + e, Toast.LENGTH_SHORT).show();
        }

    } else {
        Toast.makeText(getContext(), "FALSE", Toast.LENGTH_SHORT).show();
    }

}


@Override
public void onResume() {
    Log.d(TAG, "onResume: map ");
    super.onResume();
    mapView.onResume();
}

@Override
public void onStart() {
    Log.d(TAG, "onStart: map");
    super.onStart();
    mapView.onStart();
}

@Override
public void onStop() {
    Log.d(TAG, "onStop: map");
    super.onStop();
    mapView.onStop();
}

@Override
public void onPause() {
    Log.d(TAG, "onPause: map ");
    super.onPause();
    mapView.onPause();
}

@Override
public void onDestroy() {
    Log.d(TAG, "onDestroy: map");
    super.onDestroy();
    mapView.onDestroy();
}





public class SearchViewModel extends ViewModel {
private static final String TAG = "SearchViewModel";

private Boolean result = false;
private String input;
private ArrayList<IPLocation> ipLocationsList;
private MutableLiveData<IPLocation> ipLocation;
private MutableLiveData<Double> latResult = new MutableLiveData<>();
private MutableLiveData<Double> lonResult = new MutableLiveData<>();


public SearchViewModel() {
    Log.d(TAG, "SearchViewModel: ");
    ipLocation = new MutableLiveData<>();
    ipLocationsList = new ArrayList<>();


}

public void getIpAddress(String ipAdress) {
    Log.d(TAG, "getInfo: Start");


    Calendar calendar = Calendar.getInstance();
    final Date dateNow = calendar.getTime();
    final GetDataService[] getDataService = {RetrofitClientInstance.getRetrofit()
            .create(GetDataService.class)};

    Call<IPLocation> call = getDataService[0].getLocationByIP(ipAdress);
    call.enqueue(new Callback<IPLocation>() {
        @Override
        public void onResponse(Call<IPLocation> call, Response<IPLocation> response) {
            Log.d(TAG, "onResponse: Start");
            ipLocation.setValue(new IPLocation(0, response.body().getIp(),
                    response.body().getCity(), response.body().getRegion(),
                    response.body().getRegionCode(), response.body().getCountry(), response.body().getCountryName(),
                    response.body().getContinentCode(), response.body().getInEu(), response.body().getPostal(),
                    response.body().getLatitude(), response.body().getLongitude(), response.body().getTimezone(),
                    response.body().getUtcOffset(), response.body().getCountryCallingCode(), response.body().getCurrency(),
                    response.body().getLanguages(), response.body().getAsn(), response.body().getOrg(), dateNow));


            latResult.setValue(response.body().getLatitude());
            lonResult.setValue(response.body().getLongitude());
            setResult(true);


        }

        @Override
        public void onFailure(Call<IPLocation> call, Throwable t) {
            Log.d(TAG, "onFailure: Fail");


        }

    });


}


public Boolean getResult() {
    return result;
}

public void setResult(Boolean result) {
    this.result = result;
}

public MutableLiveData<IPLocation> getIpLocation() {
    return ipLocation;
}

public MutableLiveData<Double> getLatResult() {
    return latResult;
}

public void setLatResult(MutableLiveData<Double> latResult) {
    this.latResult = latResult;
}

public MutableLiveData<Double> getLonResult() {
    return lonResult;
}

public void setLonResult(MutableLiveData<Double> lonResult) {
    this.lonResult = lonResult;
}

}

<LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/location_title_textview"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:text="@string/location_title"
                    android:textAlignment="center"
                    android:textSize="24sp" />

                <com.google.android.gms.maps.MapView
                    android:id="@+id/location_mapview"
                    android:layout_width="match_parent"
                    android:layout_height="319dp" />

            </LinearLayout>

最佳答案

onMapReady(GoogleMap googleMap) 回调接收到对象后,全局保存您的 google map 对象。

进行 API 调用并获取结果后,对您的 map 执行类似的操作

LatLng latlng = new LatLng(response.body().getLatitude(), response.body().getLongitude());
MarkerOptions markerOption = new MarkerOption();
markerOptions.setPosition(latlng);
markerOptions.setIcon(*PASS_YOUR_BITMAP_FOR_ICON_HERE*);
markerOptions.title("Location")

Marker marker = googleMap.addMarker(markerOption);
googleMap.moveCamera(CameraUpdateFactory.newLatLng(latlng));

关于java - Android MapView 从 searchView 加载位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58863500/

相关文章:

java - 使用条件 TimerTask 不会终止线程

java - 在android中读取文件。如何修复坏路径

java - 返回对话框时 MapView 未加载(MapBox)

java - 我应该为任务处理器使用线程吗?

java - Jetty Mutual TLS 身份验证未找到客户端证书

android - 如何使用 Qt Creator 运行 ADB 命令?

android - 如何在 MapView 上创建上下文菜单?

java - 无法解析/实现 onMapReadyCallBack 接口(interface)

java - 使javafx choicebox根据键盘选择项目

java - Android 图库 View ,其中图像保存在 sqlite 中作为 blob