第二,这个界面的搜索问题,目前代码如下:package com.example.bus;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.Button;
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 java.util.ArrayList;
import java.util.List;
public class SearchResultActivity extends AppCompatActivity implements PoiSearch.OnPoiSearchListener {
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 static final int LOCATION_PERMISSION_REQUEST_CODE = 1001;
@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);
setupSearch();
// ✅ 在地图初始化完成后尝试开启蓝点(会自动请求权限)
enableMyLocationLayer();
}
private void initViews() {
searchBtn = findViewById(R.id.search_btn);
resultListView = findViewById(R.id.result_list);
goToBtn = findViewById(R.id.btn_go_to);
goToBtn.setEnabled(false);
}
private void setupMap(Bundle savedInstanceState) {
mapView = findViewById(R.id.map_view);
mapView.onCreate(savedInstanceState);
if (aMap == null) {
aMap = mapView.getMap();
UiSettings uiSettings = aMap.getUiSettings();
uiSettings.setZoomControlsEnabled(true);
uiSettings.setCompassEnabled(true);
uiSettings.setScrollGesturesEnabled(true);
// 设置地图点击事件:添加选中位置标记
aMap.setOnMapClickListener(latLng -> {
if (selectedMarker != null) {
selectedMarker.remove();
}
selectedMarker = aMap.addMarker(new MarkerOptions()
.position(latLng)
.title("选中位置"));
goToBtn.setEnabled(true);
});
// 默认视角为中国中心
aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(39.909186, 116.397411), 10f));
}
}
/**
* 开启地图蓝点(我的位置)
* 如果已有权限则直接启用,否则请求权限
* ✅ 修改:使用 MyLocationStyle 控制行为,避免自动跳转
*/
private void enableMyLocationLayer() {
if (aMap == null) return;
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
try {
// 👇 新增:自定义定位样式,只定位一次,不持续追踪
MyLocationStyle myLocationStyle = new MyLocationStyle();
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE); // 关键修改!
aMap.setMyLocationStyle(myLocationStyle); // 应用样式
aMap.setMyLocationEnabled(true); // 再开启图层
Toast.makeText(this, "已开启定位(单次居中)", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "无法开启定位图层", Toast.LENGTH_SHORT).show();
}
} 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) {
if (aMap != null) {
// 👇 同样需要重新设置样式
MyLocationStyle myLocationStyle = new MyLocationStyle();
myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);
aMap.setMyLocationStyle(myLocationStyle);
aMap.setMyLocationEnabled(true);
Toast.makeText(this, "已成功开启定位功能", Toast.LENGTH_SHORT).show();
}
} else {
boolean hasCoarse = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
== PackageManager.PERMISSION_GRANTED;
if (hasCoarse) {
Toast.makeText(this, "建议开启精确位置以获得更准确定位", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "定位权限被拒绝,部分功能受限", Toast.LENGTH_LONG).show();
}
}
}
}
private void setupSearch() {
String keyword = getIntent().getStringExtra("keyword");
if (keyword != null && !keyword.isEmpty()) {
performSearch(keyword);
}
searchBtn.setOnClickListener(v -> {
String text = ((android.widget.EditText) findViewById(R.id.search_input)).getText().toString().trim();
if (!text.isEmpty()) {
performSearch(text);
} else {
Toast.makeText(this, "请输入关键词", Toast.LENGTH_SHORT).show();
}
});
goToBtn.setOnClickListener(v -> {
LatLonPoint targetPoint = null;
String title = "选中位置";
if (selectedMarker != null) {
LatLng pos = selectedMarker.getPosition();
targetPoint = new LatLonPoint(pos.latitude, pos.longitude);
title = selectedMarker.getTitle();
} else if (!poiList.isEmpty()) {
PoiItem item = poiList.get(0);
targetPoint = item.getLatLonPoint();
title = item.getTitle();
}
if (targetPoint == null) {
Toast.makeText(this, "暂无目标位置", Toast.LENGTH_SHORT).show();
return;
}
Intent intent = new Intent(this, RoutePlanActivity.class);
intent.putExtra(RoutePlanActivity.EXTRA_SOURCE, RoutePlanActivity.SOURCE_FROM_HOME_SEARCH);
intent.putExtra("target_lat", targetPoint.getLatitude());
intent.putExtra("target_lng", targetPoint.getLongitude());
intent.putExtra("target_title", title);
startActivity(intent);
});
}
private void performSearch(String keyword) {
PoiSearch.Query query = isLikelyBusStop(keyword) ?
new PoiSearch.Query(keyword, "15", "全国") :
new PoiSearch.Query(keyword, "", "全国");
query.setPageSize(20);
query.setPageNum(0);
try {
poiSearch = new PoiSearch(this, query);
poiSearch.setOnPoiSearchListener(this);
poiSearch.searchPOIAsyn();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, "搜索启动失败", Toast.LENGTH_SHORT).show();
}
}
private boolean isLikelyBusStop(String keyword) {
return keyword.contains("公交") || keyword.contains("地铁") ||
keyword.contains("BRT") || keyword.endsWith("站") || keyword.endsWith("场");
}
@Override
public void onPoiSearched(PoiResult result, int rCode) {
if (rCode == 1000 && result != null && result.getPois() != null) {
poiList.clear();
poiList.addAll(result.getPois());
if (adapter == null) {
adapter = new ResultAdapter(poiList, item -> {
if (selectedMarker != null) {
selectedMarker.remove();
}
LatLng latLng = new LatLng(item.getLatLonPoint().getLatitude(), item.getLatLonPoint().getLongitude());
selectedMarker = aMap.addMarker(new MarkerOptions().position(latLng).title(item.getTitle()));
aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 14f));
goToBtn.setEnabled(true);
});
resultListView.setLayoutManager(new LinearLayoutManager(this));
resultListView.setAdapter(adapter);
} else {
adapter.notifyDataSetChanged();
}
goToBtn.setEnabled(!poiList.isEmpty());
} else {
String msg = rCode == 17 ? "高德Key校验失败" : "搜索失败: 错误码=" + rCode;
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
}
}
@Override
public void onPoiItemSearched(PoiItem item, int rCode) {
// 不处理详情查询
}
@Override
protected void onResume() {
super.onResume();
mapView.onResume();
}
@Override
protected void onPause() {
super.onPause();
mapView.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
mapView.onDestroy();
if (aMap != null) {
aMap.setMyLocationEnabled(false); // 关闭蓝点
}
if (poiSearch != null) {
poiSearch.setOnPoiSearchListener(null);
}
mapView = null;
aMap = null;
poiSearch = null;
}
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
mapView.onSaveInstanceState(outState);
}
@Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
}
我希望搜索的时候能够弹出提示信息,像HomeFragment一样,HomeFragment代码如下:package com.example.bus.ui.home;
import android.content.Intent;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
import com.amap.api.services.help.Inputtips;
import com.amap.api.services.help.Tip;
import android.widget.ArrayAdapter;
import android.text.TextWatcher;
import android.text.Editable;
import com.example.bus.MainActivity;
import com.example.bus.SearchResultActivity;
import com.example.bus.databinding.FragmentHomeBinding;
import com.amap.api.services.core.AMapException;
import java.util.List;
public class HomeFragment extends Fragment {
private FragmentHomeBinding binding;
private Inputtips inputTips;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
HomeViewModel homeViewModel =
new ViewModelProvider(this).get(HomeViewModel.class);
binding = FragmentHomeBinding.inflate(inflater, container, false);
View root = binding.getRoot();
final TextView textView = binding.textHome;
homeViewModel.getText().observe(getViewLifecycleOwner(), textView::setText);
setupSearchSuggestion();
binding.homeSearch.setOnClickListener(v -> {
String keyword = binding.homeInput.getText().toString().trim();
if (keyword.isEmpty()) {
Toast.makeText(requireContext(), "请输入关键词", Toast.LENGTH_SHORT).show();
return;
}
// ✅ 请求权限,权限通过后再跳转 SearchResultActivity
MainActivity activity = (MainActivity) requireActivity();
activity.ensureFineLocationPermission(() -> {
Intent intent = new Intent(requireContext(), SearchResultActivity.class);
intent.putExtra("keyword", keyword);
startActivity(intent);
});
});
return root;
}
private void setupSearchSuggestion() {
try {
inputTips = new Inputtips(requireContext(), new Inputtips.InputtipsListener() {
@Override
public void onGetInputtips(List<Tip> tipList, int rCode) {
if (rCode == 1000 && !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
);
binding.homeInput.setAdapter(adapter);
} else {
// 可选:清空建议列表
binding.homeInput.setAdapter(null);
handleSearchError(rCode);
}
}
});
} catch (AMapException e) {
throw new RuntimeException(e);
}
binding.homeInput.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 (s.length() > 0) {
try {
inputTips.requestInputtips(s.toString(), "全国"); // 这个方法在你的版本里确实 throws AMapException
} catch (AMapException e) {
e.printStackTrace();
Toast.makeText(requireContext(), "输入提示请求失败: " + e.getMessage(), Toast.LENGTH_SHORT).show();
}
} else {
binding.homeInput.setAdapter(null);
}
}
@Override
public void afterTextChanged(Editable s) {}
});
}
private void handleSearchError(int rCode) {
String msg;
switch (rCode) {
case 12:
msg = "API Key 错误,请检查 AndroidManifest.xml";
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 onDestroyView() {
super.onDestroyView();
inputTips = null;
binding = null;
}
}
fragment_home.xml代码如下:<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.home.HomeFragment"
android:fitsSystemWindows="true"
android:layout_marginTop="?attr/actionBarSize">
<!-- 🔵 垂直指南线:5%、50%、95% -->
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_05"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.05" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_50"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.50" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_95"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.95" />
<!-- 🔍 输入框 -->
<AutoCompleteTextView
android:id="@+id/home_input"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="请输入需要查询的公交线路或站点"
android:textColorHint="#777777"
android:completionThreshold="1"
android:textColor="@color/black"
android:background="@drawable/rounded_edittext"
android:minHeight="48dp"
android:textSize="14sp"
android:padding="12dp"
app:layout_constraintTop_toTopOf="@id/guideline_05"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/home_search"
app:layout_constraintHorizontal_chainStyle="packed"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp" />
<!-- 🔎 搜索按钮 -->
<Button
android:id="@+id/home_search"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="搜索"
app:layout_constraintTop_toTopOf="@id/home_input"
app:layout_constraintBottom_toBottomOf="@id/home_input"
app:layout_constraintStart_toEndOf="@id/home_input"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="16dp" />
<!-- 🚌 图片:居中偏上 -->
<ImageView
android:id="@+id/image_bus"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:src="@drawable/bus"
app:layout_constraintTop_toTopOf="@id/guideline_50"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintWidth_percent="0.6"
android:scaleType="fitCenter" />
<!-- ℹ️ 底部说明文字 -->
<TextView
android:id="@+id/text_home"
android:textColor="#777777"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:textAlignment="center"
android:textSize="11sp"
app:layout_constraintTop_toTopOf="@id/guideline_95"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
activity_search_result.xml代码如下:<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:layout_marginTop="?attr/actionBarSize">
<!-- ====== 指南线:用于精确百分比定位 ====== -->
<!-- 地图底部 -->
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_60"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.60" />
<!-- 结果列表顶部留白结束位置 -->
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_65"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.65" />
<!-- 按钮顶部位置 -->
<androidx.constraintlayout.widget.Guideline
android:id="@+id/guideline_90"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.90" />
<!-- 🔍 输入框 -->
<AutoCompleteTextView
android:id="@+id/search_input"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="请输入需要查询的公交线路或站点"
android:textColorHint="#777777"
android:textColor="@color/black"
android:background="@drawable/rounded_edittext"
android:minHeight="48dp"
android:textSize="14sp"
android:padding="12dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/search_btn"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginStart="16dp"
android:layout_marginEnd="8dp" />
<!-- 🔎 搜索按钮 -->
<Button
android:id="@+id/search_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="搜索"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toEndOf="@id/search_input"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginEnd="16dp" />
<!-- 🗺️ 地图视图 -->
<com.amap.api.maps.MapView
android:id="@+id/map_view"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginTop="20dp"
app:layout_constraintTop_toBottomOf="@id/search_input"
app:layout_constraintBottom_toTopOf="@id/guideline_60"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<!-- 🔲 固定高度容器:包裹 RecyclerView -->
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/container_result_list"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="@id/guideline_65"
app:layout_constraintBottom_toTopOf="@id/guideline_90"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_marginHorizontal="16dp">
<!-- 🔽 RecyclerView:内部可滚动 -->
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/result_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:nestedScrollingEnabled="false"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
<!-- 空状态提示 -->
<TextView
android:id="@+id/empty_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="暂无搜索结果"
android:textColorHint="#777777"
android:textColor="@color/black"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
<!-- “到这去”按钮 -->
<Button
android:id="@+id/btn_go_to"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="到这去"
android:layout_margin="16dp"
app:layout_constraintTop_toTopOf="@id/guideline_90"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
<!-- 🌀 加载进度条 -->
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:elevation="10dp" />
</androidx.constraintlayout.widget.ConstraintLayout>
现在,请你做最小量的修改达成这样的目的,给我提供修改后的完整代码