调整地址输入
This commit is contained in:
@@ -7,27 +7,34 @@ import android.graphics.BitmapFactory;
|
|||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
|
import android.graphics.Rect;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
|
import android.graphics.drawable.ColorDrawable;
|
||||||
import android.graphics.drawable.GradientDrawable;
|
import android.graphics.drawable.GradientDrawable;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
|
import android.text.InputType;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
import android.view.inputmethod.InputMethodManager;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.ListView;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@@ -117,6 +124,9 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
|||||||
|
|
||||||
private View modeMenu; //模式选择
|
private View modeMenu; //模式选择
|
||||||
private TextView tvStationName, tvStationAddr, planToggleBtn;
|
private TextView tvStationName, tvStationAddr, planToggleBtn;
|
||||||
|
private ListView suggestionList; // 输入提示列表
|
||||||
|
private ArrayAdapter<String> suggestionAdapter; // 提示列表适配器
|
||||||
|
private List<Tip> currentTipList; // 当前提示列表
|
||||||
//时间 费用 里程 路费
|
//时间 费用 里程 路费
|
||||||
private TextView tvDuration, tvDistance, tvTolls, tvTollsFuel;
|
private TextView tvDuration, tvDistance, tvTolls, tvTollsFuel;
|
||||||
|
|
||||||
@@ -150,6 +160,8 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
|||||||
container = new FrameLayout(context);
|
container = new FrameLayout(context);
|
||||||
container.setClickable(true);
|
container.setClickable(true);
|
||||||
container.setFocusable(true);
|
container.setFocusable(true);
|
||||||
|
container.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
|
||||||
|
|
||||||
|
|
||||||
mapView = new MapView(context);
|
mapView = new MapView(context);
|
||||||
mapView.onCreate(null);
|
mapView.onCreate(null);
|
||||||
@@ -179,9 +191,10 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private LinearLayout bottomContainer;
|
||||||
private void initOverlays(Context context) {
|
private void initOverlays(Context context) {
|
||||||
// --- 底部主容器 (包含两个互斥显示的面板) ---
|
// --- 底部主容器 (包含两个互斥显示的面板) ---
|
||||||
LinearLayout bottomContainer = new LinearLayout(context);
|
bottomContainer = new LinearLayout(context);
|
||||||
bottomContainer.setOrientation(LinearLayout.VERTICAL);
|
bottomContainer.setOrientation(LinearLayout.VERTICAL);
|
||||||
bottomContainer.setGravity(Gravity.BOTTOM);
|
bottomContainer.setGravity(Gravity.BOTTOM);
|
||||||
|
|
||||||
@@ -194,18 +207,72 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
|||||||
searchArea = new LinearLayout(context);
|
searchArea = new LinearLayout(context);
|
||||||
searchArea.setOrientation(LinearLayout.VERTICAL);
|
searchArea.setOrientation(LinearLayout.VERTICAL);
|
||||||
searchArea.setBackground(getRoundedDrawable(Color.WHITE, 16));
|
searchArea.setBackground(getRoundedDrawable(Color.WHITE, 16));
|
||||||
searchArea.setElevation(dp2px(10));
|
|
||||||
int p = dp2px(15);
|
int p = dp2px(15);
|
||||||
searchArea.setPadding(p, p, p, p);
|
searchArea.setPadding(p, p, p, p);
|
||||||
|
searchArea.setFocusable(true);
|
||||||
|
searchArea.setFocusableInTouchMode(true);
|
||||||
|
|
||||||
endInput = new EditText(context);
|
endInput = new EditText(context);
|
||||||
endInput.setHint("请输入目的地,不输入则自动匹配推荐加氢站");
|
endInput.setHint("请输入目的地,不输入则自动匹配推荐加氢站");
|
||||||
endInput.setTextSize(13);
|
endInput.setTextSize(13);
|
||||||
endInput.setHintTextColor(Color.LTGRAY);
|
endInput.setHintTextColor(Color.GRAY);
|
||||||
endInput.setPadding(dp2px(12), dp2px(12), dp2px(12), dp2px(12));
|
endInput.setPadding(dp2px(12), dp2px(12), dp2px(12), dp2px(12));
|
||||||
endInput.setBackground(getRoundedDrawable(Color.parseColor("#F8F8F8"), 8));
|
endInput.setBackground(getRoundedDrawable(Color.parseColor("#F8F8F8"), 8));
|
||||||
endInput.setSingleLine(true);
|
endInput.setSingleLine(true);
|
||||||
|
endInput.setInputType(InputType.TYPE_CLASS_TEXT); // 明确输入类型
|
||||||
endInput.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
|
endInput.setImeOptions(EditorInfo.IME_ACTION_SEARCH);
|
||||||
|
endInput.setFocusable(true);
|
||||||
|
endInput.setFocusableInTouchMode(true);
|
||||||
|
endInput.setClickable(true);
|
||||||
|
endInput.setCursorVisible(true);
|
||||||
|
|
||||||
|
// 针对 EditText 的特殊处理
|
||||||
|
endInput.setOnTouchListener((v, event) -> {
|
||||||
|
if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||||
|
v.requestFocus();
|
||||||
|
v.postDelayed(() -> {
|
||||||
|
InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
if (imm != null) {
|
||||||
|
// 使用 SHOW_FORCED 或确保结果成功
|
||||||
|
imm.showSoftInput(v, InputMethodManager.SHOW_FORCED);
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 处理搜索键按下
|
||||||
|
endInput.setOnEditorActionListener((v, actionId, event) -> {
|
||||||
|
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
|
||||||
|
suggestionList.setVisibility(View.GONE);
|
||||||
|
// 可以在这里直接触发路线规划,但保持原来的按钮点击逻辑
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化提示列表
|
||||||
|
currentTipList = new ArrayList<>();
|
||||||
|
suggestionList = new ListView(context);
|
||||||
|
suggestionList.setBackgroundColor(Color.WHITE);
|
||||||
|
suggestionList.setDividerHeight(1);
|
||||||
|
suggestionList.setDivider(new ColorDrawable(Color.LTGRAY));
|
||||||
|
suggestionList.setPadding(dp2px(5), dp2px(5), dp2px(5), dp2px(5));
|
||||||
|
suggestionAdapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1);
|
||||||
|
suggestionList.setAdapter(suggestionAdapter);
|
||||||
|
suggestionList.setVisibility(View.GONE);
|
||||||
|
suggestionList.setOnItemClickListener((parent, view, position, id) -> {
|
||||||
|
Tip tip = currentTipList.get(position);
|
||||||
|
if (tip.getPoint() != null) {
|
||||||
|
endPoint = new LatLng(tip.getPoint().getLatitude(), tip.getPoint().getLongitude());
|
||||||
|
String name = tip.getName();
|
||||||
|
String district = tip.getDistrict();
|
||||||
|
endName = name;
|
||||||
|
endInput.setText(district != null && !district.isEmpty() ? name + " " + district : name);
|
||||||
|
suggestionList.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
endInput.addTextChangedListener(new TextWatcher() {
|
endInput.addTextChangedListener(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
@@ -214,11 +281,15 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
|||||||
@Override
|
@Override
|
||||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
if (s.length() > 1) {
|
if (s.length() > 1) {
|
||||||
InputtipsQuery query = new InputtipsQuery(s.toString(), "");
|
// 使用当前位置的城市进行搜索
|
||||||
|
String city = currentLatLng != null ? "" : "";
|
||||||
|
InputtipsQuery query = new InputtipsQuery(s.toString(), city);
|
||||||
query.setCityLimit(true);
|
query.setCityLimit(true);
|
||||||
Inputtips inputtips = new Inputtips(mContext, query);
|
Inputtips inputtips = new Inputtips(mContext, query);
|
||||||
inputtips.setInputtipsListener(NativeMapView.this);
|
inputtips.setInputtipsListener(NativeMapView.this);
|
||||||
inputtips.requestInputtipsAsyn();
|
inputtips.requestInputtipsAsyn();
|
||||||
|
} else {
|
||||||
|
suggestionList.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,7 +297,14 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
|||||||
public void afterTextChanged(Editable s) {
|
public void afterTextChanged(Editable s) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
endInput.setOnFocusChangeListener((v, hasFocus) -> {
|
||||||
|
if (!hasFocus) {
|
||||||
|
suggestionList.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
searchArea.addView(endInput);
|
searchArea.addView(endInput);
|
||||||
|
searchArea.addView(suggestionList);
|
||||||
|
|
||||||
View vSpace = new View(context);
|
View vSpace = new View(context);
|
||||||
searchArea.addView(vSpace, new LinearLayout.LayoutParams(1, dp2px(12)));
|
searchArea.addView(vSpace, new LinearLayout.LayoutParams(1, dp2px(12)));
|
||||||
@@ -235,7 +313,7 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
|||||||
planBtn.setText("规划路线");
|
planBtn.setText("规划路线");
|
||||||
planBtn.setTextColor(Color.WHITE);
|
planBtn.setTextColor(Color.WHITE);
|
||||||
planBtn.setTypeface(Typeface.DEFAULT_BOLD);
|
planBtn.setTypeface(Typeface.DEFAULT_BOLD);
|
||||||
planBtn.setBackground(getRoundedDrawable(Color.parseColor("#017143"), 10));
|
planBtn.setBackground(getRoundedDrawable(Color.parseColor("#017143"), 99));
|
||||||
planBtn.setOnClickListener(v -> calculateRouteBeforeNavi());
|
planBtn.setOnClickListener(v -> calculateRouteBeforeNavi());
|
||||||
searchArea.addView(planBtn, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp2px(48)));
|
searchArea.addView(planBtn, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, dp2px(48)));
|
||||||
|
|
||||||
@@ -300,8 +378,40 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
|||||||
locParams.setMargins(0, 0, dp2px(15), dp2px(285)); // 调高一点,避开底部的面板
|
locParams.setMargins(0, 0, dp2px(15), dp2px(285)); // 调高一点,避开底部的面板
|
||||||
locParams.gravity = Gravity.BOTTOM | Gravity.END;
|
locParams.gravity = Gravity.BOTTOM | Gravity.END;
|
||||||
container.addView(locBtn, locParams);
|
container.addView(locBtn, locParams);
|
||||||
}
|
|
||||||
|
|
||||||
|
//最后调用监听函数
|
||||||
|
addKeyboardListener();
|
||||||
|
}
|
||||||
|
private void addKeyboardListener() {
|
||||||
|
container.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
|
||||||
|
Rect r = new Rect();
|
||||||
|
// 获取当前窗口可视区域
|
||||||
|
container.getWindowVisibleDisplayFrame(r);
|
||||||
|
|
||||||
|
// screenHeight - 可视区域高度 = 键盘高度
|
||||||
|
int screenHeight = container.getRootView().getHeight();
|
||||||
|
int keypadHeight = screenHeight - r.bottom;
|
||||||
|
|
||||||
|
// 如果键盘高度大于屏幕的 15%,说明键盘弹出了
|
||||||
|
if (keypadHeight > screenHeight * 0.15) {
|
||||||
|
// 键盘弹出:增加底部 Margin
|
||||||
|
updateBottomMargin(keypadHeight);
|
||||||
|
} else {
|
||||||
|
// 键盘收起:恢复原有 Margin (你代码中设置的是 dp2px(65))
|
||||||
|
updateBottomMargin(dp2px(65));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
private void updateBottomMargin(int bottomPx) {
|
||||||
|
if (bottomContainer != null) {
|
||||||
|
FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) bottomContainer.getLayoutParams();
|
||||||
|
if (params != null) {
|
||||||
|
// 动态设置底部间距
|
||||||
|
params.setMargins(dp2px(12), 0, dp2px(12), bottomPx);
|
||||||
|
bottomContainer.setLayoutParams(params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
private LinearLayout createDetailPanel(Context context) {
|
private LinearLayout createDetailPanel(Context context) {
|
||||||
LinearLayout panel = new LinearLayout(context);
|
LinearLayout panel = new LinearLayout(context);
|
||||||
panel.setOrientation(LinearLayout.VERTICAL);
|
panel.setOrientation(LinearLayout.VERTICAL);
|
||||||
@@ -407,11 +517,40 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
|||||||
@Override
|
@Override
|
||||||
public void onGetInputtips(List<Tip> tipList, int rCode) {
|
public void onGetInputtips(List<Tip> tipList, int rCode) {
|
||||||
if (rCode == 1000 && tipList != null && !tipList.isEmpty()) {
|
if (rCode == 1000 && tipList != null && !tipList.isEmpty()) {
|
||||||
Tip tip = tipList.get(0);
|
currentTipList.clear();
|
||||||
if (tip.getPoint() != null) {
|
currentTipList.addAll(tipList);
|
||||||
endPoint = new LatLng(tip.getPoint().getLatitude(), tip.getPoint().getLongitude());
|
|
||||||
endName = tip.getName();
|
List<String> suggestionNames = new ArrayList<>();
|
||||||
|
for (Tip tip : tipList) {
|
||||||
|
String name = tip.getName();
|
||||||
|
String district = tip.getDistrict();
|
||||||
|
// 在提示中显示名称和区域
|
||||||
|
String displayText = district != null && !district.isEmpty() ? name + " " + district : name;
|
||||||
|
suggestionNames.add(displayText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suggestionAdapter.clear();
|
||||||
|
suggestionAdapter.addAll(suggestionNames);
|
||||||
|
suggestionAdapter.notifyDataSetChanged();
|
||||||
|
|
||||||
|
// 显示提示列表
|
||||||
|
new Handler(Looper.getMainLooper()).post(() -> {
|
||||||
|
if (suggestionNames.size() > 0) {
|
||||||
|
suggestionList.setVisibility(View.VISIBLE);
|
||||||
|
// 限制显示的高度
|
||||||
|
int height = Math.min(suggestionNames.size() * dp2px(45), dp2px(200));
|
||||||
|
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
|
height
|
||||||
|
);
|
||||||
|
suggestionList.setLayoutParams(params);
|
||||||
|
} else {
|
||||||
|
suggestionList.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 请求失败或无结果,隐藏提示列表
|
||||||
|
new Handler(Looper.getMainLooper()).post(() -> suggestionList.setVisibility(View.GONE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -619,6 +758,13 @@ public class NativeMapView implements PlatformView, LocationSource, AMapLocation
|
|||||||
aMap.setMyLocationEnabled(true);
|
aMap.setMyLocationEnabled(true);
|
||||||
aMap.setOnMarkerClickListener(this);
|
aMap.setOnMarkerClickListener(this);
|
||||||
|
|
||||||
|
// 添加地图触摸监听器,点击地图时隐藏提示列表
|
||||||
|
aMap.setOnMapClickListener(latLng -> {
|
||||||
|
if (suggestionList != null && suggestionList.getVisibility() == View.VISIBLE) {
|
||||||
|
suggestionList.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
MyLocationStyle myLocationStyle = new MyLocationStyle();
|
MyLocationStyle myLocationStyle = new MyLocationStyle();
|
||||||
try {
|
try {
|
||||||
Bitmap carBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.car);
|
Bitmap carBitmap = BitmapFactory.decodeResource(mContext.getResources(), R.drawable.car);
|
||||||
|
|||||||
@@ -45,12 +45,30 @@ class NativePageIOS extends StatelessWidget {
|
|||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
height: MediaQuery.of(context).size.height - 100,
|
height: MediaQuery.of(context).size.height - 100,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
child: AndroidView(
|
child: PlatformViewLink(
|
||||||
viewType: 'NativeFirstPage', // 与Android原生端注册的标识一致
|
viewType: 'NativeFirstPage',
|
||||||
gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>{}.toSet(),
|
surfaceFactory: (context, controller) {
|
||||||
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
|
return AndroidViewSurface(
|
||||||
creationParamsCodec: const StandardMessageCodec(),
|
controller: controller as AndroidViewController,
|
||||||
layoutDirection: TextDirection.ltr,
|
gestureRecognizers: const <Factory<OneSequenceGestureRecognizer>>{},
|
||||||
|
hitTestBehavior: PlatformViewHitTestBehavior.opaque,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onCreatePlatformView: (params) {
|
||||||
|
// 使用 initSurfaceAndroidView 强制开启 Hybrid Composition
|
||||||
|
return PlatformViewsService.initSurfaceAndroidView(
|
||||||
|
id: params.id,
|
||||||
|
viewType: 'NativeFirstPage',
|
||||||
|
layoutDirection: TextDirection.ltr,
|
||||||
|
creationParams: {}, // 你的参数
|
||||||
|
creationParamsCodec: const StandardMessageCodec(),
|
||||||
|
onFocus: () {
|
||||||
|
params.onFocusChanged(true);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
..addOnPlatformViewCreatedListener(params.onPlatformViewCreated)
|
||||||
|
..create();
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user