可是你刚刚提供的代码出现报错。目前SearchResultActivity代码如下:package com.example.bus;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.ArrayAdapter;
import java.util.ArrayList;
import java.util.List;
import android.view.inputmethod.EditorInfo;
public class SearchResultActivity extends AppCompatActivity
implements PoiSearch.OnPoiSearchListener, GeocodeSearch.OnGeocodeSearchListener {
private Button searchBtn, goToBtn;
private RecyclerView resultListView;
private List<PoiItem> poiList = new ArrayList<>();
private ResultAdapter adapter;
private PoiSearch poiSearch;
// 地图相关
private MapView mapView;
private AMap aMap;
private Marker selectedMarker; // 终点标记
// 输入提示
private GeocodeSearch geocodeSearch;
// 当前城市
private String currentCity = "全国";
// 是否已与地图交互(防止重复居中)
private boolean userHasInteracted = false;
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1001;
// 空状态提示视图
private TextView emptyView;
// 【关键新增】保存定位得到的“我的位置”
private double myCurrentLat = 0;
private double myCurrentLng = 0;
private boolean isLocationReady = false; // 定位是否完成
// 缓存从 HomeFragment 传来的关键词,等待定位完成后使用
private String pendingKeyword = null;
// ✅ 新增:将搜索输入框提升为成员变量
private android.widget.AutoCompleteTextView searchInput;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search_result);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle("搜索地点");
}
initViews();
setupMap(savedInstanceState);
setupSearchSuggestion();
try {
geocodeSearch = new GeocodeSearch(this);
geocodeSearch.setOnGeocodeSearchListener(this);
} catch (Exception e) {
e.printStackTrace();
}
// ✅ 只缓存 keyword,不再尝试提前搜索
pendingKeyword = getIntent().getStringExtra("keyword");
}
private void initViews() {
searchBtn = findViewById(R.id.search_btn);
resultListView = findViewById(R.id.result_list);
goToBtn = findViewById(R.id.btn_go_to);
emptyView = findViewById(R.id.empty_view);
searchInput = findViewById(R.id.search_input); // ✅ 初始化成员变量
goToBtn.setEnabled(false);
adapter = new ResultAdapter(poiList, this::onPoiItemSelected);
resultListView.setLayoutManager(new LinearLayoutManager(this));
resultListView.setAdapter(adapter);
resultListView.setVisibility(View.GONE);
emptyView.setVisibility(View.GONE);
// 修改:传递真实定位点
goToBtn.setOnClickListener(v -> {
if (selectedMarker == null) {
Toast.makeText(this, "请先选择一个位置", Toast.LENGTH_SHORT).show();
return;
}
LatLng targetPos = selectedMarker.getPosition();
// 确保定位已完成
if (!isLocationReady) {
Toast.makeText(this, "正在获取您的位置,请稍后再试", Toast.LENGTH_SHORT).show();
return;
}
Intent intent = new Intent(SearchResultActivity.this, RoutePlanActivity.class);
intent.putExtra("start_lat", myCurrentLat);
intent.putExtra("start_lng", myCurrentLng);
intent.putExtra("target_lat", targetPos.latitude);
intent.putExtra("target_lng", targetPos.longitude);
intent.putExtra(RoutePlanActivity.EXTRA_SOURCE, RoutePlanActivity.SOURCE_FROM_SEARCH_RESULT);
startActivity(intent);
finish();
});
}
private void setupMap(Bundle savedInstanceState) {
mapView = findViewById(R.id.map_view);
mapView.onCreate(savedInstanceState);
aMap = mapView.getMap();
if (aMap != null) {
initMapSettings();
} else {
new Handler(Looper.getMainLooper()).post(() -> {
aMap = mapView.getMap();
if (aMap != null) {
initMapSettings();
} else {
waitAMapReady();
}
});
}
}
private void waitAMapReady() {
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
int retry = 0;
@Override
public void run() {
if (mapView == null) return;
aMap = mapView.getMap();
if (aMap != null) {
initMapSettings();
} else if (retry++ < 30) {
new Handler(Looper.getMainLooper()).postDelayed(this, 100);
}
}
}, 100);
}
private void initMapSettings() {
UiSettings uiSettings = aMap.getUiSettings();
uiSettings.setZoomControlsEnabled(true);
uiSettings.setCompassEnabled(true);
uiSettings.setScrollGesturesEnabled(true);
uiSettings.setMyLocationButtonEnabled(true);
aMap.setOnMapClickListener(latLng -> onCustomLocationSelected(latLng));
// 初始视野:中国中心
new Handler(Looper.getMainLooper()).post(() ->
aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(35.8617, 104.1954), 4f))
);
enableMyLocationLayer();
}
private void enableMyLocationLayer() {
if (aMap == null) return;
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
MyLocationStyle myLocationStyle = new MyLocationStyle();
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);
aMap.setMyLocationStyle(myLocationStyle);
aMap.setMyLocationEnabled(true);
AMap.OnMyLocationChangeListener listener = location -> {
if (location != null && !userHasInteracted) {
LatLng curLatlng = new LatLng(location.getLatitude(), location.getLongitude());
// 记录真实“我的位置”
myCurrentLat = location.getLatitude();
myCurrentLng = location.getLongitude();
isLocationReady = true;
// ✅ 先居中地图
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(curLatlng, 16f), 500, null);
userHasInteracted = true;
// 获取当前城市
LatLonPoint point = new LatLonPoint(myCurrentLat, myCurrentLng);
RegeocodeQuery query = new RegeocodeQuery(point, 200, GeocodeSearch.AMAP);
try {
geocodeSearch.getFromLocationAsyn(query);
} catch (Exception e) {
e.printStackTrace();
}
// ✅ 关键修改:延迟 800ms 再触发搜索,给地图留出渲染时间
new Handler(Looper.getMainLooper()).postDelayed(() -> {
if (pendingKeyword != null && !pendingKeyword.isEmpty()) {
performSearchWithKeyword(pendingKeyword);
}
}, 800);
// 防止重复触发
aMap.setOnMyLocationChangeListener(null);
}
};
aMap.setOnMyLocationChangeListener(listener);
} else {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
LOCATION_PERMISSION_REQUEST_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
enableMyLocationLayer();
} else {
Toast.makeText(this, "定位权限被拒绝,部分功能受限", Toast.LENGTH_LONG).show();
currentCity = "全国";
}
}
}
private void setupSearchSuggestion() {
RealTimePoiSuggestHelper suggestHelper = new RealTimePoiSuggestHelper(this);
suggestHelper.setCurrentCity(currentCity);
suggestHelper.setLocationBias(myCurrentLat, myCurrentLng); // 使用定位偏置
suggestHelper.setCallback(suggestions -> {
if (suggestions.length > 0) {
ArrayAdapter<String> adapter = new ArrayAdapter<>(
this,
android.R.layout.simple_dropdown_item_1line,
suggestions
);
searchInput.setAdapter(adapter);
searchInput.showDropDown();
}
});
Handler handler = new Handler(Looper.getMainLooper());
Runnable[] pendingRunnable = {null};
searchInput.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (pendingRunnable[0] != null) {
handler.removeCallbacks(pendingRunnable[0]);
}
if (s.length() == 0) {
searchInput.setAdapter(null);
return;
}
pendingRunnable[0] = () -> suggestHelper.requestSuggestions(s.toString());
handler.postDelayed(pendingRunnable[0], 300);
}
@Override
public void afterTextChanged(Editable s) {}
});
// 点击下拉建议项时,直接执行搜索
searchInput.setOnItemClickListener((parent, view, position, id) -> {
String keyword = (String) parent.getItemAtPosition(position);
if (keyword != null && !keyword.isEmpty()) {
performSearch(keyword); // 触发真实搜索
}
});
searchInput.setOnEditorActionListener((v, actionId, event) -> {
if ((actionId & EditorInfo.IME_MASK_ACTION) == EditorInfo.IME_ACTION_SEARCH) {
searchBtn.performClick();
return true;
}
return false;
});
searchBtn.setOnClickListener(v -> {
String keyword = searchInput.getText().toString().trim();
if (!keyword.isEmpty()) {
performSearch(keyword);
} else {
Toast.makeText(this, "请输入关键词", Toast.LENGTH_SHORT).show();
}
});
}
// ✅ 修改:先设置文本,再模拟点击按钮(等价于用户操作)
private void performSearchWithKeyword(String keyword) {
searchInput.setText(keyword);
searchInput.clearFocus();
searchBtn.performClick(); // ✅ 触发完整 UI 搜索流程
}
private void performSearch(String keyword) {
emptyView.setText("🔍 搜索中...");
emptyView.setVisibility(View.VISIBLE);
resultListView.setVisibility(View.GONE);
PoiSearch.Query query = new PoiSearch.Query(keyword, "", currentCity);
query.setPageSize(20);
query.setPageNum(0);
if (isLocationReady) {
LatLonPoint lp = new LatLonPoint(myCurrentLat, myCurrentLng);
query.setLocation(lp); // 告诉高德“我在哪”,让它自行加权
}
try {
poiSearch = new PoiSearch(this, query);
poiSearch.setOnPoiSearchListener(this);
poiSearch.searchPOIAsyn();
} catch (Exception e) {
Toast.makeText(this, "搜索失败", Toast.LENGTH_SHORT).show();
emptyView.setText("⚠️ 未找到相关地点");
}
}
private void onPoiItemSelected(PoiItem item) {
LatLng latLng = new LatLng(item.getLatLonPoint().getLatitude(), item.getLatLonPoint().getLongitude());
if (selectedMarker != null) {
selectedMarker.remove();
selectedMarker = null;
}
selectedMarker = aMap.addMarker(new MarkerOptions()
.position(latLng)
.title("终点:" + item.getTitle())
.icon(com.amap.api.maps.model.BitmapDescriptorFactory.defaultMarker(
com.amap.api.maps.model.BitmapDescriptorFactory.HUE_RED)));
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14f));
goToBtn.setEnabled(true);
}
private void onCustomLocationSelected(LatLng latLng) {
if (selectedMarker != null) {
selectedMarker.remove();
}
selectedMarker = aMap.addMarker(new MarkerOptions()
.position(latLng)
.title("终点:自定义位置")
.icon(com.amap.api.maps.model.BitmapDescriptorFactory.defaultMarker(
com.amap.api.maps.model.BitmapDescriptorFactory.HUE_RED)));
goToBtn.setEnabled(true);
}
@Override
public void onPoiSearched(PoiResult result, int rCode) {
if (rCode == 1000 && result != null && result.getPois() != null && !result.getPois().isEmpty()) {
List<PoiItemWithScore> rankedList = new ArrayList<>();
String keyword = searchInput.getText().toString().trim();
float[] distance = new float[1];
LatLng userPos = isLocationReady ?
new LatLng(myCurrentLat, myCurrentLng) :
new LatLng(35.8617, 104.1954);
for (PoiItem item : result.getPois()) {
String title = item.getTitle().toLowerCase();
String key = keyword.toLowerCase();
int matchScore = 0;
if (title.equals(key)) matchScore = 3;
else if (title.startsWith(key)) matchScore = 2;
else if (title.contains(key)) matchScore = 1;
else continue;
LatLonPoint lp = item.getLatLonPoint();
android.location.Location.distanceBetween(
userPos.latitude, userPos.longitude,
lp.getLatitude(), lp.getLongitude(),
distance);
rankedList.add(new PoiItemWithScore(item, matchScore, distance[0]));
}
rankedList.sort((a, b) -> {
if (a.matchScore != b.matchScore) {
return Integer.compare(b.matchScore, a.matchScore);
}
return Float.compare(a.distance, b.distance);
});
List<PoiItem> sortedList = new ArrayList<>();
for (PoiItemWithScore rp : rankedList) {
sortedList.add(rp.item);
}
poiList.clear();
poiList.addAll(sortedList);
adapter.notifyDataSetChanged();
resultListView.scrollToPosition(0);
resultListView.setVisibility(View.VISIBLE);
emptyView.setVisibility(View.GONE);
adapter.setSelected(0);
onPoiItemSelected(poiList.get(0));
} else {
emptyView.setText("⚠️ 未找到相关地点");
emptyView.setVisibility(View.VISIBLE);
resultListView.setVisibility(View.GONE);
}
}
// 新增辅助类
private static class PoiItemWithScore {
final PoiItem item;
final int matchScore;
final float distance;
PoiItemWithScore(PoiItem item, int matchScore, float distance) {
this.item = item;
this.matchScore = matchScore;
this.distance = distance;
}
}
@Override
public void onPoiItemSearched(PoiItem item, int rCode) {
// 必须实现
}
@Override
public void onRegeocodeSearched(RegeocodeResult result, int rCode) {
if (rCode == 1000 && result != null && result.getRegeocodeAddress() != null) {
String city = result.getRegeocodeAddress().getCity();
currentCity = (city != null && !city.isEmpty()) ? city : result.getRegeocodeAddress().getProvince();
} else {
currentCity = "全国";
}
}
@Override
public void onGeocodeSearched(com.amap.api.services.geocoder.GeocodeResult geocodeResult, int i) {
// 忽略
}
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
geocodeSearch = null;
}
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
@Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
}
报错:Ambiguous method call: both 'RealTimePoiSuggestHelper.requestSuggestions(String)' and 'RealTimePoiSuggestHelper.requestSuggestions(String)' match
同样的,MapFragment代码如下:package com.example.bus.ui.map;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.text.Editable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
// 用于动态修改约束
import androidx.constraintlayout.widget.ConstraintSet;
// 用于设置 Marker 颜色
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.AMap;
import com.amap.api.maps.CameraUpdateFactory;
import com.amap.api.maps.MapView;
import com.amap.api.maps.UiSettings;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.maps.model.MyLocationStyle;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeQuery;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.example.bus.R;
import com.example.bus.RealTimePoiSuggestHelper;
import com.example.bus.RoutePlanActivity;
import com.example.bus.ResultAdapter;
import com.example.bus.databinding.FragmentMapBinding;
import java.util.ArrayList;
import java.util.List;
// ✅ 新增导入
import android.view.inputmethod.EditorInfo;
public class MapFragment extends Fragment implements PoiSearch.OnPoiSearchListener, GeocodeSearch.OnGeocodeSearchListener {
private FragmentMapBinding binding;
private MapView mapView;
private AMap aMap;
// 数据
private List<PoiItem> poiList = new ArrayList<>();
private ResultAdapter adapter;
private PoiSearch poiSearch;
// 当前阶段:1=选择起点, 2=选择终点
private int selectionStage = 0;
// 缓存已选 POI
private PoiItem selectedStartPoi = null;
private PoiItem selectedEndPoi = null;
private Marker startMarker = null;
private Marker endMarker = null;
// 缓存关键词
private String lastStartKeyword = "";
private String lastEndKeyword = "";
// ✅ 当前城市
private String currentCity = "全国";
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1001;
// ✅ 标记是否已居中我的位置
private boolean userHasInteracted = false;
// ✅ 反地理编码
private GeocodeSearch geocodeSearch;
// 【关键新增】保存定位得到的“我的位置”
private double myCurrentLat = 0;
private double myCurrentLng = 0;
private boolean isLocationReady = false; // 定位是否完成
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = FragmentMapBinding.inflate(inflater, container, false);
View root = binding.getRoot();
mapView = binding.mapView;
mapView.onCreate(savedInstanceState);
initViews();
setupMap(savedInstanceState);
setupSearchSuggestion(); // 包含输入建议、防抖、回车事件
return root;
}
private void initViews() {
adapter = new ResultAdapter(poiList, this::onPoiItemSelected);
binding.resultList.setLayoutManager(new LinearLayoutManager(requireContext()));
binding.resultList.setAdapter(adapter);
binding.mapSearch.setOnClickListener(v -> performSearch());
binding.btnSwitchTarget.setOnClickListener(v -> {
if (selectionStage == 1) {
showEndpointSelection(binding.mapInput2.getText().toString().trim());
} else if (selectionStage == 2) {
showStartpointSelection(binding.mapInput1.getText().toString().trim());
}
});
binding.btnGoTo.setOnClickListener(v -> {
if (selectedStartPoi != null && selectedEndPoi != null) {
Intent intent = new Intent(requireContext(), RoutePlanActivity.class);
intent.putExtra(RoutePlanActivity.EXTRA_SOURCE, RoutePlanActivity.SOURCE_FROM_MAP_DIRECT);
intent.putExtra("start_lat", selectedStartPoi.getLatLonPoint().getLatitude());
intent.putExtra("start_lng", selectedStartPoi.getLatLonPoint().getLongitude());
intent.putExtra("target_lat", selectedEndPoi.getLatLonPoint().getLatitude());
intent.putExtra("target_lng", selectedEndPoi.getLatLonPoint().getLongitude());
intent.putExtra("target_title", selectedEndPoi.getTitle());
startActivity(intent);
} else {
Toast.makeText(requireContext(), "请完成起点和终点的选择", Toast.LENGTH_SHORT).show();
}
});
}
private void performSearch() {
String startKeyword = binding.mapInput1.getText().toString().trim();
String endKeyword = binding.mapInput2.getText().toString().trim();
if (startKeyword.isEmpty()) {
Toast.makeText(requireContext(), "请输入起点", Toast.LENGTH_SHORT).show();
return;
}
if (endKeyword.isEmpty()) {
Toast.makeText(requireContext(), "请输入终点", Toast.LENGTH_SHORT).show();
return;
}
// 智能判断跳过搜索
if (startKeyword.equals(lastStartKeyword) &&
endKeyword.equals(lastEndKeyword) &&
selectedStartPoi != null &&
selectedEndPoi != null) {
binding.btnGoTo.performClick();
return;
}
// 展示 UI
binding.containerResultList.setVisibility(View.VISIBLE);
binding.buttonGroup.setVisibility(View.VISIBLE);
// 动态压缩地图区域
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(binding.getRoot());
constraintSet.connect(
R.id.map_view, ConstraintSet.BOTTOM,
R.id.container_result_list, ConstraintSet.TOP,
0
);
constraintSet.applyTo(binding.getRoot());
userHasInteracted = true;
// 隐藏软键盘
View currentFocus = requireActivity().getCurrentFocus();
if (currentFocus != null) {
currentFocus.clearFocus();
InputMethodManager imm = (InputMethodManager) requireContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(currentFocus.getWindowToken(), 0);
}
// 执行搜索
if (!startKeyword.equals(lastStartKeyword)) {
lastStartKeyword = startKeyword;
lastEndKeyword = endKeyword;
showStartpointSelection(startKeyword);
} else if (!endKeyword.equals(lastEndKeyword)) {
lastEndKeyword = endKeyword;
showEndpointSelection(endKeyword);
} else if (selectedStartPoi == null) {
showStartpointSelection(startKeyword);
} else {
showEndpointSelection(endKeyword);
}
}
// ✅ 显示“搜索起点中...”
private void showStartpointSelection(String keyword) {
selectionStage = 1;
binding.btnSwitchTarget.setText("前往选择终点");
binding.btnGoTo.setEnabled(false);
binding.emptyView.setText("🔍 搜索起点中...");
binding.emptyView.setVisibility(View.VISIBLE);
binding.resultList.setVisibility(View.GONE);
doSearch(keyword);
}
// ✅ 显示“搜索终点中...”
private void showEndpointSelection(String keyword) {
selectionStage = 2;
binding.btnSwitchTarget.setText("回到选择起点");
binding.btnGoTo.setEnabled(false);
binding.emptyView.setText("🔍 搜索终点中...");
binding.emptyView.setVisibility(View.VISIBLE);
binding.resultList.setVisibility(View.GONE);
doSearch(keyword);
}
private void doSearch(String keyword) {
if (keyword.isEmpty()) return;
PoiSearch.Query query = new PoiSearch.Query(keyword, "", currentCity);
query.setPageSize(20);
query.setPageNum(0);
// ✅ 使用缓存的位置(仅当真实定位完成后)
if (isLocationReady) {
LatLonPoint lp = new LatLonPoint(myCurrentLat, myCurrentLng);
query.setLocation(lp); // 让高德根据“我在哪”智能排序
}
try {
poiSearch = new PoiSearch(requireContext(), query);
poiSearch.setOnPoiSearchListener(this);
poiSearch.searchPOIAsyn();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(requireContext(), "搜索失败", Toast.LENGTH_SHORT).show();
}
}
private void onPoiItemSelected(PoiItem item) {
LatLng latLng = new LatLng(item.getLatLonPoint().getLatitude(), item.getLatLonPoint().getLongitude());
if (selectionStage == 1) {
if (startMarker != null) {
startMarker.remove();
startMarker = null;
}
startMarker = aMap.addMarker(new MarkerOptions()
.position(latLng)
.title("起点:" + item.getTitle())
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
selectedStartPoi = item;
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14f));
updateGoToButtonState();
} else if (selectionStage == 2) {
if (endMarker != null) {
endMarker.remove();
endMarker = null;
}
endMarker = aMap.addMarker(new MarkerOptions()
.position(latLng)
.title("终点:" + item.getTitle())
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
selectedEndPoi = item;
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14f));
updateGoToButtonState();
}
userHasInteracted = true;
}
private void updateGoToButtonState() {
binding.btnGoTo.setEnabled(selectedStartPoi != null && selectedEndPoi != null);
}
@Override
public void onPoiSearched(PoiResult result, int rCode) {
if (rCode == 1000 && result != null && result.getPois() != null && !result.getPois().isEmpty()) {
List<PoiItemWithScore> rankedList = new ArrayList<>();
String keyword = getCurrentInputKeyword(); // 获取当前输入框文本
float[] distance = new float[1];
LatLng userPos = isLocationReady ?
new LatLng(myCurrentLat, myCurrentLng) :
new LatLng(39.909186, 116.397411);
for (PoiItem item : result.getPois()) {
String title = item.getTitle().toLowerCase();
String key = keyword.toLowerCase();
int matchScore = 0;
if (title.equals(key)) matchScore = 3;
else if (title.startsWith(key)) matchScore = 2;
else if (title.contains(key)) matchScore = 1;
else continue;
LatLonPoint lp = item.getLatLonPoint();
android.location.Location.distanceBetween(
userPos.latitude, userPos.longitude,
lp.getLatitude(), lp.getLongitude(),
distance);
rankedList.add(new PoiItemWithScore(item, matchScore, distance[0]));
}
rankedList.sort((a, b) -> {
if (a.matchScore != b.matchScore) {
return Integer.compare(b.matchScore, a.matchScore);
}
return Float.compare(a.distance, b.distance);
});
List<PoiItem> sortedList = new ArrayList<>();
for (PoiItemWithScore rp : rankedList) {
sortedList.add(rp.item);
}
poiList.clear();
poiList.addAll(sortedList);
adapter.notifyDataSetChanged();
binding.resultList.scrollToPosition(0);
binding.emptyView.setVisibility(View.GONE);
binding.resultList.setVisibility(View.VISIBLE);
adapter.setSelected(0);
onPoiItemSelected(poiList.get(0));
} else {
handleSearchError(rCode);
binding.emptyView.setText(selectionStage == 1 ? "⚠️ 未找到相关起点" : "⚠️ 未找到相关终点");
binding.emptyView.setVisibility(View.VISIBLE);
binding.resultList.setVisibility(View.GONE);
}
}
// 辅助方法:获取当前阶段的关键词
private String getCurrentInputKeyword() {
return selectionStage == 1 ?
binding.mapInput1.getText().toString().trim() :
binding.mapInput2.getText().toString().trim();
}
// 新增:排序用辅助类(放在 MapFragment 类末尾即可)
private static class PoiItemWithScore {
final PoiItem item;
final int matchScore;
final float distance;
PoiItemWithScore(PoiItem item, int matchScore, float distance) {
this.item = item;
this.matchScore = matchScore;
this.distance = distance;
}
}
@Override
public void onPoiItemSearched(PoiItem item, int rCode) {
// 必须实现
}
private void setupMap(Bundle savedInstanceState) {
mapView.onCreate(savedInstanceState);
aMap = mapView.getMap();
if (aMap != null) {
initMapSettings();
} else {
new Handler(Looper.getMainLooper()).post(() -> {
aMap = mapView.getMap();
if (aMap != null) {
initMapSettings();
} else {
waitAMapReady();
}
});
}
try {
geocodeSearch = new GeocodeSearch(requireContext());
geocodeSearch.setOnGeocodeSearchListener(this);
} catch (Exception e) {
e.printStackTrace();
}
}
private void waitAMapReady() {
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
int retry = 0;
@Override
public void run() {
if (mapView == null) return;
aMap = mapView.getMap();
if (aMap != null) {
initMapSettings();
} else if (retry++ < 30) {
new Handler(Looper.getMainLooper()).postDelayed(this, 100);
}
}
}, 100);
}
private void initMapSettings() {
UiSettings uiSettings = aMap.getUiSettings();
uiSettings.setZoomControlsEnabled(true);
uiSettings.setCompassEnabled(true);
uiSettings.setScrollGesturesEnabled(true);
uiSettings.setMyLocationButtonEnabled(true);
new Handler(Looper.getMainLooper()).post(() ->
aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(39.909186, 116.397411), 10f))
);
enableMyLocationLayer();
}
private void enableMyLocationLayer() {
if (aMap == null) return;
if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
MyLocationStyle myLocationStyle = new MyLocationStyle();
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);
aMap.setMyLocationStyle(myLocationStyle);
aMap.setMyLocationEnabled(true);
AMap.OnMyLocationChangeListener listener = location -> {
if (location != null && !userHasInteracted) {
LatLng curLatlng = new LatLng(location.getLatitude(), location.getLongitude());
// ✅ 记录真实位置
myCurrentLat = location.getLatitude();
myCurrentLng = location.getLongitude();
isLocationReady = true;
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(curLatlng, 16f));
userHasInteracted = true;
// 获取城市
LatLonPoint point = new LatLonPoint(myCurrentLat, myCurrentLng);
RegeocodeQuery query = new RegeocodeQuery(point, 200, GeocodeSearch.AMAP);
try {
geocodeSearch.getFromLocationAsyn(query);
} catch (Exception e) {
e.printStackTrace();
}
aMap.setOnMyLocationChangeListener(null);
}
};
aMap.setOnMyLocationChangeListener(listener);
} else {
ActivityCompat.requestPermissions(requireActivity(),
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
LOCATION_PERMISSION_REQUEST_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (aMap != null) {
MyLocationStyle myLocationStyle = new MyLocationStyle();
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATION_ROTATE_NO_CENTER);
aMap.setMyLocationStyle(myLocationStyle);
aMap.setMyLocationEnabled(true);
AMap.OnMyLocationChangeListener listener = location -> {
if (location != null && !userHasInteracted) {
LatLng curLatlng = new LatLng(location.getLatitude(), location.getLongitude());
// ✅ 同步记录位置
myCurrentLat = location.getLatitude();
myCurrentLng = location.getLongitude();
isLocationReady = true;
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(curLatlng, 16f));
userHasInteracted = true;
LatLonPoint point = new LatLonPoint(myCurrentLat, myCurrentLng);
RegeocodeQuery query = new RegeocodeQuery(point, 200, GeocodeSearch.AMAP);
try {
geocodeSearch.getFromLocationAsyn(query);
} catch (Exception e) {
e.printStackTrace();
}
aMap.setOnMyLocationChangeListener(null);
}
};
aMap.setOnMyLocationChangeListener(listener);
}
} else {
Toast.makeText(requireContext(), "定位权限被拒绝,部分功能受限", Toast.LENGTH_LONG).show();
currentCity = "全国";
}
}
}
@Override
public void onRegeocodeSearched(RegeocodeResult result, int rCode) {
if (rCode == 1000 && result != null && result.getRegeocodeAddress() != null) {
String city = result.getRegeocodeAddress().getCity();
currentCity = (city != null && !city.isEmpty()) ? city : result.getRegeocodeAddress().getProvince();
} else {
currentCity = "全国";
}
}
@Override
public void onGeocodeSearched(com.amap.api.services.geocoder.GeocodeResult geocodeResult, int i) {
// 忽略
}
@Override
public void onResume() {
super.onResume();
mapView.onResume();
if (!userHasInteracted) {
enableMyLocationLayer();
}
}
@Override
public void onPause() {
super.onPause();
mapView.onPause();
}
@Override
public void onDestroyView() {
super.onDestroyView();
mapView.onDestroy();
geocodeSearch = null;
binding = null;
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
// ✅ 完整保留原始的 setupSearchSuggestion 实现
private void setupSearchSuggestion() {
// 创建实时 POI 建议助手
RealTimePoiSuggestHelper suggestHelper = new RealTimePoiSuggestHelper(requireContext());
suggestHelper.setCurrentCity(currentCity);
suggestHelper.setCallback(suggestions -> {
if (suggestions.length > 0) {
ArrayAdapter<String> adapter = new ArrayAdapter<>(
requireContext(),
android.R.layout.simple_dropdown_item_1line,
suggestions
);
new Handler(Looper.getMainLooper()).post(() -> {
binding.mapInput1.setAdapter(adapter);
binding.mapInput2.setAdapter(adapter);
if (requireActivity().getCurrentFocus() == binding.mapInput1) {
binding.mapInput1.showDropDown();
} else if (requireActivity().getCurrentFocus() == binding.mapInput2) {
binding.mapInput2.showDropDown();
}
});
}
});
Handler handler = new Handler(Looper.getMainLooper());
Runnable[] pending1 = {null}, pending2 = {null};
// 使用 SimpleTextWatcher 简化注册
binding.mapInput1.addTextChangedListener(new SimpleTextWatcher(s -> {
if (pending1[0] != null) handler.removeCallbacks(pending1[0]);
if (s.length() == 0) {
binding.mapInput1.setAdapter(null);
return;
}
pending1[0] = () -> suggestHelper.requestSuggestions(s.toString());
handler.postDelayed(pending1[0], 300);
}));
binding.mapInput2.addTextChangedListener(new SimpleTextWatcher(s -> {
if (pending2[0] != null) handler.removeCallbacks(pending2[0]);
if (s.length() == 0) {
binding.mapInput2.setAdapter(null);
return;
}
pending2[0] = () -> suggestHelper.requestSuggestions(s.toString());
handler.postDelayed(pending2[0], 300);
}));
// 点击建议项时触发对应阶段的搜索
binding.mapInput1.setOnItemClickListener((parent, view, position, id) -> {
String keyword = (String) parent.getItemAtPosition(position);
if (keyword != null && !keyword.isEmpty()) {
binding.mapInput1.setText(keyword);
showStartpointSelection(keyword); // 直接触发起点搜索
}
});
binding.mapInput2.setOnItemClickListener((parent, view, position, id) -> {
String keyword = (String) parent.getItemAtPosition(position);
if (keyword != null && !keyword.isEmpty()) {
binding.mapInput2.setText(keyword);
showEndpointSelection(keyword); // 直接触发终点搜索
}
});
// 回车事件保持不变
binding.mapInput1.setOnEditorActionListener((v, actionId, event) -> {
if ((actionId & EditorInfo.IME_MASK_ACTION) == EditorInfo.IME_ACTION_SEARCH) {
performSearch();
return true;
}
return false;
});
binding.mapInput2.setOnEditorActionListener((v, actionId, event) -> {
if ((actionId & EditorInfo.IME_MASK_ACTION) == EditorInfo.IME_ACTION_SEARCH) {
performSearch();
return true;
}
return false;
});
}
private void handleSearchError(int rCode) {
String msg;
switch (rCode) {
case 12: msg = "API Key 错误"; break;
case 27: msg = "网络连接失败"; break;
case 30: msg = "SHA1 或包名错误"; break;
case 33: msg = "请求频繁"; break;
default: msg = "搜索失败: " + rCode; break;
}
Toast.makeText(requireContext(), msg, Toast.LENGTH_SHORT).show();
}
// ✅ 自定义 TextWatcher 类,保留原始写法
private static class SimpleTextWatcher implements android.text.TextWatcher {
private final java.util.function.Consumer<CharSequence> onTextChanged;
public SimpleTextWatcher(java.util.function.Consumer<CharSequence> onTextChanged) {
this.onTextChanged = onTextChanged;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
@Override
public void afterTextChanged(Editable s) {}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
onTextChanged.accept(s);
}
}
}
出现报错:Ambiguous method call: both 'RealTimePoiSuggestHelper.requestSuggestions(String)' and 'RealTimePoiSuggestHelper.requestSuggestions(String)' match
还有RealTimePoiSuggestHelper代码如下:package com.example.bus;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.amap.api.services.poisearch.PoiSearch.OnPoiSearchListener;
import java.util.ArrayList;
import java.util.List;
public class RealTimePoiSuggestHelper implements OnPoiSearchListener {
private final Context context;
private final Handler mainHandler = new Handler(Looper.getMainLooper());
private PoiSearch poiSearch;
private SuggestionCallback callback;
private String currentCity = "全国";
private double lat = 0, lng = 0;
private boolean useLocationBias = false;
public interface SuggestionCallback {
void onSuggestionsReady(String[] suggestions);
}
public RealTimePoiSuggestHelper(Context context) {
this.context = context;
}
public void setCurrentCity(String city) {
this.currentCity = city;
}
public void setLocationBias(double lat, double lng) {
this.lat = lat;
this.lng = lng;
this.useLocationBias = true;
}
public void setCallback(SuggestionCallback callback) {
this.callback = callback;
}
public void requestSuggestions(String keyword) {
if (keyword.isEmpty() || callback == null) return;
PoiSearch.Query query = new PoiSearch.Query(keyword, "", currentCity);
query.setPageSize(20);
query.requireSubPois(false);
if (useLocationBias && lat != 0 && lng != 0) {
LatLonPoint lp = new LatLonPoint(lat, lng);
query.setLocation(lp);
}
try {
poiSearch = new PoiSearch(context, query);
poiSearch.setOnPoiSearchListener(this);
poiSearch.searchPOIAsyn();
} catch (Exception e) {
e.printStackTrace();
notifyEmpty();
}
}
@Override
public void onPoiSearched(PoiResult result, int rCode) {
if (rCode == 1000 && result != null && result.getPois() != null && !result.getPois().isEmpty()) {
List<PoiItemWithScore> rankedList = new ArrayList<>();
float[] distance = new float[1];
for (com.amap.api.services.core.PoiItem item : result.getPois()) {
String title = item.getTitle().toLowerCase();
String key = keyword.toLowerCase();
// 匹配评分
int matchScore = 0;
if (title.equals(key)) matchScore = 3;
else if (title.startsWith(key)) matchScore = 2;
else if (title.contains(key)) matchScore = 1;
else continue; // 不包含直接跳过
// 计算距离
if (useLocationBias && lat != 0 && lng != 0) {
LatLonPoint lp = item.getLatLonPoint();
android.location.Location.distanceBetween(lat, lng, lp.getLatitude(), lp.getLongitude(), distance);
} else {
distance[0] = 0; // 默认为0不影响排序
}
rankedList.add(new PoiItemWithScore(item, matchScore, distance[0]));
}
// 排序:匹配度高 → 距离近
rankedList.sort((a, b) -> {
if (a.matchScore != b.matchScore) {
return Integer.compare(b.matchScore, a.matchScore);
}
return Float.compare(a.distance, b.distance);
});
// 取前8个作为建议
int count = Math.min(rankedList.size(), 8);
String[] suggestions = new String[count];
for (int i = 0; i < count; i++) {
suggestions[i] = rankedList.get(i).item.getTitle();
}
notifySuccess(suggestions);
} else {
notifyEmpty();
}
}
@Override
public void onPoiItemSearched(com.amap.api.services.core.PoiItem item, int rCode) {
// 忽略
}
private void notifySuccess(@NonNull String[] suggestions) {
mainHandler.post(() -> callback.onSuggestionsReady(suggestions));
}
private void notifyEmpty() {
mainHandler.post(() -> callback.onSuggestionsReady(new String[0]));
}
// 辅助类:用于排序
private static class PoiItemWithScore {
final com.amap.api.services.core.PoiItem item;
final int matchScore;
final float distance;
PoiItemWithScore(com.amap.api.services.core.PoiItem item, int matchScore, float distance) {
this.item = item;
this.matchScore = matchScore;
this.distance = distance;
}
}
// 缓存关键词(用于排序)
private String keyword = "";
public void requestSuggestions(String keyword) {
this.keyword = keyword; // 存储关键词用于后续比较
if (keyword.isEmpty() || callback == null) return;
// ... 原始逻辑不变 ...
}
}
出现报错'requestSuggestions(String)' is already defined in 'com.example.bus.RealTimePoiSuggestHelper'。我不知道你刚刚对我的RealTimePoiSuggestHelper改了多少,这是我原来的RealTimePoiSuggestHelper代码:
package com.example.bus;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import androidx.annotation.NonNull;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.amap.api.services.poisearch.PoiSearch.OnPoiSearchListener;
import java.util.ArrayList;
import java.util.List;
public class RealTimePoiSuggestHelper implements OnPoiSearchListener {
private final Context context;
private final Handler mainHandler = new Handler(Looper.getMainLooper());
private PoiSearch poiSearch;
private SuggestionCallback callback;
private String currentCity = "全国";
private double lat = 0, lng = 0;
private boolean useLocationBias = false;
public interface SuggestionCallback {
void onSuggestionsReady(String[] suggestions);
}
public RealTimePoiSuggestHelper(Context context) {
this.context = context;
}
public void setCurrentCity(String city) {
this.currentCity = city;
}
public void setLocationBias(double lat, double lng) {
this.lat = lat;
this.lng = lng;
this.useLocationBias = true;
}
public void setCallback(SuggestionCallback callback) {
this.callback = callback;
}
// 外部调用此方法发起实时建议查询
public void requestSuggestions(String keyword) {
if (keyword.isEmpty() || callback == null) return;
PoiSearch.Query query = new PoiSearch.Query(keyword, "", currentCity);
query.setPageSize(20); // 控制数量,加快返回
query.requireSubPois(false);
if (useLocationBias) {
LatLonPoint lp = new LatLonPoint(lat, lng);
query.setLocation(lp);
}
try {
poiSearch = new PoiSearch(context, query);
poiSearch.setOnPoiSearchListener(this);
poiSearch.searchPOIAsyn();
} catch (Exception e) {
e.printStackTrace();
notifyEmpty();
}
}
@Override
public void onPoiSearched(PoiResult result, int rCode) {
if (rCode == 1000 && result != null && result.getPois() != null) {
List<String> names = new ArrayList<>();
for (int i = 0; i < result.getPois().size(); i++) {
names.add(result.getPois().get(i).getTitle());
}
String[] arr = names.toArray(new String[0]);
notifySuccess(arr);
} else {
notifyEmpty();
}
}
@Override
public void onPoiItemSearched(com.amap.api.services.core.PoiItem item, int rCode) {
// 忽略
}
private void notifySuccess(@NonNull String[] suggestions) {
mainHandler.post(() -> callback.onSuggestionsReady(suggestions));
}
private void notifyEmpty() {
mainHandler.post(() -> callback.onSuggestionsReady(new String[0]));
}
}
相比之下我感觉好像改了很多,而这些报错问题,我目前也不知道怎么解决
最新发布