startservice.setOnClickListener(this)报错

本文介绍了在Android应用开发中遇到的startService.setOnClickListener(this)编译不通过的问题,分析了原因并提供了解决方案。通过添加 implements View.OnClickListener 到Activity类,实现了按钮点击事件监听器,确保代码正确运行。

startservice.setOnClickListener(this);编译不通过

下面代码却是OK

startservice.OnClickListener onclicklistenner = new Button.OnClickListener(){
    //@Override
    public void onClick(View v) {
  
    }
};

缺少implements View.OnClickListener,加上即可

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
}



    @Override
    public void onClick(View view) {

    }
package com.aprilshowersz.music; import android.annotation.SuppressLint; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.content.SharedPreferences; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.util.Log; import android.view.View; import android.widget.SeekBar; import androidx.activity.EdgeToEdge; import androidx.appcompat.app.AppCompatActivity; import androidx.core.graphics.Insets; import androidx.core.view.ViewCompat; import androidx.core.view.WindowInsetsCompat; import com.aprilshowersz.music.bean.Music; import com.aprilshowersz.music.databinding.ActivityMainBinding; import com.bumptech.glide.Glide; import java.io.Serializable; import java.util.concurrent.TimeUnit; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private Handler updateProgressHandler; private MusicService musicService; private boolean isServiceBound = false; private Music music; private ActivityMainBinding binding; private static final String EMPTY_TIME = "00:00"; private final ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { try { MusicService.MusicBinder binder = (MusicService.MusicBinder) service; musicService = binder.getService(); isServiceBound = true; Log.d(TAG, "服务连接成功"); // 确保音乐服务已连接后更新UI if (music != null) { updateUI(); } // 设置进度更新监听器(主线程更新UI) if (musicService != null) { musicService.setOnProgressUpdateListener((currentPosition, duration) -> { runOnUiThread(() -> { if (binding != null) { binding.sb.setMax(duration); binding.sb.setProgress(currentPosition); binding.progress.setText(formatTime(currentPosition)); binding.total.setText(formatTime(duration)); } }); }); } } catch (Exception e) { Log.e(TAG, "服务连接异常", e); isServiceBound = false; } } @Override public void onServiceDisconnected(ComponentName name) { isServiceBound = false; musicService = null; Log.d(TAG, "服务断开连接"); } }; @SuppressLint("SetTextI18n") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); EdgeToEdge.enable(this); binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); // 处理窗口边距 ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> { Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars()); v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return insets; }); // 加载用户信息 SharedPreferences sp = getSharedPreferences("user", MODE_PRIVATE); String account = sp.getString("account", "游客"); binding.account.setText("用户名:" + account); // 获取传递的音乐数据 Intent intent = getIntent(); if (intent.hasExtra("music")) { music = (Music) intent.getSerializableExtra("music"); } // 初始化UI和音乐播放 initUI(); initMusicPlayer(); } @SuppressLint("SetTextI18n") private void initUI() { if (binding == null) return; // 初始化默认显示 binding.total.setText(EMPTY_TIME); binding.music.setText("未选择音乐"); // 加载并显示专辑封面(默认图) Glide.with(this) .load(R.drawable.music) .error(R.drawable.baseline_error_24) .into(binding.iv); // 设置按钮点击事件 binding.start.setOnClickListener(v -> playMusic()); binding.pause.setOnClickListener(v -> pauseMusic()); binding.continue1.setOnClickListener(v -> continueMusic()); // 设置进度条事件 binding.sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser && isServiceBound && musicService != null) { musicService.seekTo(progress); } } @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) { if (isServiceBound && musicService != null) { musicService.seekTo(seekBar.getProgress()); } } }); // 设置返回按钮 binding.iv.setOnClickListener(v -> finish()); binding.exit.setOnClickListener(v -> finish()); } private void initMusicPlayer() { if (music != null) { // 绑定音乐服务 Intent serviceIntent = new Intent(this, MusicService.class); bindService(serviceIntent, serviceConnection, BIND_AUTO_CREATE); } } private void playMusic() { if (isServiceBound && musicService != null && music != null) { Intent playIntent = new Intent(this, MusicService.class); playIntent.setAction("PLAY"); playIntent.putExtra("path", new String(music.getPath())); // 确保路径为String startService(playIntent); } } private void pauseMusic() { if (isServiceBound && musicService != null) { Intent pauseIntent = new Intent(this, MusicService.class); pauseIntent.setAction("PAUSE"); startService(pauseIntent); } } private void continueMusic() { if (isServiceBound && musicService != null) { Intent continueIntent = new Intent(this, MusicService.class); continueIntent.setAction("CONTINUE"); startService(continueIntent); } } // 格式化时间显示 @SuppressLint("DefaultLocale") private String formatTime(int milliseconds) { if (milliseconds <= 0) return EMPTY_TIME; return String.format("%02d:%02d", TimeUnit.MILLISECONDS.toMinutes(milliseconds) % TimeUnit.HOURS.toMinutes(1), TimeUnit.MILLISECONDS.toSeconds(milliseconds) % TimeUnit.MINUTES.toSeconds(1)); } @SuppressLint("SetTextI18n") private void updateUI() { if (music == null || binding == null) return; // 修复:将char[]转换为String并处理空值 String musicName = music.getName() != null ? new String(music.getName()) : "未知名称"; String singerName = music.getSinger() != null ? new String(music.getSinger()) : "未知歌手"; String musicTime = music.getTime() != null ? new String(music.getTime()) : EMPTY_TIME; binding.total.setText(musicTime); binding.music.setText(musicName + " - " + singerName); // 加载并显示专辑封面 if (music.getPic() != null) { Glide.with(this) .load(music.getPic()) .placeholder(R.drawable.music) .error(R.drawable.baseline_error_24) .into(binding.iv); } // 更新进度条和时间显示 if (isServiceBound && musicService != null) { int duration = musicService.getDuration(); int currentPosition = musicService.getCurrentPosition(); binding.sb.setMax(duration); binding.sb.setProgress(currentPosition); binding.progress.setText(formatTime(currentPosition)); binding.total.setText(formatTime(duration)); } } @Override protected void onResume() { super.onResume(); // 重新绑定服务 if (music != null) { Intent serviceIntent = new Intent(this, MusicService.class); bindService(serviceIntent, serviceConnection, BIND_AUTO_CREATE); } } @Override protected void onPause() { super.onPause(); // 解除绑定服务,但不停止服务 if (isServiceBound) { unbindService(serviceConnection); isServiceBound = false; } } @Override protected void onDestroy() { super.onDestroy(); // 解除绑定并停止服务 if (isServiceBound) { unbindService(serviceConnection); isServiceBound = false; } // 停止音乐服务 Intent stopIntent = new Intent(this, MusicService.class); stopIntent.setAction("STOP"); startService(stopIntent); // 清理Glide资源 Glide.with(this).clear(binding.iv); // 移除Handler回调 if (updateProgressHandler != null) { updateProgressHandler.removeCallbacksAndMessages(null); } } }错误: 找不到符号 String musicTime = music.getTime() != null ? new String(music.getTime()) : EMPTY_TIME; ^ 符号: 方法 getTime() 位置: 类型为Music的变量 music
06-19
var LogFloatWindow = (function () { function LogFloatWindow(y) { this.x = 0; this.y = y || device.height * 0.5; this.workThread = null; this.storage = $storages.create('floatLogWindow'); this.onStart = null; this.onStop = null; } LogFloatWindow.prototype.init = function () { var _this = this; this.floatyLogW = $floaty.rawWindow( '<card id="root" h="150" cardBackgroundColor="#b3000000" cardElevation="0" cardCornerRadius="0" gravity="center_vertical">\n <vertical id="layout" marginLeft="22">\n <horizontal w="*" margin="5">\n <horizontal h="auto" w="0" layout_weight="1">\n <text id="title" text="" textSize="13dp" textColor="#FFD700" textStyle="bold" maxLines="1" ellipsize="end" style="Widget/AppCompat.Button.Borderless" />\n <text id="label" text="" textSize="13dp" textColor="#1E90FF" textStyle="bold" maxLines="1" ellipsize="end" style="Widget/AppCompat.Button.Borderless" marginLeft="10" />\n </horizontal>\n <Chronometer id="runTime" textSize="13dp" textColor="#03D96A" style="Widget/AppCompat.Button.Borderless" textStyle="bold" />\n </horizontal>\n <button gravity="center_horizontal" textColor="#DC143C" bg="#FFF5EE" h="1" padding="0" margin="0" textStyle="bold" />\n <console id="console" w="*" h="*" padding="5" />\n </vertical>\n </card>' ); this.controller = floaty.rawWindow( '<vertical>\n <vertical h="150" id="main">\n <text layout_weight="5" id="start" textStyle="bold" gravity="center" w="22dp" text="\u542F\u52A8" textColor="#333333" bg="#00a86b" />\n <text layout_weight="5" id="hideLog" textStyle="bold" gravity="center" w="22dp" text="\u65E5\u5FD7" textColor="#333333" bg="#FF8E12" />\n <text layout_weight="5" id="stop" textStyle="bold" gravity="center" w="22dp" text="\u7ED3\u675F" textColor="#333333" bg="#ee4d2d" />\n </vertical>\n </vertical>' ); ui.post(function () { setTimeout(function () { if (_this.floatyLogW && _this.controller) { try { _this.logButton = _this.controller.hideLog; _this.startButton = _this.controller.start; _this.stopButton = _this.controller.stop; _this.runTimeView = _this.floatyLogW.runTime; if (_this.floatyLogW.main) { _this.floatyLogW.main.getRootView().setAlpha(0.8); } _this.floatyLogW.setTouchable(false); _this.runTimeView.setFormat('运行时长 %s '); _this.runTimeView.setBase(android.os.SystemClock.elapsedRealtime()); var floatConsole = _this.floatyLogW.console; floatConsole.setConsole(runtime.console); floatConsole.setInputEnabled(false); floatConsole.setColor('V', '#ffff00'); floatConsole.setColor('I', '#ffffff'); floatConsole.setColor('D', '#ffff00'); floatConsole.setColor('W', '#673ab7'); floatConsole.setColor('E', '#ff0000'); floatConsole.setTextSize(13); _this.floatyLogW.setSize(-1, -2); var storedX = _this.storage.get('floatLogWindowX', _this.x); var storedY = _this.storage.get('floatLogWindowY', _this.y); _this.floatyLogW.setPosition(storedX, storedY); _this.controller.setPosition(storedX, storedY); _this.logButton.setText('隐藏'); _this.logButton.attr('background', '#d1c7b7'); if (_this.startButton) { _this.startButton.setOnClickListener(new java.lang.Object({ onClick: function () { _this.handleStart(_this); } })); } if (_this.stopButton) { _this.stopButton.setOnClickListener(new java.lang.Object({ onClick: function () { _this.handleStop(_this); } })); } if (_this.logButton) { _this.logButton.setOnClickListener(new java.lang.Object({ onClick: function () { _this.handleLog(_this); } })); } } catch (error) { console.error("初始化悬浮窗时出错:", error); } } }, 300); }); }; LogFloatWindow.getInstance = function () { if (!LogFloatWindow.instance) { LogFloatWindow.instance = new LogFloatWindow(); } return LogFloatWindow.instance; }; LogFloatWindow.prototype.handleStop = function (_this) { $app.launchPackage(context.getPackageName()); toast('停止本次任务'); if (_this.workThread) { _this.workThread.interrupt(); } _this.floatyLogW.close(); _this.controller.close(); $threads.shutDownAll(); }; LogFloatWindow.prototype.handleLog = function (_this) { var x = _this.storage.get('floatLogWindowX', 0); var y = _this.storage.get('floatLogWindowY', device.height * 0.5); ui.post(function () { if (_this.logButton.attr('text') == '隐藏') { _this.floatyLogW.setPosition(3000, 3000); _this.logButton.attr('text', '日志'); _this.logButton.attr('background', '#FF8E12'); } else { _this.logButton.setText('隐藏'); _this.logButton.attr('background', '#d1c7b7'); _this.floatyLogW.setPosition(x, y); } }); }; LogFloatWindow.prototype.handleStart = function (_this) { toast('开始本次任务'); if (!_this.workThread || !_this.workThread.isAlive()) { if (_this.controller) _this.toggleStatus(true); _this.workThread = threads.start(function () { try { _this.info('任务开始'); _this.onStart && _this.onStart(); if (_this.controller) _this.toggleStatus(false); _this.info('任务完成'); } catch (e) { var info = $debug.getStackTrace(e); if (info.includes('com.stardust.autojs.runtime.exception.ScriptInterruptedException')) { _this.info('停止任务'); } else { _this.error('任务报错: ' + e); _this.error('程序运行失败: ' + info); } _this.toggleStatus(false); } }); } else { _this.onStop && _this.onStop(); _this.toggleStatus(false); _this.workThread && _this.workThread.interrupt(); } }; LogFloatWindow.prototype.dateFormat = function (date, fmt_str) { return new java.text.SimpleDateFormat(fmt_str).format(date || new Date()); }; LogFloatWindow.prototype.info = function (msg) { console.info('['.concat(this.dateFormat(new Date(), 'HH:mm:ss'), ']').concat(msg)); }; LogFloatWindow.prototype.error = function (msg) { console.error('['.concat(this.dateFormat(new Date(), 'HH:mm:ss'), ']').concat(msg)); }; LogFloatWindow.prototype.setFloatyTitle = function (title) { ui.run(function () { if (this.floatyLogW && this.floatyLogW.title) { this.floatyLogW.title.attr('text', title); } }); }; LogFloatWindow.prototype.setFloatySubTitle = function (label) { ui.run(function () { if (this.floatyLogW && this.floatyLogW.label) { this.floatyLogW.label.attr('text', label); } }); }; LogFloatWindow.prototype.toggleStatus = function (enabled) { $ui.post(function () { if (this.floatyLogW && this.controller && this.runTimeView && this.startButton) { if (enabled) { this.runTimeView.setBase(android.os.SystemClock.elapsedRealtime()); this.runTimeView.start(); this.startButton.setText('停止'); this.startButton.attr('background', '#05a7f4'); } else { this.runTimeView.stop(); this.startButton.setText('启动'); this.startButton.attr('background', '#00a86b'); } } }); }; return LogFloatWindow; })(); var logWindow = LogFloatWindow.getInstance(); logWindow.init(); logWindow.setFloatyTitle("任务日志"); logWindow.setFloatySubTitle("运行状态"); logWindow.onStart = function () { logWindow.info("任务已启动"); for (let i = 0; i < 5; i++) { logWindow.info("执行第 " + (i + 1) + " 次任务"); threads.sleep(1000); // 模拟任务延迟 } }; logWindow.handleStart(logWindow); setTimeout(function () { logWindow.handleStop(logWindow); }, 3000000); AutoJsPro,以上代码哪出错了,把代码结合在一起给我
05-07
可是你刚刚提供的代码出现报错。目前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])); } } 相比之下我感觉好像改了很多,而这些报错问题,我目前也不知道怎么解决
最新发布
12-02
你修改的代码出现报错:Cannot resolve method 'getRecodeAddress' in 'RegeocodeResult'原本的代码是没有报错的,我不需要添加什么别的杂七杂八的功能,仅仅是去掉那个预选即可,改成直接选中。这是我原本的代码: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.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.inputmethod.InputMethodManager; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import com.amap.api.services.core.AMapException; import com.amap.api.services.core.LatLonPoint; import com.amap.api.services.geocoder.GeocodeQuery; import com.amap.api.services.geocoder.GeocodeResult; import com.amap.api.services.geocoder.GeocodeSearch; import com.amap.api.services.geocoder.RegeocodeQuery; import com.amap.api.services.geocoder.RegeocodeResult; 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.recyclerview.widget.RecyclerView; // 👉 新增导入:用于动态修改约束 import androidx.constraintlayout.widget.ConstraintSet; import androidx.constraintlayout.widget.ConstraintLayout; // 🔺 新增导入:用于设置 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.PoiItem; import com.amap.api.services.poisearch.PoiResult; import com.amap.api.services.poisearch.PoiSearch; import com.amap.api.services.help.Inputtips; import com.amap.api.services.help.Tip; import com.example.bus.R; import com.example.bus.RoutePlanActivity; import com.example.bus.ResultAdapter; import com.example.bus.databinding.FragmentMapBinding; import java.util.ArrayList; import java.util.List; public class MapFragment extends Fragment implements PoiSearch.OnPoiSearchListener, GeocodeSearch.OnGeocodeSearchListener { private FragmentMapBinding binding; private MapView mapView; private AMap aMap; private Inputtips inputTips; // 数据 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 = "全国"; // 默认 fallback private static final int LOCATION_PERMISSION_REQUEST_CODE = 1001; // 👉 新增:记录面板是否已展开(用于首次设置约束) private boolean isResultPanelShown = false; // ✅ 标记是否已经居中过“我的位置” private boolean userHasInteracted = false; // ✅ 新增:用于延迟执行“默认选中第一条” private boolean isMapInitialized = false; private boolean hasPendingSelect = false; private PoiItem pendingFirstItem = null; // ✅ 新增:用于反地理编码 private GeocodeSearch geocodeSearch; @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() { // 初始化 RecyclerView 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 constraintSet = new ConstraintSet(); constraintSet.clone((ConstraintLayout) binding.getRoot()); constraintSet.connect( R.id.map_view, ConstraintSet.BOTTOM, R.id.container_result_list, ConstraintSet.TOP, 0 ); constraintSet.applyTo((ConstraintLayout) 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); try { poiSearch = new PoiSearch(requireContext(), query); poiSearch.setOnPoiSearchListener(this); poiSearch.searchPOIAsyn(); } catch (Exception e) { e.printStackTrace(); Toast.makeText(requireContext(), "搜索失败", Toast.LENGTH_SHORT).show(); } } /** * 用户点击了某个 POI item */ 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) { requireActivity().runOnUiThread(() -> { if (rCode == 1000 && result != null && result.getPois() != null && !result.getPois().isEmpty()) { List<PoiItem> newPoiList = result.getPois(); poiList.clear(); poiList.addAll(newPoiList); if (adapter == null) { adapter = new ResultAdapter(poiList, this::onPoiItemSelected); binding.resultList.setLayoutManager(new LinearLayoutManager(requireContext())); binding.resultList.setAdapter(adapter); } else { adapter.notifyDataSetChanged(); // 🔺 新增:滚动到顶部 binding.resultList.scrollToPosition(0); } binding.emptyView.setVisibility(View.GONE); binding.resultList.setVisibility(View.VISIBLE); hasPendingSelect = true; pendingFirstItem = poiList.get(0); if (isMapInitialized) { maybeSelectFirstItem(); } } else { handleSearchError(rCode); binding.resultList.setVisibility(View.GONE); binding.emptyView.setVisibility(View.VISIBLE); binding.emptyView.setText("⚠️ 未找到相关地点"); } }); } @Override public void onPoiItemSearched(PoiItem item, int rCode) {} private void setupMap(Bundle savedInstanceState) { mapView.onCreate(savedInstanceState); aMap = mapView.getMap(); if (aMap != null) { initMapSettings(); isMapInitialized = true; maybeSelectFirstItem(); } else { waitAMapReady(); } // ✅ 初始化 GeocodeSearch 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(); isMapInitialized = true; maybeSelectFirstItem(); } else if (retry++ < 50) { new Handler(Looper.getMainLooper()).postDelayed(this, 200); } } }, 200); } private void initMapSettings() { UiSettings uiSettings = aMap.getUiSettings(); uiSettings.setZoomControlsEnabled(true); uiSettings.setCompassEnabled(true); uiSettings.setScrollGesturesEnabled(true); uiSettings.setMyLocationButtonEnabled(true); } private void maybeSelectFirstItem() { if (!hasPendingSelect || pendingFirstItem == null || aMap == null) return; LatLng latLng = new LatLng( pendingFirstItem.getLatLonPoint().getLatitude(), pendingFirstItem.getLatLonPoint().getLongitude() ); // 移除旧的临时 marker if (startMarker != null && selectionStage == 1 && selectedStartPoi == null) { startMarker.remove(); startMarker = null; } if (endMarker != null && selectionStage == 2 && selectedEndPoi == null) { endMarker.remove(); endMarker = null; } // 🔺 根据当前阶段设置预览颜色 float hue = selectionStage == 1 ? BitmapDescriptorFactory.HUE_AZURE : // 起点预览用浅蓝 BitmapDescriptorFactory.HUE_ORANGE; // 终点预览用橙色 MarkerOptions options = new MarkerOptions() .position(latLng) .title("预览:" + pendingFirstItem.getTitle()) .icon(BitmapDescriptorFactory.defaultMarker(hue)); if (selectionStage == 1) { startMarker = aMap.addMarker(options); } else if (selectionStage == 2) { endMarker = aMap.addMarker(options); } aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14f)); hasPendingSelect = false; pendingFirstItem = null; } private void setupSearchSuggestion() { try { inputTips = new Inputtips(requireContext(), new Inputtips.InputtipsListener() { @Override public void onGetInputtips(List<Tip> tipList, int rCode) { if (rCode == 1000 && tipList != null && !tipList.isEmpty()) { String[] arr = new String[tipList.size()]; for (int i = 0; i < tipList.size(); i++) { arr[i] = tipList.get(i).getName(); } ArrayAdapter<String> adapter = new ArrayAdapter<>( requireContext(), android.R.layout.simple_dropdown_item_1line, arr ); requireActivity().runOnUiThread(() -> { if (requireActivity().getCurrentFocus() == binding.mapInput1) { binding.mapInput1.setAdapter(adapter); } else if (requireActivity().getCurrentFocus() == binding.mapInput2) { binding.mapInput2.setAdapter(adapter); } }); } else { requireActivity().runOnUiThread(() -> { binding.mapInput1.setAdapter(null); binding.mapInput2.setAdapter(null); }); handleSearchError(rCode); } } }); } catch (Exception e) { e.printStackTrace(); Toast.makeText(requireContext(), "智能提示初始化失败", Toast.LENGTH_SHORT).show(); } Handler handler = new Handler(Looper.getMainLooper()); Runnable[] pending1 = {null}, pending2 = {null}; binding.mapInput1.addTextChangedListener(new SimpleTextWatcher(s -> { if (pending1[0] != null) handler.removeCallbacks(pending1[0]); if (s.length() == 0) { binding.mapInput1.setAdapter(null); } else { pending1[0] = () -> { try { inputTips.requestInputtips(s.toString(), currentCity); // ✅ 使用当前城市 } catch (AMapException e) { e.printStackTrace(); } }; handler.postDelayed(pending1[0], 600); } })); binding.mapInput2.addTextChangedListener(new SimpleTextWatcher(s -> { if (pending2[0] != null) handler.removeCallbacks(pending2[0]); if (s.length() == 0) { binding.mapInput2.setAdapter(null); } else { pending2[0] = () -> { try { inputTips.requestInputtips(s.toString(), currentCity); // ✅ 使用当前城市 } catch (AMapException e) { e.printStackTrace(); } }; handler.postDelayed(pending2[0], 600); } })); } 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(); } @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(); inputTips = null; geocodeSearch = null; binding = null; } @Override public void onSaveInstanceState(@NonNull Bundle outState) { super.onSaveInstanceState(outState); mapView.onSaveInstanceState(outState); } private void enableMyLocationLayer() { if (aMap == null) return; if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { try { 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()); aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(curLatlng, 16f)); userHasInteracted = true; // ✅ 获取城市信息 LatLonPoint latLonPoint = new LatLonPoint(location.getLatitude(), location.getLongitude()); RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 200, GeocodeSearch.AMAP); try { geocodeSearch.getFromLocationAsyn(query); } catch (Exception e) { e.printStackTrace(); } aMap.setOnMyLocationChangeListener(null); } }; aMap.setOnMyLocationChangeListener(listener); } catch (Exception e) { e.printStackTrace(); } } 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()); aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(curLatlng, 16f)); userHasInteracted = true; // ✅ 获取城市信息 LatLonPoint latLonPoint = new LatLonPoint(location.getLatitude(), location.getLongitude()); RegeocodeQuery query = new RegeocodeQuery(latLonPoint, 200, GeocodeSearch.AMAP); try { geocodeSearch.getFromLocationAsyn(query); } catch (Exception e) { e.printStackTrace(); } aMap.setOnMyLocationChangeListener(null); } }; aMap.setOnMyLocationChangeListener(listener); } } } } // ✅ 接收反地理编码结果 @Override public void onRegeocodeSearched(RegeocodeResult result, int rCode) { if (rCode == 1000 && result != null && result.getRegeocodeAddress() != null) { String city = result.getRegeocodeAddress().getCity(); if (city != null && !city.isEmpty()) { currentCity = city; } else { currentCity = result.getRegeocodeAddress().getProvince(); } } else { currentCity = "全国"; } } @Override public void onGeocodeSearched(GeocodeResult geocodeResult, int i) {} 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); } } } 请你在这个基础上进行修改,其它已有功能不改变,仅做最小量的修改即可,为我提供修改好的完整代码
11-29
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值