From 15f5680b532238290d0adf095a93e5af1c5f1203 Mon Sep 17 00:00:00 2001
From: zuoxiao <470321431@qq.com>
Date: 星期五, 07 二月 2025 17:14:57 +0800
Subject: [PATCH] 1.添加显示隐藏取水口、分水房功能 2.完善图例自定义控件功能和显示 3.处理工单添加选择时间功能
---
app/src/main/assets/js/map.js | 71 ++++
app/src/main/java/com/dayu/pipirrapp/activity/OrderDealActivity.java | 13
app/src/main/res/layout/activity_order_deal.xml | 10
app/src/main/java/com/dayu/pipirrapp/MyApplication.java | 2
app/src/main/java/com/dayu/pipirrapp/dao/DivideDao.java | 4
app/src/main/java/com/dayu/pipirrapp/dao/MarkerDao.java | 2
app/src/main/java/com/dayu/pipirrapp/utils/DateUtils.java | 14
app/src/main/res/drawable/divide_home_unselected.xml | 25 +
app/src/main/res/layout/fragment_map.xml | 17
expand_button/src/main/res/values/attrs.xml | 6
app/src/main/res/drawable/marker_blue.xml | 9
app/src/main/res/drawable/marker_unselected.xml | 9
expand_button/src/main/java/com/example/expand_button/ExpandButton.kt | 416 +++++++++++++++++++++++----
app/src/main/java/com/dayu/pipirrapp/fragment/MapFragment.java | 222 +++++++++-----
app/src/main/res/drawable/divide_home_blue.xml | 25 +
15 files changed, 672 insertions(+), 173 deletions(-)
diff --git a/app/src/main/assets/js/map.js b/app/src/main/assets/js/map.js
index 85b3113..bfd0f8d 100644
--- a/app/src/main/assets/js/map.js
+++ b/app/src/main/assets/js/map.js
@@ -27,6 +27,12 @@
let pipeLineList = [];
let currentPipePath = [];
+ // 瀛樺偍鎵�鏈夊彇姘村彛鏍囪鐨勬暟缁�
+ let waterIntakeMarkers = [];
+
+ // 瀛樺偍鎵�鏈夊垎姘存埧鏍囪鐨勬暟缁�
+ let divideMarkers = [];
+
// 灏嗘柟娉曟寕杞藉埌 window 涓�
function mountMethodToWindow() {
window.locationOverLay = locationOverLay;
@@ -46,6 +52,10 @@
window.hideAllPipeLines = hideAllPipeLines;
window.clearAllPipeLines = clearAllPipeLines;
window.addPipeNetwork = addPipeNetwork;
+ window.hideAllWaterIntakes = hideAllWaterIntakes;
+ window.showAllWaterIntakes = showAllWaterIntakes;
+ window.hideAllDivides = hideAllDivides;
+ window.showAllDivides = showAllDivides;
}
@@ -242,19 +252,26 @@
let label = new T.Label({
text: `<div style='position:absolute;left:-50%;transform: translateX(-50%);'>${name}<div>`,
position: marker.getLngLat(),
- offset: new T.Point(0, 8), // 璁剧疆鏍囨敞鏂囧瓧鐨勪綅缃�
- opacity: 1, // 璁剧疆鏂囨湰鐨勬樉绀轰笉閫忔槑搴︼紙鑼冨洿0-1锛�
+ offset: new T.Point(0, 8),
+ opacity: 1,
});
- label.setBorderLine(0); // 璁剧疆鏂囨湰鐨勮竟妗嗙嚎瀹�
- label.setBackgroundColor("transparent"); // 璁剧疆鏂囨湰鐨勮儗鏅壊锛堥�忔槑鑹诧級
+ label.setBorderLine(0);
+ label.setBackgroundColor("transparent");
label.setFontColor("#FFFFFF");
label.setFontSize(10);
marker.label = label;
if (isRed) {
lastClickedMarker = marker;
}
+
+ // 灏嗘爣璁板拰鏍囩瀛樺偍鍒版暟缁勪腑
+ waterIntakeMarkers.push({
+ marker: marker,
+ label: label
+ });
+
map.addOverLay(label);
- map.addOverLay(marker); // 灏嗘爣娉ㄦ坊鍔犲埌鍦板浘涓�
+ map.addOverLay(marker);
return "addMarker鍔犺浇鎴愬姛 id:" + id
}
//鏇存柊浣嶅潗鏍�
@@ -538,6 +555,13 @@
if (isRed) {
lastClickedMarker = marker;
}
+
+ // 灏嗗垎姘存埧鏍囪鍜屾爣绛惧瓨鍌ㄥ埌鏁扮粍涓�
+ divideMarkers.push({
+ marker: marker,
+ label: label
+ });
+
map.addOverLay(label);
map.addOverLay(marker); // 灏嗘爣娉ㄦ坊鍔犲埌鍦板浘涓�
return "addMarker鍔犺浇鎴愬姛 id:" + id
@@ -577,9 +601,44 @@
window.Android.showDivideDetail(data);
}
+ /**
+ * 闅愯棌鎵�鏈夊彇姘村彛鏍囪
+ */
+ function hideAllWaterIntakes() {
+ waterIntakeMarkers.forEach(item => {
+ map.removeOverLay(item.marker);
+ map.removeOverLay(item.label);
+ });
+ }
+ /**
+ * 鏄剧ず鎵�鏈夊彇姘村彛鏍囪
+ */
+ function showAllWaterIntakes() {
+ waterIntakeMarkers.forEach(item => {
+ map.addOverLay(item.marker);
+ map.addOverLay(item.label);
+ });
+ }
+ /**
+ * 闅愯棌鎵�鏈夊垎姘存埧鏍囪
+ */
+ function hideAllDivides() {
+ divideMarkers.forEach(item => {
+ map.removeOverLay(item.marker);
+ map.removeOverLay(item.label);
+ });
+ }
-
+ /**
+ * 鏄剧ず鎵�鏈夊垎姘存埧鏍囪
+ */
+ function showAllDivides() {
+ divideMarkers.forEach(item => {
+ map.addOverLay(item.marker);
+ map.addOverLay(item.label);
+ });
+ }
})();
diff --git a/app/src/main/java/com/dayu/pipirrapp/MyApplication.java b/app/src/main/java/com/dayu/pipirrapp/MyApplication.java
index 1bb8f2f..3681ff6 100644
--- a/app/src/main/java/com/dayu/pipirrapp/MyApplication.java
+++ b/app/src/main/java/com/dayu/pipirrapp/MyApplication.java
@@ -32,7 +32,7 @@
// JPushInterface.setDebugMode(true);
// JPushInterface.init(this);
- CrashReport.initCrashReport(getApplicationContext(), "3d4bcf7046", false);
+ CrashReport.initCrashReport(getApplicationContext(), "f6dea280a2", false);
// // 璁剧疆鍏ㄥ眬鐨刄ncaughtExceptionHandler
// Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
diff --git a/app/src/main/java/com/dayu/pipirrapp/activity/OrderDealActivity.java b/app/src/main/java/com/dayu/pipirrapp/activity/OrderDealActivity.java
index 0d707c0..411a8e2 100644
--- a/app/src/main/java/com/dayu/pipirrapp/activity/OrderDealActivity.java
+++ b/app/src/main/java/com/dayu/pipirrapp/activity/OrderDealActivity.java
@@ -23,13 +23,11 @@
import com.dayu.pipirrapp.bean.net.AddProcessingRequest;
import com.dayu.pipirrapp.bean.net.InsectionResult;
import com.dayu.pipirrapp.bean.net.UplodFileState;
-import com.dayu.pipirrapp.dao.DaoSingleton;
import com.dayu.pipirrapp.databinding.ActivityOrderDealBinding;
import com.dayu.pipirrapp.fragment.OrderFragment;
import com.dayu.pipirrapp.net.ApiManager;
import com.dayu.pipirrapp.net.BaseResponse;
import com.dayu.pipirrapp.net.subscribers.SubscriberListener;
-import com.dayu.pipirrapp.net.upload.UploadFileListener;
import com.dayu.pipirrapp.tool.FileUploadUtils;
import com.dayu.pipirrapp.tool.FullyGridLayoutManager;
import com.dayu.pipirrapp.tool.GlideEngine;
@@ -58,10 +56,8 @@
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import retrofit2.Call;
@@ -87,6 +83,7 @@
Map<String, UplodFileState> uplodFileStates = new HashMap<>();
String workOrderId;
LatLonBean latLonBean;
+ String strCompleteTime;
/**
* 瀹氫綅鐩戝惉
@@ -124,13 +121,15 @@
new CardDatePickerDialog.Builder(this)
.setTitle("閫夋嫨澶勭悊鏃堕棿")
.setOnChoose("纭畾", aLong -> {
- //aLong = millisecond
-
+ //aLong = millisecond
+ strCompleteTime = com.dayu.pipirrapp.utils.DateUtils.formatTimestamp(aLong);
+ binding.timeData.setText(strCompleteTime);
return null;
})
.showBackNow(true)
.setDefaultTime(time)
.setMaxTime(time)
+ .setMinTime(time - 365L * 24 * 60 * 60 * 1000) // 璁剧疆鏈�灏忔椂闂翠负涓�骞村墠
.setDisplayType(list)
.build().show();
});
@@ -306,7 +305,7 @@
result.setContent(binding.contentET.getText().toString());
result.setInspectorId(MyApplication.myApplication.userId);
result.setWorkOrderId(workOrderId);
- result.setCompleteTime(com.dayu.pipirrapp.utils.DateUtils.getNowDateToMMStr());
+ result.setCompleteTime(strCompleteTime);
if (latLonBean != null) {
result.setLat(String.valueOf(latLonBean.getLatitude()));
result.setLng(String.valueOf(latLonBean.getLongitude()));
diff --git a/app/src/main/java/com/dayu/pipirrapp/dao/DivideDao.java b/app/src/main/java/com/dayu/pipirrapp/dao/DivideDao.java
index aa9295a..a574aa0 100644
--- a/app/src/main/java/com/dayu/pipirrapp/dao/DivideDao.java
+++ b/app/src/main/java/com/dayu/pipirrapp/dao/DivideDao.java
@@ -17,7 +17,7 @@
import io.reactivex.rxjava3.core.Maybe;
/**
- * DivideDao -
+ * DivideDao -鍒嗘按鎴�
*
* @author zuoxiao
* @version 1.0
@@ -52,6 +52,6 @@
@Query("select * from DivideBean")
Single<List<DivideBean>> findAllToSingle();
- @Query("SELECT * FROM divide")
+ @Query("SELECT * FROM DivideBean")
Maybe<List<DivideBean>> getAll(); // 鏀逛负杩斿洖Maybe<List<DivideBean>>
}
diff --git a/app/src/main/java/com/dayu/pipirrapp/dao/MarkerDao.java b/app/src/main/java/com/dayu/pipirrapp/dao/MarkerDao.java
index 0323b6d..4bd9344 100644
--- a/app/src/main/java/com/dayu/pipirrapp/dao/MarkerDao.java
+++ b/app/src/main/java/com/dayu/pipirrapp/dao/MarkerDao.java
@@ -19,7 +19,7 @@
* author: zuo
* Date: 2024-09-30
* Time: 14:39
- * 澶囨敞锛�
+ * 澶囨敞锛氬彇姘村彛
*/
@Dao
public interface MarkerDao {
diff --git a/app/src/main/java/com/dayu/pipirrapp/fragment/MapFragment.java b/app/src/main/java/com/dayu/pipirrapp/fragment/MapFragment.java
index ddfb4c4..7229bca 100644
--- a/app/src/main/java/com/dayu/pipirrapp/fragment/MapFragment.java
+++ b/app/src/main/java/com/dayu/pipirrapp/fragment/MapFragment.java
@@ -5,9 +5,11 @@
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -20,6 +22,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.core.content.ContextCompat;
import androidx.lifecycle.Observer;
import com.dayu.pipirrapp.MyApplication;
@@ -62,6 +65,7 @@
import com.dayu.pipirrapp.utils.WebViewUtils;
import com.dayu.pipirrapp.view.ConfirmDialog;
import com.dayu.pipirrapp.view.TipUtil;
+import com.example.expand_button.ExpandButton;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
@@ -80,6 +84,7 @@
import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.disposables.CompositeDisposable;
import io.reactivex.rxjava3.schedulers.Schedulers;
+import kotlin.Triple;
/**
* author: zuo
@@ -178,69 +183,69 @@
private void loadLocalData() {
// 寮傛鍔犺浇涓績鐐规暟鎹�
compositeDisposable.add(
- DaoSingleton.getAsynchInstance(this.getContext()).centerPointDao().findFirst()
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(result -> {
- centerPointBean = result;
- if (centerPointBean == null) {
- getCenterPoint();
- } else {
- jumpCenterPoint();
- }
- }, throwable -> {
- Log.e(TAG, "Load centerPoint error: " + throwable);
- getCenterPoint();
- }, () -> {
- // 褰揗aybe涓虹┖鏃惰皟鐢�
- getCenterPoint();
- })
+ DaoSingleton.getAsynchInstance(this.getContext()).centerPointDao().findFirst()
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(result -> {
+ centerPointBean = result;
+ if (centerPointBean == null) {
+ getCenterPoint();
+ } else {
+ jumpCenterPoint();
+ }
+ }, throwable -> {
+ Log.e(TAG, "Load centerPoint error: " + throwable);
+ getCenterPoint();
+ }, () -> {
+ // 褰揗aybe涓虹┖鏃惰皟鐢�
+ getCenterPoint();
+ })
);
// 寮傛鍔犺浇鍙栨按鍙f暟鎹�
compositeDisposable.add(
- DaoSingleton.getAsynchInstance(this.getContext()).markerDao().getAll()
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(markers -> {
- if (markers == null || markers.isEmpty()) {
- getMarkerData();
- } else {
- for (MarkerBean marker : markers) {
- markerBeanSet.put(marker.getId(), marker);
- setMapMarker(marker);
- }
- }
- }, throwable -> {
- Log.e(TAG, "Load markers error: " + throwable.getMessage());
- getMarkerData();
- }, () -> {
- // 褰揗aybe涓虹┖鏃惰皟鐢�
- getMarkerData();
- })
+ DaoSingleton.getAsynchInstance(this.getContext()).markerDao().getAll()
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(markers -> {
+ if (markers == null || markers.isEmpty()) {
+ getMarkerData();
+ } else {
+ for (MarkerBean marker : markers) {
+ markerBeanSet.put(marker.getId(), marker);
+ setMapMarker(marker);
+ }
+ }
+ }, throwable -> {
+ Log.e(TAG, "Load markers error: " + throwable.getMessage());
+ getMarkerData();
+ }, () -> {
+ // 褰揗aybe涓虹┖鏃惰皟鐢�
+ getMarkerData();
+ })
);
// 寮傛鍔犺浇鍒嗘按鎴挎暟鎹�
compositeDisposable.add(
- DaoSingleton.getAsynchInstance(this.getContext()).divideDao().getAll()
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(divides -> {
- if (divides == null || divides.isEmpty()) {
- getDivideList();
- } else {
- for (DivideBean divide : divides) {
- divideBeanMap.put(divide.getId(), divide);
- setMapDivide(divide);
- }
- }
- }, throwable -> {
- Log.e(TAG, "Load divides error: " + throwable.getMessage());
- getDivideList();
- }, () -> {
- // 褰揗aybe涓虹┖鏃惰皟鐢�
- getDivideList();
- })
+ DaoSingleton.getAsynchInstance(this.getContext()).divideDao().getAll()
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(divides -> {
+ if (divides == null || divides.isEmpty()) {
+ getDivideList();
+ } else {
+ for (DivideBean divide : divides) {
+ divideBeanMap.put(divide.getId(), divide);
+ setMapDivide(divide);
+ }
+ }
+ }, throwable -> {
+ Log.e(TAG, "Load divides error: " + throwable.getMessage());
+ getDivideList();
+ }, () -> {
+ // 褰揗aybe涓虹┖鏃惰皟鐢�
+ getDivideList();
+ })
);
}
@@ -370,19 +375,19 @@
// 浣跨敤 CompositeDisposable 绠$悊鏁版嵁搴撴彃鍏ユ搷浣�
compositeDisposable.add(
- DaoSingleton.getAsynchInstance(MapFragment.this.getContext()).markerDao().insertAll(markerBeans)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(
- () -> {
- // 鎻掑叆鎴愬姛
- Log.i("mWebView", "鏁版嵁鎻掑叆鎴愬姛");
- },
- throwable -> {
- // 鎻掑叆澶辫触
- Log.e("mWebView", "鏁版嵁鎻掑叆澶辫触: " + throwable.getMessage());
- }
- )
+ DaoSingleton.getAsynchInstance(MapFragment.this.getContext()).markerDao().insertAll(markerBeans)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ () -> {
+ // 鎻掑叆鎴愬姛
+ Log.i("mWebView", "鏁版嵁鎻掑叆鎴愬姛");
+ },
+ throwable -> {
+ // 鎻掑叆澶辫触
+ Log.e("mWebView", "鏁版嵁鎻掑叆澶辫触: " + throwable.getMessage());
+ }
+ )
);
}
@@ -432,8 +437,27 @@
Intent issue = new Intent(MapFragment.this.getActivity(), AddIssueActivity.class);
MapFragment.this.getActivity().startActivity(issue);
});
+ binding.expandButton.setLegendsArray(new Triple<>(
+ ContextCompat.getDrawable(requireContext(), R.drawable.marker_blue),
+ ContextCompat.getDrawable(requireContext(), R.drawable.marker_unselected),
+ "鍙栨按鍙�"
+ ),
+ new Triple<>(
+ ContextCompat.getDrawable(requireContext(), R.drawable.divide_home_blue),
+ ContextCompat.getDrawable(requireContext(), R.drawable.divide_home_unselected),
+ "鍒嗘按鎴�"
+ ));
+ binding.expandButton.setOnLegendItemClickListener((position, isSelected) -> {
+ switch (position) {
+ case 0:
+ showMarkers(isSelected);
+ break;
+ case 1:
+ showDivideMarkers(isSelected);
+ break;
-
+ }
+ });
}
/**
@@ -1010,22 +1034,22 @@
setMapDivide(divideBean);
divideBeans.add(divideBean);
}
-
+
// 浣跨敤 CompositeDisposable 绠$悊鏁版嵁搴撴彃鍏ユ搷浣�
compositeDisposable.add(
- DaoSingleton.getAsynchInstance(MapFragment.this.getContext()).divideDao().insertAll(divideBeans)
- .subscribeOn(Schedulers.io())
- .observeOn(AndroidSchedulers.mainThread())
- .subscribe(
- () -> {
- // 鎻掑叆鎴愬姛
- Log.i("mWebView", "鏁版嵁鎻掑叆鎴愬姛");
- },
- throwable -> {
- // 鎻掑叆澶辫触
- Log.e("mWebView", "鏁版嵁鎻掑叆澶辫触: " + throwable.getMessage());
- }
- )
+ DaoSingleton.getAsynchInstance(MapFragment.this.getContext()).divideDao().insertAll(divideBeans)
+ .subscribeOn(Schedulers.io())
+ .observeOn(AndroidSchedulers.mainThread())
+ .subscribe(
+ () -> {
+ // 鎻掑叆鎴愬姛
+ Log.i("mWebView", "鏁版嵁鎻掑叆鎴愬姛");
+ },
+ throwable -> {
+ // 鎻掑叆澶辫触
+ Log.e("mWebView", "鏁版嵁鎻掑叆澶辫触: " + throwable.getMessage());
+ }
+ )
);
}
} else {
@@ -1157,4 +1181,36 @@
mWebView.restoreState(savedInstanceState);
}
}
+
+ /**
+ * 鏄剧ず鎴栭殣钘忓湴鍥句笂鐨勫彇姘村彛
+ *
+ * @param isShow
+ */
+ private void showMarkers(boolean isShow) {
+ if (isShow) {
+ mWebView.evaluateJavascript("javascript:showAllWaterIntakes()", value -> {
+ });
+ } else {
+ mWebView.evaluateJavascript("javascript:hideAllWaterIntakes()", value -> {
+ });
+ }
+
+ }
+
+ /**
+ * 鏄剧ず鎴栭殣钘忓湴鍥句笂鐨勫垎姘存埧
+ *
+ * @param isShow
+ */
+ private void showDivideMarkers(boolean isShow) {
+ if (isShow) {
+ mWebView.evaluateJavascript("javascript:showAllDivides()", value -> {
+ });
+ } else {
+ mWebView.evaluateJavascript("javascript:hideAllDivides()", value -> {
+ });
+ }
+ }
+
}
diff --git a/app/src/main/java/com/dayu/pipirrapp/utils/DateUtils.java b/app/src/main/java/com/dayu/pipirrapp/utils/DateUtils.java
index 1d25d66..1cdc3c5 100644
--- a/app/src/main/java/com/dayu/pipirrapp/utils/DateUtils.java
+++ b/app/src/main/java/com/dayu/pipirrapp/utils/DateUtils.java
@@ -31,15 +31,25 @@
/**
* 杩斿洖缁熶竴鏍煎紡鐨勫綋鍓嶆椂闂存埅姝㈠埌鍒嗛挓
*
- * @return yyyy-MM-dd HH:mm:ss
+ * @return yyyy-MM-dd HH:mm
*/
public static String getNowDateToMMStr() {
// 褰撳墠鏃堕棿
Date date = new Date();
// 鍒涘缓 SimpleDateFormat 瀵硅薄锛岃缃棩鏈熸牸寮�
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault());
// 鏍煎紡鍖栧綋鍓嶆椂闂翠负瀛楃涓�
return sdf.format(date);
}
+ /**
+ * 灏嗘椂闂存埑杞崲涓烘寚瀹氭牸寮忕殑瀛楃涓�
+ * @param timestamp 鏃堕棿鎴�
+ * @return 鏍煎紡鍖栧悗鐨勬椂闂村瓧绗︿覆 (yyyy-MM-dd HH:mm)
+ */
+ public static String formatTimestamp(long timestamp) {
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm", Locale.getDefault());
+ return sdf.format(new Date(timestamp));
+ }
+
}
diff --git a/app/src/main/res/drawable/divide_home_blue.xml b/app/src/main/res/drawable/divide_home_blue.xml
new file mode 100644
index 0000000..30680be
--- /dev/null
+++ b/app/src/main/res/drawable/divide_home_blue.xml
@@ -0,0 +1,25 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="48"
+ android:viewportHeight="48">
+ <path
+ android:pathData="M9,18V42H39V18L24,6L9,18Z"
+ android:strokeLineJoin="round"
+ android:strokeWidth="4"
+ android:fillColor="#00000000"
+ android:strokeColor="#1890FF"
+ android:strokeLineCap="round"/>
+ <path
+ android:pathData="M19,29V42H29V29H19Z"
+ android:strokeLineJoin="round"
+ android:strokeWidth="4"
+ android:fillColor="#00000000"
+ android:strokeColor="#1890FF"/>
+ <path
+ android:pathData="M9,42H39"
+ android:strokeWidth="4"
+ android:fillColor="#00000000"
+ android:strokeColor="#1890FF"
+ android:strokeLineCap="round"/>
+</vector>
diff --git a/app/src/main/res/drawable/divide_home_unselected.xml b/app/src/main/res/drawable/divide_home_unselected.xml
new file mode 100644
index 0000000..a37f1fe
--- /dev/null
+++ b/app/src/main/res/drawable/divide_home_unselected.xml
@@ -0,0 +1,25 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="48"
+ android:viewportHeight="48">
+ <path
+ android:pathData="M9,18V42H39V18L24,6L9,18Z"
+ android:strokeLineJoin="round"
+ android:strokeWidth="4"
+ android:fillColor="#00000000"
+ android:strokeColor="#757575"
+ android:strokeLineCap="round"/>
+ <path
+ android:pathData="M19,29V42H29V29H19Z"
+ android:strokeLineJoin="round"
+ android:strokeWidth="4"
+ android:fillColor="#00000000"
+ android:strokeColor="#757575"/>
+ <path
+ android:pathData="M9,42H39"
+ android:strokeWidth="4"
+ android:fillColor="#00000000"
+ android:strokeColor="#757575"
+ android:strokeLineCap="round"/>
+</vector>
diff --git a/app/src/main/res/drawable/marker_blue.xml b/app/src/main/res/drawable/marker_blue.xml
new file mode 100644
index 0000000..e3e70bf
--- /dev/null
+++ b/app/src/main/res/drawable/marker_blue.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M12,2L12,2C8.13,2 5,5.13 5,9c0,1.74 0.5,3.37 1.41,4.84c0.95,1.54 2.2,2.86 3.16,4.4c0.47,0.75 0.81,1.45 1.17,2.26C11,21.05 11.21,22 12,22h0c0.79,0 1,-0.95 1.25,-1.5c0.37,-0.81 0.7,-1.51 1.17,-2.26c0.96,-1.53 2.21,-2.85 3.16,-4.4C18.5,12.37 19,10.74 19,9C19,5.13 15.87,2 12,2zM12,11.75c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5s2.5,1.12 2.5,2.5S13.38,11.75 12,11.75z"
+ android:fillColor="#1890FF"/>
+</vector>
diff --git a/app/src/main/res/drawable/marker_unselected.xml b/app/src/main/res/drawable/marker_unselected.xml
new file mode 100644
index 0000000..24a8afd
--- /dev/null
+++ b/app/src/main/res/drawable/marker_unselected.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:pathData="M12,2L12,2C8.13,2 5,5.13 5,9c0,1.74 0.5,3.37 1.41,4.84c0.95,1.54 2.2,2.86 3.16,4.4c0.47,0.75 0.81,1.45 1.17,2.26C11,21.05 11.21,22 12,22h0c0.79,0 1,-0.95 1.25,-1.5c0.37,-0.81 0.7,-1.51 1.17,-2.26c0.96,-1.53 2.21,-2.85 3.16,-4.4C18.5,12.37 19,10.74 19,9C19,5.13 15.87,2 12,2zM12,11.75c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5s2.5,1.12 2.5,2.5S13.38,11.75 12,11.75z"
+ android:fillColor="#757575"/>
+</vector>
diff --git a/app/src/main/res/layout/activity_order_deal.xml b/app/src/main/res/layout/activity_order_deal.xml
index 3bc03cb..8481bf9 100644
--- a/app/src/main/res/layout/activity_order_deal.xml
+++ b/app/src/main/res/layout/activity_order_deal.xml
@@ -62,7 +62,15 @@
android:text="鍙嶉鏃堕棿锛�"
android:textColor="@color/black"
android:textSize="@dimen/order_detail_button_size" />
-
+ <TextView
+ android:id="@+id/timeData"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
+ android:layout_toEndOf="@+id/timeTV"
+ android:layout_marginLeft="10dp"
+ android:textColor="@color/black"
+ android:textSize="@dimen/order_detail_button_size" />
<ImageView
android:layout_width="25dp"
android:layout_height="25dp"
diff --git a/app/src/main/res/layout/fragment_map.xml b/app/src/main/res/layout/fragment_map.xml
index e0de4e9..9a71ebc 100644
--- a/app/src/main/res/layout/fragment_map.xml
+++ b/app/src/main/res/layout/fragment_map.xml
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- xmlns:app="http://schemas.android.com/apk/res-auto">
+ android:layout_height="match_parent">
<!-- <com.github.lzyzsd.jsbridge.BridgeWebView-->
<!-- android:id="@+id/webView"-->
@@ -110,17 +110,18 @@
android:id="@+id/expandButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:padding="10dp"
- android:background="@drawable/ic_green_bg"
android:layout_alignParentRight="true"
android:layout_marginTop="180dp"
- android:textSize="18sp"
android:layout_marginRight="15dp"
+ android:background="@drawable/ic_green_bg"
+ android:padding="10dp"
android:textColor="@color/white"
+ android:textSize="18sp"
+ app:animDuration="300"
+ app:collapsedText="渚�"
app:letterSpacing="10dp"
- app:expandedText="鐐瑰嚮灞曞紑"
- app:collapsedText="鐐�"
- app:animDuration="300" />
+ app:expandedTextSize="12sp"/>
+
<RelativeLayout
android:id="@+id/pointRL"
android:layout_width="match_parent"
diff --git a/expand_button/src/main/java/com/example/expand_button/ExpandButton.kt b/expand_button/src/main/java/com/example/expand_button/ExpandButton.kt
index c024329..1ac7b29 100644
--- a/expand_button/src/main/java/com/example/expand_button/ExpandButton.kt
+++ b/expand_button/src/main/java/com/example/expand_button/ExpandButton.kt
@@ -25,10 +25,23 @@
defStyleAttr: Int = 0
) : AppCompatTextView(context, attrs, defStyleAttr) {
+ // 淇敼灞炴��
+ private data class LegendItem(
+ val selectedIcon: Drawable,
+ val unselectedIcon: Drawable,
+ val description: String,
+ var isSelected: Boolean = true
+ )
+
+ private var legendItems: List<LegendItem> = listOf()
+ private var itemSpacing: Float = context.resources.displayMetrics.density * 16 // 鍥句緥椤逛箣闂寸殑姘村钩闂磋窛
+ private var iconSize: Int = (24 * context.resources.displayMetrics.density).toInt() // 鍥炬爣澶у皬
+ private var iconTextSpacing: Float = context.resources.displayMetrics.density * 4 // 鍥炬爣鍜屾枃瀛椾箣闂寸殑鍨傜洿闂磋窛
+
// 灞曞紑鏃舵樉绀虹殑瀹屾暣鏂囧瓧
- private var expandedText: String = ""
+ private var expandedText: String = "鏍囨敞鐐�: 褰撳墠浣嶇疆\n鍖哄煙: 閰嶉�佽寖鍥�"
// 鏀惰捣鏃舵樉绀虹殑鍗曚釜瀛楃
- private var collapsedText: String = ""
+ private var collapsedText: String = "鍥句緥"
// 褰撳墠鏄惁澶勪簬灞曞紑鐘舵��
private var isExpanded: Boolean = false
// 鍔ㄧ敾鎸佺画鏃堕棿锛岄粯璁�300姣
@@ -50,7 +63,33 @@
// 涓夎褰㈠浘鏍囦笌鏂囧瓧鐨勯棿璺濓紝榛樿涓�8dp
private var triangleMargin: Float = 3 * context.resources.displayMetrics.density
+ // 娣诲姞鏂板睘鎬�
+ private var textLines: List<String> = listOf()
+
+ // 娣诲姞鐐瑰嚮鍥炶皟鎺ュ彛
+ interface OnLegendItemClickListener {
+ fun onLegendItemClick(position: Int, isSelected: Boolean)
+ }
+
+ private var legendItemClickListener: OnLegendItemClickListener? = null
+
+ // 淇敼鍥句緥椤圭殑鎬婚珮搴﹁绠�
+ private val legendItemHeight: Int
+ get() = iconSize + iconTextSpacing.toInt() + paint.textSize.toInt() + paint.descent().toInt() - paint.ascent().toInt()
+
+ // 娣诲姞灞曞紑鍚庣殑瀛椾綋澶у皬灞炴��
+ private var expandedTextSize: Float = textSize
+
+ // 娣诲姞涓�涓彉閲忎繚瀛橀粯璁ゅ瓧浣撳ぇ灏�
+ private var defaultTextSize: Float = 0f
+
+ // 娣诲姞涓�涓睘鎬у畾涔変笁瑙掑舰鍥炬爣鐨勭偣鍑诲尯鍩熸墿灞曡寖鍥�
+ private val triangleClickPadding: Float = 15f * context.resources.displayMetrics.density // 20dp
+
init {
+ // 淇濆瓨 XML 涓缃殑榛樿瀛椾綋澶у皬
+ defaultTextSize = textSize
+
// 璇诲彇鑷畾涔夊睘鎬�
context.theme.obtainStyledAttributes(
attrs,
@@ -60,10 +99,14 @@
).apply {
try {
customLetterSpacing = getDimension(R.styleable.ExpandButton_letterSpacing, customLetterSpacing)
- expandedText = getString(R.styleable.ExpandButton_expandedText) ?: ""
- collapsedText = getString(R.styleable.ExpandButton_collapsedText) ?: ""
+ expandedText = getString(R.styleable.ExpandButton_expandedText) ?: "鏍囨敞鐐�: 褰撳墠浣嶇疆\n鍖哄煙: 閰嶉�佽寖鍥�"
+ collapsedText = getString(R.styleable.ExpandButton_collapsedText) ?: "鍥句緥"
animationDuration = getInteger(R.styleable.ExpandButton_animDuration, 300).toLong()
triangleMargin = getDimension(R.styleable.ExpandButton_triangleMargin, triangleMargin)
+ itemSpacing = getDimension(R.styleable.ExpandButton_itemSpacing, itemSpacing)
+ iconSize = getDimension(R.styleable.ExpandButton_iconSize, iconSize.toFloat()).toInt()
+ iconTextSpacing = getDimension(R.styleable.ExpandButton_iconTextSpacing, iconTextSpacing)
+ expandedTextSize = getDimension(R.styleable.ExpandButton_expandedTextSize, defaultTextSize)
} finally {
recycle()
}
@@ -80,26 +123,11 @@
}
}
- // 璁剧疆鏂囨湰鍙偣鍑伙紝浠呭湪鏀惰捣鐘舵�佹椂鍝嶅簲鐐瑰嚮灞曞紑
- setOnClickListener {
- if (!isExpanded) {
- toggleExpand()
- }
- }
-
- // 娣诲姞瑙︽懜浜嬩欢澶勭悊
- setOnTouchListener { _, event ->
- when (event.action) {
- MotionEvent.ACTION_DOWN -> {
- // 妫�鏌ョ偣鍑绘槸鍚﹀湪涓夎褰㈠浘鏍囧尯鍩熷唴
- if (isClickOnTriangle(event.x)) {
- toggleExpand()
- return@setOnTouchListener true
- }
- }
- }
- false
- }
+ // 淇敼瑙︽懜浜嬩欢澶勭悊
+ setOnTouchListener(null) // 绉婚櫎鍘熸湁鐨勮Е鎽哥洃鍚櫒
+
+ // 绉婚櫎鍘熸湁鐨勭偣鍑荤洃鍚櫒
+ setOnClickListener(null)
// 璁剧疆宸﹁竟璺濓紝涓哄浘鏍囩暀鍑虹┖闂�
compoundDrawablePadding = triangleMargin.toInt()
@@ -111,23 +139,107 @@
)
// 璁剧疆鍗曡鏄剧ず锛岄槻姝㈤珮搴﹀彉鍖�
- maxLines = 1
- isSingleLine = true
+ maxLines = if (isExpanded) Int.MAX_VALUE else 1
+ isSingleLine = !isExpanded
// 璁剧疆鏂囧瓧鍨傜洿灞呬腑
gravity = Gravity.CENTER_VERTICAL
+
+ // 璁剧疆榛樿鐨勫唴杈硅窛
+ val defaultPadding = (8 * context.resources.displayMetrics.density).toInt()
+ setPadding(
+ (16 * context.resources.displayMetrics.density + triangleMargin).toInt(), // 宸﹁竟璺濆鍔狅紝涓哄浘鏍囩暀绌洪棿
+ defaultPadding, // 涓婅竟璺�
+ defaultPadding, // 鍙宠竟璺�
+ defaultPadding // 涓嬭竟璺�
+ )
+ }
+
+ override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec)
+
+ if (isExpanded) {
+ // 灞曞紑鐘舵�佷笅鐨勯珮搴﹁绠�
+ val desiredHeight = legendItemHeight + paddingTop + paddingBottom
+ setMeasuredDimension(measuredWidth, desiredHeight)
+ }
}
override fun onDraw(canvas: Canvas) {
- // 淇濆瓨鐢诲竷鐘舵��
+ // 缁樺埗灞曞紑/鏀惰捣鍥炬爣
+ drawTriangle(canvas)
+
+ if (!isExpanded) {
+ // 鏀惰捣鐘舵�佷娇鐢ㄩ粯璁ゅ瓧浣撳ぇ灏�
+ paint.textSize = defaultTextSize
+ super.onDraw(canvas)
+ return
+ }
+
+ // 灞曞紑鐘舵�佷娇鐢ㄥ睍寮�鍚庣殑瀛椾綋澶у皬
+ paint.textSize = expandedTextSize
+
+ // 璁$畻鎵�鏈夊浘渚嬮」涓渶瀹界殑瀹藉害
+ val maxWidth = legendItems.maxOf { item ->
+ maxOf(paint.measureText(item.description), iconSize.toFloat())
+ }
+
+ // 璁$畻鎬诲搴︼紙娣诲姞棣栧熬鐨勮竟璺濓級
+ val totalWidth = legendItems.size * maxWidth +
+ (legendItems.size + 1) * itemSpacing // 淇敼杩欓噷锛屾坊鍔犱竴涓澶栫殑闂磋窛
+
+ // 璁$畻璧峰x鍧愭爣锛屼娇鏁翠綋姘村钩灞呬腑
+ var x = (width - totalWidth) / 2 + itemSpacing // 娣诲姞璧峰杈硅窛
+
+ // 璁$畻鍨傜洿灞呬腑鐨剏鍧愭爣锛岃�冭檻涓婁笅杈硅窛
+ val centerY = height / 2f
+
+ legendItems.forEachIndexed { index, item ->
+ // 璁$畻褰撳墠鍥句緥椤圭殑璧峰浣嶇疆锛堢Щ闄ndex > 0鐨勫垽鏂級
+ val itemStartX = x
+
+ // 璁$畻鍥炬爣鐨勬按骞充綅缃紙灞呬腑浜庡浘渚嬮」锛�
+ val iconLeft = itemStartX + (maxWidth - iconSize) / 2
+
+ // 璁$畻鏂囧瓧鐨勪綅缃�
+ val textWidth = paint.measureText(item.description)
+ val textX = itemStartX + (maxWidth - textWidth) / 2
+
+ // 缁樺埗鍥炬爣锛屾牴鎹�変腑鐘舵�侀�夋嫨涓嶅悓鐨勫浘鏍�
+ val iconTop = paddingTop + (height - legendItemHeight) / 2
+ val currentIcon = if (item.isSelected) item.selectedIcon else item.unselectedIcon
+ currentIcon.setBounds(
+ iconLeft.toInt(),
+ iconTop.toInt(),
+ (iconLeft + iconSize).toInt(),
+ (iconTop + iconSize).toInt()
+ )
+ currentIcon.draw(canvas)
+
+ // 缁樺埗鏂囧瓧锛屾牴鎹�変腑鐘舵�佷娇鐢ㄤ笉鍚岀殑棰滆壊
+ paint.color = if (item.isSelected)
+ currentTextColor
+ else
+ 0xFF999999.toInt() // 鐏拌壊
+ val textY = iconTop + iconSize + iconTextSpacing - paint.ascent()
+ canvas.drawText(item.description, textX, textY, paint)
+
+ // 鏇存柊涓嬩竴涓浘渚嬮」鐨勮捣濮嬩綅缃�
+ x = itemStartX + maxWidth + itemSpacing
+ }
+
+ // 鎭㈠鐢荤瑪棰滆壊
+ paint.color = currentTextColor
+ }
+
+ // 灏嗗師鏉ョ殑onDraw涓殑涓夎褰㈢粯鍒堕�昏緫鎻愬彇鍑烘潵
+ private fun drawTriangle(canvas: Canvas) {
canvas.save()
- // 璁$畻鍥炬爣浣嶇疆
val iconSize = triangleDrawable.intrinsicWidth
val iconLeft = paddingLeft - iconSize - compoundDrawablePadding
val iconTop = (height - iconSize) / 2
- // 璁剧疆鍥炬爣杈圭晫
triangleDrawable.setBounds(
iconLeft,
iconTop,
@@ -135,20 +247,15 @@
iconTop + iconSize
)
- // 鏃嬭浆鐢诲竷
canvas.rotate(
triangleRotation,
(iconLeft + iconSize / 2).toFloat(),
(iconTop + iconSize / 2).toFloat()
)
- // 缁樺埗鍥炬爣
triangleDrawable.draw(canvas)
- // 鎭㈠鐢诲竷鐘舵��
canvas.restore()
-
- super.onDraw(canvas)
}
/**
@@ -193,13 +300,18 @@
/**
* 鍒囨崲灞曞紑/鏀惰捣鐘舵��
- * 浣跨敤ValueAnimator瀹炵幇瀹藉害鍔ㄧ敾鍜屽浘鏍囨棆杞�
*/
private fun toggleExpand() {
isExpanded = !isExpanded
// 璁$畻鏀惰捣鍜屽睍寮�鐘舵�佺殑瀹藉害
- val collapsedWidth = paint.measureText(collapsedText).toInt() + paddingLeft + paddingRight
+ val collapsedWidth = run {
+ paint.textSize = defaultTextSize
+ val width = paint.measureText(collapsedText).toInt() + paddingLeft + paddingRight
+ paint.textSize = if (isExpanded) expandedTextSize else defaultTextSize
+ width
+ }
+
val expandedWidth = calculateExpandedWidth()
// 鍒涘缓瀹藉害鍔ㄧ敾
@@ -225,31 +337,46 @@
duration = animationDuration
addUpdateListener { animator ->
triangleRotation = animator.animatedValue as Float
- invalidate() // 閲嶇粯浠ユ洿鏂板浘鏍囨棆杞�
+ invalidate()
}
start()
}
- // 鏇存柊鏂囨湰
+ // 鏇存柊鏂囨湰鍜屽瓧浣撳ぇ灏�
if (isExpanded) {
- setExpandedClickableText()
+ paint.textSize = expandedTextSize
} else {
text = collapsedText
+ paint.textSize = defaultTextSize
+ setTextSize(android.util.TypedValue.COMPLEX_UNIT_PX, defaultTextSize)
}
+
+ invalidate()
}
/**
* 璁$畻灞曞紑鍚庣殑鎬诲搴�
*/
private fun calculateExpandedWidth(): Int {
- val spaceWidth = paint.measureText(" ") * (customLetterSpacing / 10)
- // 璁$畻鎵�鏈夊瓧绗︾殑鎬诲搴�
- val textWidth = expandedText.fold(0f) { acc, char ->
- acc + paint.measureText(char.toString())
+ // 涓存椂淇濆瓨褰撳墠瀛椾綋澶у皬
+ val currentTextSize = paint.textSize
+ // 璁剧疆涓哄睍寮�鐘舵�佺殑瀛椾綋澶у皬
+ paint.textSize = expandedTextSize
+
+ try {
+ // 璁$畻鎵�鏈夊浘渚嬮」涓渶瀹界殑瀹藉害
+ val maxWidth = legendItems.maxOf { item ->
+ maxOf(paint.measureText(item.description), iconSize.toFloat())
+ }
+
+ // 璁$畻鎬诲搴� = 鎵�鏈夊浘渚嬮」鐨勫搴� + 鎵�鏈夐棿璺濓紙鍖呮嫭棣栧熬锛� + 宸﹀彸鍐呰竟璺�
+ return (legendItems.size * maxWidth +
+ (legendItems.size + 1) * itemSpacing +
+ paddingLeft + paddingRight).toInt()
+ } finally {
+ // 鎭㈠鍘熸潵鐨勫瓧浣撳ぇ灏�
+ paint.textSize = currentTextSize
}
- // 璁$畻闂磋窛鐨勬�诲搴︼紙瀛楃鏁伴噺鍑�1涓棿璺濓級
- val spacesWidth = spaceWidth * (expandedText.length - 1)
- return (textWidth + spacesWidth).toInt() + paddingLeft + paddingRight
}
/**
@@ -257,39 +384,76 @@
*/
private fun setExpandedClickableText() {
val builder = SpannableStringBuilder()
- expandedText.forEachIndexed { index, char ->
- // 娣诲姞瀛楃
- builder.append(char)
+
+ // 璁$畻鎵�鏈夊浘渚嬮」涓渶瀹界殑瀹藉害
+ val maxWidth = legendItems.maxOf { item ->
+ maxOf(paint.measureText(item.description), iconSize.toFloat())
+ }
+
+ // 璁$畻鎬诲搴�
+ val totalWidth = legendItems.size * maxWidth +
+ (legendItems.size - 1) * itemSpacing
+
+ // 璁$畻鏁翠綋姘村钩灞呬腑闇�瑕佺殑璧峰绌烘牸
+ val startPadding = ((width - totalWidth) / 2 / paint.measureText(" ")).toInt()
+ if (startPadding > 0) {
+ builder.append(" ".repeat(startPadding))
+ }
+
+ // 娣诲姞鍨傜洿绌洪棿锛屼负鍥炬爣棰勭暀浣嶇疆
+ val verticalSpaces = ((iconSize + iconTextSpacing) / paint.textSize).toInt()
+ builder.append("\n".repeat(verticalSpaces))
+
+ legendItems.forEachIndexed { index, item ->
+ if (index > 0) {
+ // 鍦ㄥ浘渚嬮」涔嬮棿娣诲姞姘村钩闂磋窛
+ builder.append(" ".repeat((itemSpacing / paint.measureText(" ")).toInt()))
+ }
- // 涓哄瓧绗﹁缃偣鍑讳簨浠�
+ // 璁$畻姘村钩灞呬腑鎵�闇�鐨勭┖鏍兼暟
+ val textWidth = paint.measureText(item.description)
+ val paddingSpaces = ((maxWidth - textWidth) / 2 / paint.measureText(" ")).toInt()
+
+ // 娣诲姞宸︿晶绌烘牸瀹炵幇灞呬腑
+ if (paddingSpaces > 0) {
+ builder.append(" ".repeat(paddingSpaces))
+ }
+
+ // 娣诲姞鎻忚堪鏂囨湰
+ val startPosition = builder.length
+ builder.append(item.description)
+
+ // 娣诲姞鍙充晶绌烘牸浠ョ‘淇濆搴︿竴鑷�
+ val remainingSpaces = ((maxWidth - textWidth) / paint.measureText(" ")).toInt() - paddingSpaces
+ if (remainingSpaces > 0) {
+ builder.append(" ".repeat(remainingSpaces))
+ }
+
+ // 涓烘枃瀛楄缃偣鍑讳簨浠�
val clickableSpan = object : ClickableSpan() {
override fun onClick(view: View) {
- onCharClickListener?.invoke(char, index)
+ onCharClickListener?.invoke(item.description[0], index)
}
override fun updateDrawState(ds: android.text.TextPaint) {
super.updateDrawState(ds)
- // 绉婚櫎涓嬪垝绾�
ds.isUnderlineText = false
- // 淇濇寔鍘熷鏂囧瓧棰滆壊
ds.color = currentTextColor
}
}
+
builder.setSpan(
clickableSpan,
- builder.length - 1,
- builder.length,
+ startPosition,
+ startPosition + item.description.length,
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
)
-
- // 鍙湪闈炴渶鍚庝竴涓瓧绗﹀悗娣诲姞绌烘牸浣滀负闂磋窛
- if (index < expandedText.length - 1) {
- builder.append(" ".repeat((customLetterSpacing / 10).toInt()))
- }
}
+ // 璁剧疆鏂囨湰瀵归綈鏂瑰紡涓哄眳涓�
+ gravity = Gravity.CENTER
+
text = builder
- // 鍚敤LinkMovementMethod浠ュ搷搴擟lickableSpan鐨勭偣鍑讳簨浠�
movementMethod = android.text.method.LinkMovementMethod.getInstance()
}
@@ -299,7 +463,10 @@
private fun isClickOnTriangle(x: Float): Boolean {
val iconSize = triangleDrawable.intrinsicWidth
val iconLeft = paddingLeft - iconSize - compoundDrawablePadding
- return x <= paddingLeft && x >= iconLeft
+
+ // 鎵╁ぇ鐐瑰嚮鍖哄煙锛氬乏鍙冲悇澧炲姞 triangleClickPadding
+ return x <= (paddingLeft + triangleClickPadding) &&
+ x >= (iconLeft - triangleClickPadding)
}
/**
@@ -316,4 +483,129 @@
paddingBottom
)
}
+
+ /**
+ * 璁剧疆鍥句緥鍐呭
+ */
+ @JvmName("setLegendsList")
+ fun setLegends(items: List<Triple<Drawable, Drawable, String>>) {
+ legendItems = items.map { (selectedIcon, unselectedIcon, description) ->
+ selectedIcon.setBounds(0, 0, iconSize, iconSize)
+ unselectedIcon.setBounds(0, 0, iconSize, iconSize)
+ LegendItem(selectedIcon, unselectedIcon, description)
+ }
+
+ if (!isExpanded) {
+ text = collapsedText
+ } else {
+ invalidate()
+ }
+ requestLayout()
+ }
+
+ // 娣诲姞涓�涓� Java 鍙嬪ソ鐨勬柟娉�
+ @JvmName("setLegendsArray")
+ fun setLegends(vararg items: Triple<Drawable, Drawable, String>) {
+ setLegends(items.toList())
+ }
+
+ /**
+ * 娣诲姞璁剧疆鐩戝惉鍣ㄧ殑鏂规硶
+ */
+ fun setOnLegendItemClickListener(listener: OnLegendItemClickListener) {
+ legendItemClickListener = listener
+ }
+
+ /**
+ * 澶勭悊瑙︽懜浜嬩欢
+ */
+ override fun onTouchEvent(event: MotionEvent): Boolean {
+ when (event.action) {
+ MotionEvent.ACTION_DOWN -> {
+ // 妫�鏌ョ偣鍑绘槸鍚﹀湪涓夎褰㈠浘鏍囧尯鍩熷唴
+ if (isClickOnTriangle(event.x)) {
+ toggleExpand()
+ return true
+ }
+
+ // 濡傛灉鏄睍寮�鐘舵�侊紝妫�鏌ユ槸鍚︾偣鍑讳簡鍥句緥椤�
+ if (isExpanded) {
+ val clickedIndex = getClickedItemIndex(event.x, event.y)
+ if (clickedIndex != -1) {
+ toggleItemSelection(clickedIndex)
+ return true
+ }
+ } else if (!isExpanded && event.x > paddingLeft) {
+ // 鍦ㄦ敹璧风姸鎬佷笅锛岀偣鍑婚潪涓夎褰㈠尯鍩熶篃灞曞紑
+ toggleExpand()
+ return true
+ }
+ }
+ }
+ return super.onTouchEvent(event)
+ }
+
+ /**
+ * 鑾峰彇鐐瑰嚮浣嶇疆瀵瑰簲鐨勫浘渚嬮」绱㈠紩
+ */
+ private fun getClickedItemIndex(x: Float, y: Float): Int {
+ if (!isExpanded) return -1
+
+ val maxWidth = legendItems.maxOf { item ->
+ maxOf(paint.measureText(item.description), iconSize.toFloat())
+ }
+
+ val totalWidth = legendItems.size * maxWidth +
+ (legendItems.size - 1) * itemSpacing
+
+ val startX = (width - totalWidth) / 2
+ val iconTop = paddingTop + (height - legendItemHeight) / 2
+ val iconBottom = iconTop + legendItemHeight
+
+ // 妫�鏌ュ瀭鐩存柟鍚戞槸鍚﹀湪鍥句緥椤硅寖鍥村唴
+ if (y < iconTop || y > iconBottom) return -1
+
+ // 妫�鏌ユ按骞虫柟鍚戠偣鍑荤殑鏄摢涓浘渚嬮」
+ legendItems.forEachIndexed { index, _ ->
+ val itemStartX = startX + index * (maxWidth + itemSpacing)
+ val itemEndX = itemStartX + maxWidth
+ if (x >= itemStartX && x <= itemEndX) {
+ return index
+ }
+ }
+ return -1
+ }
+
+ /**
+ * 鍒囨崲鍥句緥椤圭殑閫変腑鐘舵��
+ */
+ private fun toggleItemSelection(index: Int) {
+ if (index < 0 || index >= legendItems.size) return
+
+ legendItems[index].isSelected = !legendItems[index].isSelected
+ legendItemClickListener?.onLegendItemClick(
+ index,
+ legendItems[index].isSelected
+ )
+ invalidate()
+ }
+
+ /**
+ * 璁剧疆灞曞紑鍚庣殑瀛椾綋澶у皬
+ * @param size 瀛椾綋澶у皬锛堝儚绱狅級
+ */
+ fun setExpandedTextSize(size: Float) {
+ this.expandedTextSize = size
+ if (isExpanded) {
+ invalidate()
+ }
+ }
+
+ /**
+ * 璁剧疆灞曞紑鍚庣殑瀛椾綋澶у皬锛圫P锛�
+ * @param sp 瀛椾綋澶у皬锛圫P锛�
+ */
+ fun setExpandedTextSizeSp(sp: Float) {
+ setExpandedTextSize(sp * context.resources.displayMetrics.scaledDensity)
+ }
}
\ No newline at end of file
diff --git a/expand_button/src/main/res/values/attrs.xml b/expand_button/src/main/res/values/attrs.xml
index 1d34c70..aca0c25 100644
--- a/expand_button/src/main/res/values/attrs.xml
+++ b/expand_button/src/main/res/values/attrs.xml
@@ -11,5 +11,11 @@
<attr name="animDuration" format="integer"/>
<!-- 涓夎褰㈠浘鏍囦笌鏂囧瓧鐨勯棿璺� -->
<attr name="triangleMargin" format="dimension"/>
+ <!-- 鏂板灞炴�� -->
+ <attr name="itemSpacing" format="dimension"/>
+ <attr name="iconSize" format="dimension"/>
+ <attr name="iconTextSpacing" format="dimension"/>
+ <!-- 鏂板灞曞紑鍚庣殑瀛椾綋澶у皬灞炴�� -->
+ <attr name="expandedTextSize" format="dimension"/>
</declare-styleable>
</resources>
\ No newline at end of file
--
Gitblit v1.8.0