首页界面优化,地图模块优化,部分下载地图瓦片功能代码
| | |
| | | viewBinding { |
| | | enabled = true; |
| | | } |
| | | packagingOptions { |
| | | exclude 'META-INF/DEPENDENCIES' |
| | | // 如果你还遇到其他重复的META-INF文件,也可以添加类似的排除规则 |
| | | exclude 'META-INF/LICENSE' |
| | | exclude 'META-INF/LICENSE.txt' |
| | | exclude 'META-INF/NOTICE' |
| | | exclude 'META-INF/NOTICE.txt' |
| | | // RocketMQ特有的排除项(如果需要) |
| | | exclude 'META-INF/INDEX.LIST' |
| | | exclude 'META-INF/spring.factories' |
| | | exclude 'META-INF/spring.handlers' |
| | | } |
| | | |
| | | } |
| | | |
| | |
| | | |
| | | // //推送相关 |
| | | // // 此处以JPush 5.0.0 版本为例,5.0.0 版本开始可以自动拉取 JCore 包,无需另外配置 |
| | | implementation 'cn.jiguang.sdk:jpush:5.2.2' |
| | | // implementation 'cn.jiguang.sdk:jpush:5.2.2' |
| | | // //若不集成厂商通道,可直接跳过以下依赖 |
| | | // // 极光厂商插件版本与接入 JPush 版本保持一致,下同 |
| | | // // 接入华为厂商 |
| | | implementation 'com.huawei.hms:push:6.5.0.300' |
| | | implementation 'cn.jiguang.sdk.plugin:huawei:5.2.2' |
| | | // implementation 'com.huawei.hms:push:6.5.0.300' |
| | | // implementation 'cn.jiguang.sdk.plugin:huawei:5.2.2' |
| | | // // 接入 FCM 厂商 |
| | | // implementation 'com.google.firebase:firebase-messaging:23.0.5' |
| | | // implementation 'cn.jiguang.sdk.plugin:fcm:5.2.2' |
| | | // // 接入魅族厂商 |
| | | implementation 'cn.jiguang.sdk.plugin:meizu:5.2.2' |
| | | // implementation 'cn.jiguang.sdk.plugin:meizu:5.2.2' |
| | | // // 接入 VIVO 厂商 |
| | | implementation 'cn.jiguang.sdk.plugin:vivo:5.2.2' |
| | | // implementation 'cn.jiguang.sdk.plugin:vivo:5.2.2' |
| | | // // 接入小米厂商 |
| | | implementation 'cn.jiguang.sdk.plugin:xiaomi:5.2.2' |
| | | // implementation 'cn.jiguang.sdk.plugin:xiaomi:5.2.2' |
| | | // // 接入 OPPO 厂商 |
| | | // implementation 'cn.jiguang.sdk.plugin:oppo:5.2.2' |
| | | // // JPush Android SDK v4.6.0 开始,需要单独引入 oppo 厂商 aar ,请下载官网 SDK 包并把 jpush-android-xxx-release/third-push/oppo/libs 下的 aar 文件单独拷贝一份到应用 module/libs 下 |
| | | // implementation(name: 'com.heytap.msp-push-3.1.0', ext: 'aar') |
| | | // //以下为 OPPO 3.1.0 aar需要依赖 |
| | | implementation 'com.google.code.gson:gson:2.6.2' |
| | | implementation 'commons-codec:commons-codec:1.6' |
| | | implementation 'androidx.annotation:annotation:1.1.0' |
| | | // implementation 'com.google.code.gson:gson:2.6.2' |
| | | // implementation 'commons-codec:commons-codec:1.6' |
| | | // implementation 'androidx.annotation:annotation:1.1.0' |
| | | // // 接入荣耀厂商 |
| | | implementation 'cn.jiguang.sdk.plugin:honor:5.2.2' |
| | | // implementation 'cn.jiguang.sdk.plugin:honor:5.2.2' |
| | | |
| | | // apply plugin: 'com.google.gms.google-services' |
| | | // apply plugin: 'com.huawei.agconnect' |
| | |
| | | |
| | | //广播通信 |
| | | implementation 'io.github.jeremyliao:live-event-bus-x:1.8.0' |
| | | |
| | | //阿里的RocketMQ |
| | | implementation 'org.apache.rocketmq:rocketmq-client:4.9.4' |
| | | } |
| | |
| | | |
| | | |
| | | <!--百度定位--> |
| | | <meta-data |
| | | android:name="com.baidu.lbsapi.API_KEY" |
| | | android:value="Ky5wvrB9A9Rztsh3rQO8v8oNRgQM27NV"></meta-data> |
| | | <service |
| | | android:name="com.baidu.location.f" |
| | | android:enabled="true" |
| | | android:process=":remote"></service> |
| | | <!-- <meta-data--> |
| | | <!-- android:name="com.baidu.lbsapi.API_KEY"--> |
| | | <!-- android:value="Ky5wvrB9A9Rztsh3rQO8v8oNRgQM27NV"></meta-data>--> |
| | | <!-- <service--> |
| | | <!-- android:name="com.baidu.location.f"--> |
| | | <!-- android:enabled="true"--> |
| | | <!-- android:process=":remote"></service>--> |
| | | |
| | | </application> |
| | | |
New file |
| | |
| | | <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><rect fill="none" height="24" width="24"/><path d="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.26 C11,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.4 C18.5,12.37,19,10.74,19,9C19,5.13,15.87,2,12,2z M12,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.5 S13.38,11.75,12,11.75z"/></svg> |
New file |
| | |
| | | <svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24px" viewBox="0 0 24 24" width="24px" fill="#D81E06"><rect fill="none" height="24" width="24"/><path d="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.26 C11,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.4 C18.5,12.37,19,10.74,19,9C19,5.13,15.87,2,12,2z M12,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.5 S13.38,11.75,12,11.75z"/></svg> |
New file |
| | |
| | | <!DOCTYPE html> |
| | | <html lang="en"> |
| | | |
| | | <head> |
| | | <meta charset="UTF-8"> |
| | | <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| | | <title>天地图</title> |
| | | <style> |
| | | /* 确保 body 和 html 充满整个视口 */ |
| | | html, body { |
| | | margin: 0; |
| | | padding: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | overflow: hidden; /* 防止滚动条出现 */ |
| | | } |
| | | /* 确保地图容器充满整个视口 */ |
| | | #mapDiv { |
| | | width: 100%; |
| | | height: 100%; |
| | | position: absolute; /* 保证地图全屏 */ |
| | | top: 0; |
| | | left: 0; |
| | | } |
| | | </style> |
| | | <script src="http://api.tianditu.gov.cn/api?v=4.0&tk=d8beed89b43160a9a185e5aff431f85d" |
| | | type="text/javascript"></script> |
| | | </head> |
| | | |
| | | <body> |
| | | <div id="mapDiv"></div> |
| | | <script src="js/map.js"></script> |
| | | </body> |
| | | |
| | | </html> |
New file |
| | |
| | | (function () { |
| | | // 图片路径 |
| | | const locationIMGPath = 'img/location.png'; |
| | | const markerBalckPath = 'img/marker_black.svg'; |
| | | const markerRedPath = 'img/marker_red.svg'; |
| | | |
| | | let map; |
| | | let lastMarker = null; |
| | | let lastClickedMarker = null; |
| | | let isShowWaterIntakeDetail = false; |
| | | let zoom=12; |
| | | |
| | | |
| | | document.addEventListener('DOMContentLoaded', function () { |
| | | |
| | | initMap(); |
| | | // buttonOverLay(); |
| | | mountMethodToWindow(); |
| | | |
| | | }); |
| | | window.onload = function() { |
| | | //加载坐标点 |
| | | window.Android.loadMarker(); |
| | | }; |
| | | // 初始化地图 |
| | | function initMap() { |
| | | var imageURL = "http://t0.tianditu.gov.cn/img_w/wmts?" + |
| | | "SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles" + |
| | | "&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=d8beed89b43160a9a185e5aff431f85d"; |
| | | //创建自定义图层对象 |
| | | var lay = new T.TileLayer(imageURL, { minZoom: 1, maxZoom: 18 }); |
| | | var config = { layers: [lay] }; |
| | | map = new T.Map("mapDiv", config); |
| | | map.centerAndZoom(new T.LngLat(116.40769, 39.89945), zoom); //地图的初始化中心点,此为北京的经纬度 |
| | | map.addEventListener("click", closeWaterIntakeDetail); |
| | | } |
| | | |
| | | // 地图点击后获取经纬度 |
| | | function getLngLat(lnglat) { |
| | | console.log(lnglat.lng.toFixed(6) + "," + lnglat.lat.toFixed(6)); |
| | | addClickOverLay(lnglat); |
| | | } |
| | | |
| | | // 点击后添加坐标点 |
| | | function addClickOverLay(lnglat) { |
| | | removeMyOverLay(); |
| | | |
| | | let marker = new T.Marker( |
| | | new T.LngLat(lnglat.lng, lnglat.lat) // 创建标注 |
| | | ); |
| | | map.addOverLay(marker); // 将标注添加到地图中 |
| | | |
| | | // 设置弹出的窗口样式 |
| | | let infoWin = new T.InfoWindow(); |
| | | let sContent = |
| | | "<div style='margin:0px;'>" + |
| | | "<div style='margin:10px 10px; '>" + |
| | | "<div >电话 : (010)88187700 <br>地址:北京市顺义区机场东路国门商务区地理信息产业园2号楼天地图大厦" + |
| | | "</div>" + |
| | | "<input width: 80px;height: 24px; text-align: center; background: #5596de;color: #FFF;border: none;display: block;cursor: pointer;' type='button' value='跳转详情' onClick=\"showToast()\">" + |
| | | "</div>" + |
| | | "</div>"; |
| | | infoWin.setContent(sContent); |
| | | |
| | | // 添加点击事件 |
| | | marker.addEventListener("click", function () { |
| | | marker.openInfoWindow(infoWin); |
| | | }); |
| | | |
| | | lastMarker = marker; |
| | | } |
| | | |
| | | // 删除上次点击后添加的标注 |
| | | function removeMyOverLay() { |
| | | if (lastMarker !== null) { |
| | | map.removeOverLay(lastMarker); // 将标注从地图中移除 |
| | | } |
| | | } |
| | | |
| | | // 模拟添加取水口标注 |
| | | function buttonOverLay() { |
| | | map.clearOverLays(); // 清理地图上的所有覆盖物 |
| | | |
| | | let data_info = [ |
| | | [116.417854, 39.921988, "235取水口"], |
| | | [116.406605, 39.921585, "237取水口"], |
| | | [116.412222, 39.912345, "236取水口"] |
| | | ]; |
| | | |
| | | for (let i = 0; i < data_info.length; i++) { |
| | | let icon = new T.Icon({ |
| | | iconUrl: markerBalckPath, |
| | | iconSize: new T.Point(27, 27), |
| | | iconAnchor: new T.Point(10, 25) |
| | | }); |
| | | |
| | | let marker = new T.Marker( |
| | | new T.LngLat(data_info[i][0], data_info[i][1]), // 创建标注 |
| | | { icon: icon } |
| | | ); |
| | | |
| | | marker.addEventListener("click", function (data) { |
| | | addMarkerListener(data); |
| | | }); |
| | | |
| | | map.addOverLay(marker); // 将标注添加到地图中 |
| | | |
| | | let label = new T.Label({ |
| | | text: data_info[i][2], |
| | | position: marker.getLngLat(), |
| | | offset: new T.Point(-50, 10), // 设置标注文字的位置 |
| | | opacity: 1, // 设置文本的显示不透明度(范围0-1) |
| | | }); |
| | | label.setBorderLine(0); // 设置文本的边框线宽 |
| | | label.setBackgroundColor("transparent"); // 设置文本的背景色(透明色) |
| | | label.setFontColor("#0000FF"); |
| | | label.setFontSize(10); |
| | | map.addOverLay(label); |
| | | } |
| | | } |
| | | |
| | | // 显示标注点击后的窗口 |
| | | function openInfo(content, e) { |
| | | let point = e.lnglat; |
| | | let markerInfoWin = new T.InfoWindow(content, { |
| | | offset: new T.Point(0, -30) |
| | | }); |
| | | map.openInfoWindow(markerInfoWin, point); // 开启信息窗口 |
| | | } |
| | | |
| | | // 手机获取到定位后显示定位 |
| | | function locationOverLay(lng, lag) { |
| | | map.centerAndZoom(new T.LngLat(lng, lag), 18); |
| | | |
| | | let icon = new T.Icon({ |
| | | iconUrl: locationIMGPath, |
| | | iconSize: new T.Point(27, 27), |
| | | iconAnchor: new T.Point(10, 25) |
| | | }); |
| | | |
| | | let marker = new T.Marker(new T.LngLat(lng, lag), { icon: icon }); |
| | | map.addOverLay(marker); |
| | | } |
| | | |
| | | // 将方法挂载到 window 上 |
| | | function mountMethodToWindow() { |
| | | window.locationOverLay = locationOverLay; |
| | | window.showToast = showToast; |
| | | window.addMarker = addMarker; |
| | | } |
| | | |
| | | // 调用原生安卓方法显示取水口详情 |
| | | function showWaterIntakeDetail(data) { |
| | | isShowWaterIntakeDetail = true; |
| | | window.Android.showWaterIntakeView(data); |
| | | } |
| | | |
| | | // 调用原生安卓方法隐藏取水口详情 |
| | | function closeWaterIntakeDetail(data) { |
| | | if (lastClickedMarker!== null) { |
| | | // 如果有点击取水口则将取水口恢复成黑色 |
| | | // 上次点击的标注改为黑色 |
| | | var defaulticon = new T.Icon({ |
| | | iconUrl: markerBalckPath, |
| | | iconSize: new T.Point(27, 27), |
| | | iconAnchor: new T.Point(10, 25) |
| | | }); |
| | | lastClickedMarker.setIcon(defaulticon); |
| | | } |
| | | if (isShowWaterIntakeDetail) { |
| | | // 假如显示了取水口详情则隐藏取水口详情 |
| | | isShowWaterIntakeDetail = false; |
| | | window.Android.closeWaterIntakeView(); |
| | | } else { |
| | | // 假如没有显示取水口则添加点击的坐标 |
| | | getLngLat(data.lnglat); |
| | | } |
| | | } |
| | | |
| | | // 点击标注的事件 |
| | | function addMarkerListener(data) { |
| | | chageMarkerIcon(data); |
| | | showWaterIntakeDetail("模拟数据"); |
| | | } |
| | | |
| | | // 修改点击标注的图标 |
| | | function chageMarkerIcon(data) { |
| | | // 点击的标注改为红色 |
| | | var currentMarker = data.target; |
| | | // 点击后图标 |
| | | var clickedIcon = new T.Icon({ |
| | | iconUrl: markerRedPath, |
| | | iconSize: new T.Point(27, 27), |
| | | iconAnchor: new T.Point(10, 25) |
| | | }); |
| | | // 设置当前点击的 marker 为点击后图标 |
| | | currentMarker.setIcon(clickedIcon); |
| | | // 判断点击的不是同一个坐标 |
| | | if (lastClickedMarker!== null) { |
| | | if (!isEqualsLngLat(data.target.getLngLat(), lastClickedMarker.getLngLat())) { |
| | | var defaulticon = new T.Icon({ |
| | | iconUrl: markerBalckPath, |
| | | iconSize: new T.Point(27, 27), |
| | | iconAnchor: new T.Point(10, 25) |
| | | }); |
| | | lastClickedMarker.setIcon(defaulticon); |
| | | } |
| | | } |
| | | lastClickedMarker = data.target; |
| | | } |
| | | //调安卓原生 |
| | | function showToast() { |
| | | // 调用 JavaScript 接口对象的方法 |
| | | window.Android.showToast('Hello, Android!'); |
| | | } |
| | | // 判断两个坐标是否一致 |
| | | function isEqualsLngLat(data1, data2) { |
| | | return data1.lat === data2.lat && data1.lng === data2.lng; |
| | | } |
| | | //添加从原生传过来的坐标并显示在地图上 |
| | | function addMarker(jsonData) { |
| | | console.log("function》》》》》addMarker"); |
| | | var array = JSON.parse(jsonData); |
| | | var icon = new T.Icon({ |
| | | iconUrl: markerBalckPath, |
| | | iconSize: new T.Point(27, 27), |
| | | iconAnchor: new T.Point(10, 25) |
| | | }); |
| | | array.forEach(element => { |
| | | let marker = new T.Marker( |
| | | new T.LngLat(element[0], element[1]) // 创建标注 |
| | | , { icon: icon }); |
| | | //添加点击事件 |
| | | marker.addEventListener("click", (data) => { |
| | | addMarkerListener(data) |
| | | }); |
| | | map.addOverLay(marker); // 将标注添加到地图中 |
| | | }); |
| | | return "addMarker加载成功" |
| | | } |
| | | |
| | | |
| | | })(); |
| | |
| | | import com.dayu.pipirrapp.net.ApiManager; |
| | | import com.tencent.bugly.crashreport.CrashReport; |
| | | |
| | | import cn.jpush.android.api.JPushInterface; |
| | | //import cn.jpush.android.api.JPushInterface; |
| | | |
| | | /** |
| | | * author: zuo |
| | |
| | | |
| | | ApiManager.init(); |
| | | |
| | | JPushInterface.setDebugMode(true); |
| | | JPushInterface.init(this); |
| | | // JPushInterface.setDebugMode(true); |
| | | // JPushInterface.init(this); |
| | | CrashReport.initCrashReport(getApplicationContext(), "3d4bcf7046", false); |
| | | } |
| | | } |
| | |
| | | import android.os.Bundle; |
| | | import android.view.KeyEvent; |
| | | import android.view.LayoutInflater; |
| | | import android.view.MotionEvent; |
| | | import android.view.View; |
| | | import android.widget.Toast; |
| | | |
| | | import androidx.appcompat.app.AppCompatActivity; |
| | | import androidx.core.content.ContextCompat; |
| | | import androidx.fragment.app.Fragment; |
| | | |
| | | import com.dayu.pipirrapp.R; |
| | | import com.dayu.pipirrapp.adapter.TabAdapter; |
| | | import com.dayu.pipirrapp.databinding.ActivityMainBinding; |
| | | import com.dayu.pipirrapp.fragment.BaseFragment; |
| | | import com.dayu.pipirrapp.fragment.MainFragment; |
| | | import com.dayu.pipirrapp.fragment.MapFragment; |
| | | import com.dayu.pipirrapp.fragment.MyFragment; |
| | |
| | | import java.util.ArrayList; |
| | | import java.util.List; |
| | | |
| | | |
| | | /** |
| | | * |
| | | * 首页 |
| | | */ |
| | | public class MainActivity extends BaseActivity { |
| | | ActivityMainBinding binding; |
| | | List<Fragment> mFragment = new ArrayList<>(); |
| | | public class MainActivity extends AppCompatActivity { |
| | | private ActivityMainBinding binding; |
| | | private List<Fragment> fragments = new ArrayList<>(); |
| | | private long mExitTime; |
| | | |
| | | private enum Tab { |
| | | ORDER, MAP, MY |
| | | } |
| | | |
| | | @Override |
| | | protected void onCreate(Bundle savedInstanceState) { |
| | | |
| | | super.onCreate(savedInstanceState); |
| | | binding = ActivityMainBinding.inflate(LayoutInflater.from(this)); |
| | | MapFragment mapFragment = new MapFragment(); |
| | | setContentView(binding.getRoot()); |
| | | mFragment.add(mapFragment); |
| | | mFragment.add(new MainFragment()); |
| | | mFragment.add(new MyFragment()); |
| | | |
| | | setupFragments(); |
| | | initView(); |
| | | initTab(); |
| | | } |
| | | |
| | | private void getPermission(){ |
| | | |
| | | private void setupFragments() { |
| | | fragments.add(new MainFragment()); |
| | | fragments.add(new MapFragment()); |
| | | fragments.add(new MyFragment()); |
| | | } |
| | | |
| | | |
| | | private void initView() { |
| | | binding.orderLL.setOnClickListener(v -> changeBottomState(Tab.ORDER)); |
| | | binding.mapLL.setOnClickListener(v -> changeBottomState(Tab.MAP)); |
| | | binding.myLL.setOnClickListener(v -> changeBottomState(Tab.MY)); |
| | | } |
| | | |
| | | private void initTab() { |
| | | TabAdapter adapter = new TabAdapter(getSupportFragmentManager(), mFragment); |
| | | TabAdapter adapter = new TabAdapter(getSupportFragmentManager(), fragments); |
| | | binding.viewPager.setAdapter(adapter); |
| | | binding.viewPager.setPagingEnabled(false); |
| | | //设置缓存view 的个数 |
| | | binding.viewPager.setOffscreenPageLimit(3); |
| | | // 将 ViewPager 与 TabLayout 关联 |
| | | binding.tabLayout.setupWithViewPager(binding.viewPager); |
| | | binding.viewPager.setOffscreenPageLimit(fragments.size()); |
| | | binding.viewPager.setCurrentItem(1); // 默认显示地图页 |
| | | } |
| | | |
| | | long mExitTime; |
| | | |
| | | //点击两次退出程序 有时间间隔 间隔内点击则退出程序 否则 则提示 |
| | | @Override |
| | | public boolean onKeyDown(int keyCode, KeyEvent event) { |
| | | if (keyCode == KeyEvent.KEYCODE_BACK) { |
| | |
| | | Toast.makeText(MainActivity.this, "再按一次退出程序", Toast.LENGTH_SHORT).show(); |
| | | mExitTime = System.currentTimeMillis(); |
| | | } else { |
| | | MainActivity.this.finish(); |
| | | finish(); |
| | | } |
| | | return true; |
| | | } |
| | | return super.onKeyDown(keyCode, event); |
| | | } |
| | | |
| | | } |
| | | /** |
| | | * 修改底部状态 |
| | | */ |
| | | private void changeBottomState(Tab tab) { |
| | | resetTabState(); |
| | | switch (tab) { |
| | | case ORDER: |
| | | updateTabUI(0, R.drawable.bottom_order_white, R.color.white); |
| | | break; |
| | | case MAP: |
| | | updateTabUI(1, R.drawable.bottom_map_white, R.color.white); |
| | | break; |
| | | case MY: |
| | | updateTabUI(2, R.drawable.bottom_my_white, R.color.white); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 更新某个 Tab 的 UI 状态 |
| | | */ |
| | | private void updateTabUI(int position, int iconResId, int textColorResId) { |
| | | binding.viewPager.setCurrentItem(position); |
| | | switch (position) { |
| | | case 0: |
| | | binding.orderImg.setImageDrawable(ContextCompat.getDrawable(this, iconResId)); |
| | | binding.orderText.setTextColor(ContextCompat.getColor(this, textColorResId)); |
| | | break; |
| | | case 1: |
| | | binding.mapImg.setImageDrawable(ContextCompat.getDrawable(this, iconResId)); |
| | | binding.mapText.setTextColor(ContextCompat.getColor(this, textColorResId)); |
| | | break; |
| | | case 2: |
| | | binding.myImg.setImageDrawable(ContextCompat.getDrawable(this, iconResId)); |
| | | binding.myText.setTextColor(ContextCompat.getColor(this, textColorResId)); |
| | | break; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 重置所有 Tab 的默认状态 |
| | | */ |
| | | private void resetTabState() { |
| | | binding.orderImg.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.bottom_order_black)); |
| | | binding.orderText.setTextColor(ContextCompat.getColor(this, R.color.black)); |
| | | |
| | | binding.mapImg.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.bottom_map_black)); |
| | | binding.mapText.setTextColor(ContextCompat.getColor(this, R.color.black)); |
| | | |
| | | binding.myImg.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.bottom_my_black)); |
| | | binding.myText.setTextColor(ContextCompat.getColor(this, R.color.black)); |
| | | } |
| | | } |
| | |
| | | import android.content.Intent; |
| | | import android.location.LocationManager; |
| | | import android.os.Bundle; |
| | | import android.os.Handler; |
| | | import android.os.Looper; |
| | | import android.util.Log; |
| | | import android.view.LayoutInflater; |
| | | import android.view.View; |
| | | import android.view.ViewGroup; |
| | | import android.webkit.JsResult; |
| | | import android.webkit.WebChromeClient; |
| | | import android.webkit.WebSettings; |
| | | import android.webkit.ValueCallback; |
| | | import android.webkit.WebResourceError; |
| | | import android.webkit.WebResourceRequest; |
| | | import android.webkit.WebResourceResponse; |
| | | import android.webkit.WebView; |
| | | import android.webkit.WebViewClient; |
| | | |
| | | import androidx.annotation.NonNull; |
| | | import androidx.annotation.Nullable; |
| | | import androidx.lifecycle.DefaultLifecycleObserver; |
| | | import androidx.lifecycle.LifecycleOwner; |
| | | |
| | | import com.dayu.pipirrapp.databinding.FragmentMapBinding; |
| | | import com.dayu.pipirrapp.js.MyWebViewInterface; |
| | | import com.dayu.pipirrapp.observer.MapFragmenObserver; |
| | | import com.dayu.pipirrapp.service.MyLocationService; |
| | | import com.dayu.pipirrapp.utils.MapJpgUtils; |
| | | import com.dayu.pipirrapp.utils.MyLog; |
| | | import com.dayu.pipirrapp.utils.ToastUtil; |
| | | import com.dayu.pipirrapp.utils.WebViewUtils; |
| | | |
| | | import java.util.List; |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.io.FileNotFoundException; |
| | | import java.util.Random; |
| | | |
| | | /** |
| | | * author: zuo |
| | |
| | | binding = FragmentMapBinding.inflate(inflater, container, false); |
| | | Log.i("MapFragment", "onCreateView"); |
| | | mWebView = binding.webView; |
| | | initWebView(); |
| | | mWebView.loadUrl("http://192.168.3.178:3000/"); |
| | | mWebView = WebViewUtils.initWebView(mWebView); |
| | | MyWebViewInterface myWebViewInterface = new MyWebViewInterface(MapFragment.this); |
| | | mWebView.addJavascriptInterface(myWebViewInterface, "Android"); |
| | | mWebView.loadUrl("file:///android_asset/index.html"); |
| | | |
| | | initView(); |
| | | //开启定位 |
| | | Intent location = new Intent(this.getActivity(), MyLocationService.class); |
| | | location.putExtra("isSingle", false); |
| | | this.getActivity().startService(location); |
| | | return binding.getRoot(); |
| | | } |
| | | |
| | | /** |
| | | * 添加标注点 |
| | | */ |
| | | public void addMarker() { |
| | | Random random = new Random(); |
| | | StringBuilder stringBuilder = new StringBuilder(); |
| | | stringBuilder.append("["); |
| | | |
| | | // 中国经纬度范围 |
| | | double minLongitude = 73.43; |
| | | double maxLongitude = 135.05; |
| | | double minLatitude = 3.52; |
| | | double maxLatitude = 53.57; |
| | | |
| | | for (int i = 0; i < 1000; i++) { |
| | | stringBuilder.append("["); |
| | | // 生成随机经度 |
| | | double longitude = minLongitude + (maxLongitude - minLongitude) * random.nextDouble(); |
| | | stringBuilder.append(longitude); |
| | | stringBuilder.append(","); |
| | | // 生成随机纬度 |
| | | double latitude = minLatitude + (maxLatitude - minLatitude) * random.nextDouble(); |
| | | stringBuilder.append(latitude); |
| | | stringBuilder.append(",\"237取水口\"],"); |
| | | } |
| | | stringBuilder.append("[116.417854,39.921988,\"235取水口\"]]"); |
| | | String jsonData = stringBuilder.toString().replace("\\", "\\\\").replace("\"", "\\\""); |
| | | // String jsonData = "[[116.417854,39.921988,\"235取水口\"],[116.406605,39.921585,\"237取水口\"],[116.412222,39.912345,\"236取水口\"]]"; |
| | | Log.i("mWebView", "addMarker????????????" + jsonData); |
| | | mWebView.evaluateJavascript("javascript:addMarker(\"" + jsonData + "\")", new ValueCallback<String>() { |
| | | @Override |
| | | public void onReceiveValue(String value) { |
| | | Log.i("mWebView", "addMarker!!!!!!!!!" + value); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | |
| | |
| | | @Override |
| | | public void onPause() { |
| | | super.onPause(); |
| | | // |
| | | mWebView.onPause(); // 通过 onPause 动作通知内核暂停所有的动作,如 DOM 的解析、plugin 的执行、JavaScript 执行等 |
| | | |
| | | } |
| | | |
| | | @Override |
| | |
| | | mWebView.destroy(); // 当 Activity 要 destroy 时,应先将 WebView 移除,再 destroy 掉 |
| | | } |
| | | |
| | | void initWebView() { |
| | | // getActivity().getWindow().setFlags( |
| | | // WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, |
| | | // WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); |
| | | // WebView 配置 |
| | | WebSettings webSettings = mWebView.getSettings(); |
| | | // 生命周期 |
| | | // 前进后退 |
| | | if (mWebView.canGoBack()) { |
| | | mWebView.goBack(); |
| | | } |
| | | if (mWebView.canGoForward()) { |
| | | mWebView.goForward(); |
| | | } |
| | | // 缓存相关 |
| | | mWebView.clearCache(false); // 清除缓存 |
| | | // mWebView.clearHistory(); // 清除历史 |
| | | // mWebView.clearFormData(); // 清除表单数据 |
| | | webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);// 设置缓存模式 |
| | | webSettings.setDatabaseEnabled(true); |
| | | webSettings.setDomStorageEnabled(true);//开启DOM缓存,关闭的话H5自身的一些操作是无效的 |
| | | // 缓存模式 |
| | | // LOAD_DEFAULT: 默认,根据 cache-control 决定是否从网络上取数据 |
| | | // LOAD_NORMAL: API level 17 中已经废弃, 从API level 11开始作用同 LOAD_DEFAULT 模式 |
| | | // LOAD_CACHE_ELSE_NETWORK: 只要本地有,无论是否过期,或者 no-cache,都使用缓存中的数据 |
| | | // LOAD_NO_CACHE: 不使用缓存,只从网络获取数据 |
| | | // LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据 |
| | | // js 相关 |
| | | webSettings.setJavaScriptEnabled(true); // 支持 js。如果碰到后台无法释放 js 导致耗电,应在 onStop 和 onResume 里分别设成 false 和 true |
| | | // mWebView.addJavascriptInterface(new WebAppInterface(this), "android"); // js 接口 |
| | | |
| | | // webSettings.setPluginsEnabled(true); // 支持插件 |
| | | // 设置自适应屏幕,两者合用 |
| | | webSettings.setUseWideViewPort(true); // 将图片调整到适合 WebView 的大小 |
| | | webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小 |
| | | // 缩放操作 |
| | | webSettings.setSupportZoom(true); // 支持缩放,默认为 true |
| | | webSettings.setBuiltInZoomControls(true); // 设置内置的缩放控件,若为 false,则该 WebView 不可缩放 |
| | | webSettings.setDisplayZoomControls(false); // 隐藏原生的缩放控件 |
| | | webSettings.setLoadsImagesAutomatically(true);//预加载 |
| | | //webView弹JsAlert |
| | | mWebView.setWebChromeClient(new WebChromeClient() { |
| | | @Override |
| | | public boolean onJsAlert(WebView view, String url, String message, JsResult result) { |
| | | return super.onJsAlert(view, url, message, result); |
| | | } |
| | | }); |
| | | MyWebViewInterface myWebViewInterface=new MyWebViewInterface(this); |
| | | mWebView.addJavascriptInterface(myWebViewInterface,"Android"); |
| | | } |
| | | |
| | | void initView() { |
| | | //跳转到指定位置 |
| | | binding.flyBtn.setOnClickListener(v -> { |
| | | mWebView.evaluateJavascript("javascript:locationOverLay(116.399565,39.89432)", value -> { |
| | | }); |
| | | }); |
| | | mWebView.setWebViewClient(new WebViewClient() { |
| | | @Override |
| | | public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { |
| | | String url = request.getUrl().toString(); |
| | | // 检查本地缓存 |
| | | File cachedTile = MapJpgUtils.getInsatance(MapFragment.this.getContext()).getCachedTile(url); |
| | | if (cachedTile != null && cachedTile.exists()) { |
| | | // 判断缓存是否过期 |
| | | if (!MapJpgUtils.getInsatance(MapFragment.this.getContext()).isCacheExpired(cachedTile)) { |
| | | try { |
| | | // 从缓存加载瓦片 |
| | | return new WebResourceResponse("image/jpg", "utf-8", new FileInputStream(cachedTile)); |
| | | } catch (FileNotFoundException e) { |
| | | e.printStackTrace(); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return super.shouldInterceptRequest(view, request); |
| | | } |
| | | |
| | | @Override |
| | | public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { |
| | | super.onReceivedError(view, request, error); |
| | | // 捕获加载过程中发生的错误 |
| | | int errorCode = error.getErrorCode(); |
| | | String description = error.getDescription().toString(); |
| | | String failingUrl = request.getUrl().toString(); |
| | | Log.e("setWebViewClient", "errorCode:" + errorCode + ">>>>description:" + description + ">>>>failingUrl:" + failingUrl); |
| | | // 处理错误,例如显示错误页面或提示用户 |
| | | // view.loadUrl("file:///android_asset/error.html"); |
| | | } |
| | | |
| | | @Override |
| | | public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) { |
| | | super.onReceivedHttpError(view, request, errorResponse); |
| | | // 捕获HTTP错误(如404, 500等) |
| | | int statusCode = errorResponse.getStatusCode(); |
| | | String description = errorResponse.getReasonPhrase(); |
| | | Log.e("setWebViewClient", "statusCode:" + statusCode + ">>>>description:" + description); |
| | | // 根据HTTP状态码处理错误 |
| | | } |
| | | }); |
| | | } |
| | | |
| | | |
| | | public void showWaterIntakeDetail(String data){ |
| | | public void showWaterIntakeDetail(String data) { |
| | | MyLog.i(data); |
| | | binding.bottomLL.setVisibility(View.VISIBLE); |
| | | } |
| | | |
| | | |
| | | |
| | | public void closeWaterIntakeDetail(){ |
| | | public void closeWaterIntakeDetail() { |
| | | binding.bottomLL.setVisibility(View.GONE); |
| | | } |
| | | |
| | |
| | | package com.dayu.pipirrapp.js; |
| | | |
| | | import android.content.Context; |
| | | import android.os.Handler; |
| | | import android.os.Looper; |
| | | import android.webkit.JavascriptInterface; |
| | |
| | | } |
| | | } |
| | | |
| | | @JavascriptInterface |
| | | public void loadMarker(){ |
| | | if (myContext instanceof MapFragment) { |
| | | new Handler(Looper.getMainLooper()).post(new Runnable() { |
| | | @Override |
| | | public void run() { |
| | | // 在主线程上执行UI操作 |
| | | // 更新或操作UI元素的代码 |
| | | myContext.addMarker(); |
| | | } |
| | | }); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | package com.dayu.pipirrapp.net; |
| | | |
| | | import android.content.Context; |
| | | |
| | | import android.util.Log; |
| | | |
| | | import com.dayu.pipirrapp.bean.WeatherResponse; |
| | | import com.dayu.pipirrapp.net.subscribers.BaseProgressSubscriber; |
| | | import com.dayu.pipirrapp.net.subscribers.ProgressSubscriber; |
| | | import com.dayu.pipirrapp.net.subscribers.SubscriberListener; |
| | | import com.dayu.pipirrapp.utils.MapJpgUtils; |
| | | import com.dayu.pipirrapp.utils.MyJsonParser; |
| | | |
| | | import java.io.File; |
| | | import java.io.FileNotFoundException; |
| | | import java.io.FileOutputStream; |
| | | import java.io.IOException; |
| | | import java.io.InputStream; |
| | | import java.util.HashMap; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Objects; |
| | | |
| | | import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers; |
| | | import io.reactivex.rxjava3.annotations.NonNull; |
| | | import io.reactivex.rxjava3.core.Observable; |
| | | import io.reactivex.rxjava3.core.Observer; |
| | | import io.reactivex.rxjava3.disposables.Disposable; |
| | | import io.reactivex.rxjava3.disposables.CompositeDisposable; |
| | | import io.reactivex.rxjava3.functions.Function; |
| | | import io.reactivex.rxjava3.schedulers.Schedulers; |
| | | import okhttp3.MediaType; |
| | | import okhttp3.MultipartBody; |
| | | import okhttp3.RequestBody; |
| | | import okhttp3.ResponseBody; |
| | | import retrofit2.Call; |
| | | import retrofit2.Callback; |
| | | import retrofit2.Response; |
| | | |
| | | |
| | | /** |
| | |
| | | */ |
| | | public class ApiManager { |
| | | |
| | | static String TAG = "ApiManager"; |
| | | |
| | | static ApiManager apiManager; |
| | | //文件上传失败重复次数 |
| | | int uplodFilerepeatSize = 3; |
| | | |
| | | ApiService apiService; |
| | | private CompositeDisposable compositeDisposable = new CompositeDisposable(); // 管理订阅事件 |
| | | |
| | | /** |
| | | * 初始化通信框架 |
| | |
| | | |
| | | public ApiManager() { |
| | | apiService = RetrofitClient.getInstance().getApiService(); |
| | | |
| | | } |
| | | |
| | | public static ApiManager getInstance() { |
| | |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * 获取天气 |
| | | * @param data 经纬度(格式是 纬度:经度,英文冒号分隔) |
| | | * 获取天气 |
| | | * |
| | | * @param data 经纬度(格式是 纬度:经度,英文冒号分隔) |
| | | * @param callback |
| | | * @param <T> |
| | | */ |
| | | public <T> void requestWeather(String data,Callback<WeatherResponse> callback) { |
| | | public <T> void requestWeather(String data, Callback<WeatherResponse> callback) { |
| | | Map<String, Object> params = new HashMap<>(); |
| | | params.put("key", "S6Tq4pvOakMuWRrg0"); |
| | | params.put("location", data); |
| | |
| | | } |
| | | |
| | | |
| | | public void donwLoadTile(Context context, String urlPath) { |
| | | Observable<ResponseBody> observable; |
| | | observable = apiService.downloadTile(urlPath); |
| | | |
| | | |
| | | compositeDisposable.add( |
| | | observable |
| | | .subscribeOn(Schedulers.io()) // 网络请求在 I/O 线程中进行 |
| | | .observeOn(Schedulers.io()) // 回调处理也在 I/O 线程 |
| | | .subscribe( |
| | | responseBody -> { |
| | | boolean success = false; |
| | | if (!MapJpgUtils.getInsatance(context).isHasFiles(urlPath)) { |
| | | success = MapJpgUtils.getInsatance(context).saveTileToCache(urlPath, responseBody); |
| | | } |
| | | if (success) { |
| | | Log.d(TAG, "Download success for tile: " + urlPath); |
| | | } else { |
| | | Log.e(TAG, "Failed to save tile to disk: " + urlPath); |
| | | } |
| | | }, |
| | | throwable -> Log.e(TAG, "Download failed for tile: " + urlPath) |
| | | ) |
| | | ); |
| | | |
| | | |
| | | } |
| | | |
| | | // 停止线程池,释放资源 |
| | | public void clearDisposables() { |
| | | if (!compositeDisposable.isDisposed()) { |
| | | compositeDisposable.dispose(); |
| | | } |
| | | } |
| | | |
| | | } |
| | |
| | | package com.dayu.pipirrapp.net; |
| | | |
| | | |
| | | |
| | | import com.dayu.pipirrapp.bean.WeatherResponse; |
| | | |
| | | import java.util.Map; |
| | |
| | | @POST(Constants.BASE_URL + "file/upload") |
| | | Call<BaseResponse> uploadFile(@Part("description") RequestBody description, @Part MultipartBody.Part file); |
| | | |
| | | |
| | | @GET("{url}}") |
| | | Observable<ResponseBody> downloadTile(@Path("url") String url); |
| | | |
| | | } |
| | |
| | | package com.dayu.pipirrapp.service; |
| | | |
| | | import cn.jpush.android.service.JCommonService; |
| | | //import cn.jpush.android.service.JCommonService; |
| | | |
| | | /** |
| | | * author: zuo |
| | |
| | | * Time: 11:51 |
| | | * 备注: |
| | | */ |
| | | public class MyCommonService extends JCommonService { |
| | | } |
| | | //public class MyCommonService extends JCommonService { |
| | | //} |
| | |
| | | super.onCreate(); |
| | | |
| | | createNativeLocation(); |
| | | createBDLocation(); |
| | | // createBDLocation(); |
| | | } |
| | | |
| | | |
| | |
| | | if (locationManager != null) { |
| | | locationManager.removeUpdates(listener); |
| | | } |
| | | if (mBDLocationClient != null) { |
| | | mBDLocationClient.stop(); |
| | | mBDLocationClient.unRegisterLocationListener(mBDLocationListener); |
| | | } |
| | | // if (mBDLocationClient != null) { |
| | | // mBDLocationClient.stop(); |
| | | // mBDLocationClient.unRegisterLocationListener(mBDLocationListener); |
| | | // } |
| | | |
| | | } catch (Exception e) { |
| | | CrashReport.postCatchedException(e); |
| | |
| | | package com.dayu.pipirrapp.service; |
| | | |
| | | import android.app.Service; |
| | | import android.content.Intent; |
| | | import android.os.IBinder; |
| | | |
| | | import androidx.annotation.Nullable; |
| | | |
| | | import cn.jpush.android.service.JPushMessageService; |
| | | //import cn.jpush.android.service.JPushMessageService; |
| | | |
| | | /** |
| | | * author: zuo |
| | |
| | | * Time: 10:29 |
| | | * 备注:推送的服务 |
| | | */ |
| | | public class PushService extends JPushMessageService { |
| | | |
| | | } |
| | | //public class PushService extends JPushMessageService { |
| | | // |
| | | //} |
New file |
| | |
| | | package com.dayu.pipirrapp.tool; |
| | | |
| | | import android.util.Log; |
| | | |
| | | import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer; |
| | | import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext; |
| | | import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus; |
| | | import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently; |
| | | import org.apache.rocketmq.client.exception.MQClientException; |
| | | import org.apache.rocketmq.common.message.MessageExt; |
| | | |
| | | import java.util.List; |
| | | |
| | | /** |
| | | * author: zuo |
| | | * Date: 2024-09-03 |
| | | * Time: 13:51 |
| | | * 备注:MQ消息队列模块 |
| | | */ |
| | | public class RocketMQConsumer { |
| | | |
| | | private DefaultMQPushConsumer consumer; |
| | | |
| | | public void start() { |
| | | try { |
| | | // 创建一个消费者实例 |
| | | consumer = new DefaultMQPushConsumer("YourConsumerGroup"); |
| | | |
| | | // 设置NameServer地址 |
| | | consumer.setNamesrvAddr("YourNameServerAddress"); |
| | | |
| | | // 订阅一个或多个Topic |
| | | consumer.subscribe("YourTopic", "*"); |
| | | |
| | | // 注册消息监听器 |
| | | consumer.registerMessageListener(new MessageListenerConcurrently() { |
| | | @Override |
| | | public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) { |
| | | for (MessageExt msg : msgs) { |
| | | // 处理消息 |
| | | Log.d("RocketMQ", "Receive message: " + new String(msg.getBody())); |
| | | // 这里可以触发本地通知或者更新UI |
| | | } |
| | | return ConsumeConcurrentlyStatus.CONSUME_SUCCESS; |
| | | } |
| | | }); |
| | | |
| | | // 启动消费者 |
| | | consumer.start(); |
| | | |
| | | } catch (MQClientException e) { |
| | | e.printStackTrace(); |
| | | Log.e("RocketMQ", "Consumer failed to start: " + e.getMessage()); |
| | | } |
| | | } |
| | | |
| | | public void stop() { |
| | | if (consumer != null) { |
| | | consumer.shutdown(); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | package com.dayu.pipirrapp.utils; |
| | | |
| | | import android.content.Context; |
| | | |
| | | import java.io.File; |
| | | import java.io.FileOutputStream; |
| | | import java.io.InputStream; |
| | | import java.io.OutputStream; |
| | | import java.security.MessageDigest; |
| | | import java.security.NoSuchAlgorithmException; |
| | | |
| | | import okhttp3.ResponseBody; |
| | | |
| | | /** |
| | | * author: zuo |
| | | * Date: 2024-09-06 |
| | | * Time: 17:59 |
| | | * 备注: 完成地图缓存策略 |
| | | */ |
| | | public class MapJpgUtils { |
| | | static MapJpgUtils mapJpgUtils; |
| | | Context context; |
| | | |
| | | public static MapJpgUtils getInsatance(Context context) { |
| | | if (mapJpgUtils == null) { |
| | | mapJpgUtils = new MapJpgUtils(); |
| | | } |
| | | mapJpgUtils.context = context; |
| | | return mapJpgUtils; |
| | | } |
| | | |
| | | |
| | | // 获取缓存瓦片文件 |
| | | public File getCachedTile(String url) { |
| | | String fileName = hashUrl(url); // URL 转换为唯一的哈希值或文件名 |
| | | File cacheDir = new File(context.getCacheDir(), "mapCache"); // 瓦片存储目录 |
| | | if (!cacheDir.exists()) { |
| | | cacheDir.mkdirs(); |
| | | } |
| | | return new File(cacheDir, fileName); |
| | | } |
| | | |
| | | // 使用 MD5 哈希 URL 作为文件名 |
| | | private String hashUrl(String url) { |
| | | try { |
| | | MessageDigest digest = MessageDigest.getInstance("MD5"); |
| | | digest.update(url.getBytes()); |
| | | byte[] hashBytes = digest.digest(); |
| | | StringBuilder sb = new StringBuilder(); |
| | | for (byte b : hashBytes) { |
| | | sb.append(String.format("%02x", b)); |
| | | } |
| | | return sb.toString(); |
| | | } catch (NoSuchAlgorithmException e) { |
| | | e.printStackTrace(); |
| | | return String.valueOf(url.hashCode()); |
| | | } |
| | | } |
| | | |
| | | // 保存瓦片到缓存 |
| | | public boolean saveTileToCache(String url, ResponseBody body) { |
| | | |
| | | try { |
| | | File tileFile = new File(context.getCacheDir() + File.separator + hashUrl(url) + ".png"); |
| | | |
| | | if (!tileFile.getParentFile().exists()) { |
| | | tileFile.getParentFile().mkdirs(); |
| | | } |
| | | |
| | | InputStream inputStream = null; |
| | | OutputStream outputStream = null; |
| | | |
| | | try { |
| | | byte[] fileReader = new byte[4096]; |
| | | long fileSizeDownloaded = 0; |
| | | |
| | | inputStream = body.byteStream(); |
| | | outputStream = new FileOutputStream(tileFile); |
| | | |
| | | while (true) { |
| | | int read = inputStream.read(fileReader); |
| | | |
| | | if (read == -1) { |
| | | break; |
| | | } |
| | | outputStream.write(fileReader, 0, read); |
| | | fileSizeDownloaded += read; |
| | | } |
| | | |
| | | outputStream.flush(); |
| | | // 保存完成后,记录缓存创建时间 |
| | | tileFile.setLastModified(System.currentTimeMillis()); |
| | | return true; |
| | | } catch (Exception e) { |
| | | return false; |
| | | } finally { |
| | | if (inputStream != null) { |
| | | inputStream.close(); |
| | | } |
| | | if (outputStream != null) { |
| | | outputStream.close(); |
| | | } |
| | | } |
| | | } catch (Exception e) { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * 判断文件是否存在 |
| | | * |
| | | * @param url |
| | | * @return |
| | | */ |
| | | public boolean isHasFiles(String url) { |
| | | String fileName = hashUrl(url); // URL 转换为唯一的哈希值或文件名 |
| | | File cacheDir = new File(context.getCacheDir(), "mapCache"); // 瓦片存储目录 |
| | | if (!cacheDir.exists()) { |
| | | cacheDir.mkdirs(); |
| | | } |
| | | if (new File(cacheDir, fileName).exists()) { |
| | | return true; |
| | | } |
| | | return false; |
| | | } |
| | | |
| | | // 判断缓存是否过期 |
| | | public boolean isCacheExpired(File cachedFile) { |
| | | final long cacheValidity = 24 * 60 * 60 * 1000; // 1 天有效期 |
| | | long lastModified = cachedFile.lastModified(); |
| | | return (System.currentTimeMillis() - lastModified) > cacheValidity; |
| | | } |
| | | |
| | | // 清理旧缓存 |
| | | private void clearOldCacheFiles() { |
| | | File cacheDir = new File(context.getCacheDir(), "mapCache"); |
| | | if (cacheDir.exists()) { |
| | | File[] files = cacheDir.listFiles(); |
| | | if (files != null) { |
| | | for (File file : files) { |
| | | // 清理超过 7 天的缓存文件 |
| | | if (System.currentTimeMillis() - file.lastModified() > 7 * 24 * 60 * 60 * 1000) { |
| | | file.delete(); |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
New file |
| | |
| | | package com.dayu.pipirrapp.utils; |
| | | |
| | | import android.util.Log; |
| | | import android.webkit.ConsoleMessage; |
| | | import android.webkit.JsResult; |
| | | import android.webkit.WebChromeClient; |
| | | import android.webkit.WebSettings; |
| | | import android.webkit.WebView; |
| | | |
| | | /** |
| | | * author: zuo |
| | | * Date: 2024-09-03 |
| | | * Time: 15:43 |
| | | * 备注: |
| | | */ |
| | | public class WebViewUtils { |
| | | |
| | | |
| | | public static WebView initWebView(WebView mWebView) { |
| | | |
| | | // getActivity().getWindow().setFlags( |
| | | // WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, |
| | | // WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); |
| | | // WebView 配置 |
| | | WebSettings webSettings = mWebView.getSettings(); |
| | | // 生命周期 |
| | | // 前进后退 |
| | | if (mWebView.canGoBack()) { |
| | | mWebView.goBack(); |
| | | } |
| | | if (mWebView.canGoForward()) { |
| | | mWebView.goForward(); |
| | | } |
| | | |
| | | // 缓存相关 |
| | | mWebView.clearCache(false); // 清除缓存 |
| | | // mWebView.clearHistory(); // 清除历史 |
| | | // mWebView.clearFormData(); // 清除表单数据 |
| | | webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);// 设置缓存模式 |
| | | webSettings.setDatabaseEnabled(true); |
| | | webSettings.setDomStorageEnabled(true);//开启DOM缓存,关闭的话H5自身的一些操作是无效的 |
| | | // 缓存模式 |
| | | // LOAD_DEFAULT: 默认,根据 cache-control 决定是否从网络上取数据 |
| | | // LOAD_NORMAL: API level 17 中已经废弃, 从API level 11开始作用同 LOAD_DEFAULT 模式 |
| | | // LOAD_CACHE_ELSE_NETWORK: 只要本地有,无论是否过期,或者 no-cache,都使用缓存中的数据 |
| | | // LOAD_NO_CACHE: 不使用缓存,只从网络获取数据 |
| | | // LOAD_CACHE_ONLY: 不使用网络,只读取本地缓存数据 |
| | | // js 相关 |
| | | webSettings.setJavaScriptEnabled(true); // 支持 js。如果碰到后台无法释放 js 导致耗电,应在 onStop 和 onResume 里分别设成 false 和 true |
| | | // mWebView.addJavascriptInterface(new WebAppInterface(this), "android"); // js 接口 |
| | | |
| | | // webSettings.setPluginsEnabled(true); // 支持插件 |
| | | // 设置自适应屏幕,两者合用 |
| | | webSettings.setUseWideViewPort(true); // 将图片调整到适合 WebView 的大小 |
| | | webSettings.setLoadWithOverviewMode(true); // 缩放至屏幕的大小 |
| | | // 缩放操作 |
| | | webSettings.setSupportZoom(true); // 支持缩放,默认为 true |
| | | webSettings.setBuiltInZoomControls(true); // 设置内置的缩放控件,若为 false,则该 WebView 不可缩放 |
| | | webSettings.setDisplayZoomControls(false); // 隐藏原生的缩放控件 |
| | | webSettings.setLoadsImagesAutomatically(true);//预加载 |
| | | //添加访问权限 |
| | | webSettings.setAllowFileAccess(true); |
| | | webSettings.setAllowFileAccessFromFileURLs(true); |
| | | webSettings.setAllowUniversalAccessFromFileURLs(true); |
| | | |
| | | //webView弹JsAlert |
| | | mWebView.setWebChromeClient(new WebChromeClient() { |
| | | @Override |
| | | public boolean onJsAlert(WebView view, String url, String message, JsResult result) { |
| | | return super.onJsAlert(view, url, message, result); |
| | | } |
| | | @Override |
| | | public boolean onConsoleMessage(ConsoleMessage consoleMessage) { |
| | | Log.d("WebView", consoleMessage.message() |
| | | + " -- From line " |
| | | + consoleMessage.lineNumber() + " of " |
| | | + consoleMessage.sourceId()); |
| | | return true; |
| | | } |
| | | }); |
| | | |
| | | |
| | | return mWebView; |
| | | } |
| | | } |
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <shape xmlns:android="http://schemas.android.com/apk/res/android"> |
| | | <solid android:color="@color/bottom_color" /> <!-- 按钮的背景色 --> |
| | | <corners android:radius="90dp" /> <!-- 让按钮的四个角变成圆形 --> |
| | | <size android:width="200dp" android:height="100dp" /> <!-- 设置按钮的宽高 --> |
| | | </shape> |
New file |
| | |
| | | <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="M24,44C35.046,44 44,35.046 44,24C44,12.954 35.046,4 24,4C12.954,4 4,12.954 4,24C4,35.046 12.954,44 24,44Z" |
| | | android:strokeWidth="4" |
| | | android:fillColor="#00000000" |
| | | android:strokeColor="#333"/> |
| | | <path |
| | | android:pathData="M4,20.84C7.015,19.417 9.245,19.219 10.689,20.245C12.857,21.786 13.128,28.064 18.058,25.063C22.987,22.063 15.947,20.84 17.475,16.494C19.003,12.147 24.008,15.524 24.506,10.763C24.837,7.589 21.041,6.374 13.116,7.119" |
| | | android:strokeWidth="4" |
| | | android:fillColor="#00000000" |
| | | android:strokeColor="#333"/> |
| | | <path |
| | | android:pathData="M36,8C30.286,12.989 28.29,16.001 30.013,17.037C32.597,18.592 33.693,16.403 36.847,17.037C40,17.671 39.317,21.946 37.659,21.946C36,21.946 27.41,20.852 27.843,25.865C28.275,30.878 33.442,31.62 33.442,34.421C33.442,36.288 32.299,39.146 30.013,42.994" |
| | | android:strokeWidth="4" |
| | | android:fillColor="#00000000" |
| | | android:strokeColor="#333" |
| | | android:strokeLineCap="round"/> |
| | | <path |
| | | android:pathData="M6.104,32.926C7.016,32.529 7.701,32.237 8.16,32.052C12.007,30.498 14.862,30.131 16.724,30.953C20.016,32.406 18.75,35.34 19.782,36.421C20.813,37.502 23.388,37.188 23.388,39.244C23.388,40.615 22.927,42.164 22.007,43.89" |
| | | android:strokeWidth="4" |
| | | android:fillColor="#00000000" |
| | | android:strokeColor="#333" |
| | | android:strokeLineCap="round"/> |
| | | </vector> |
New file |
| | |
| | | <vector xmlns:android="http://schemas.android.com/apk/res/android" |
| | | android:width="24dp" |
| | | android:height="24dp" |
| | | android:viewportWidth="48" |
| | | android:viewportHeight="48"> |
| | | <path |
| | | android:fillColor="#00000000" |
| | | android:pathData="M24,44C35.046,44 44,35.046 44,24C44,12.954 35.046,4 24,4C12.954,4 4,12.954 4,24C4,35.046 12.954,44 24,44Z" |
| | | android:strokeWidth="4" |
| | | android:strokeColor="#fff" /> |
| | | <path |
| | | android:fillColor="#00000000" |
| | | android:pathData="M4,20.84C7.015,19.417 9.245,19.219 10.689,20.245C12.857,21.786 13.128,28.064 18.058,25.063C22.987,22.063 15.947,20.84 17.475,16.494C19.003,12.147 24.008,15.524 24.506,10.763C24.837,7.589 21.041,6.374 13.116,7.119" |
| | | android:strokeWidth="4" |
| | | android:strokeColor="#fff" /> |
| | | <path |
| | | android:fillColor="#00000000" |
| | | android:pathData="M36,8C30.286,12.989 28.29,16.001 30.013,17.037C32.597,18.592 33.693,16.403 36.847,17.037C40,17.671 39.317,21.946 37.659,21.946C36,21.946 27.41,20.852 27.843,25.865C28.275,30.878 33.442,31.62 33.442,34.421C33.442,36.288 32.299,39.146 30.013,42.994" |
| | | android:strokeWidth="4" |
| | | android:strokeColor="#fff" |
| | | android:strokeLineCap="round" /> |
| | | <path |
| | | android:fillColor="#00000000" |
| | | android:pathData="M6.104,32.926C7.016,32.529 7.701,32.237 8.16,32.052C12.007,30.498 14.862,30.131 16.724,30.953C20.016,32.406 18.75,35.34 19.782,36.421C20.813,37.502 23.388,37.188 23.388,39.244C23.388,40.615 22.927,42.164 22.007,43.89" |
| | | android:strokeWidth="4" |
| | | android:strokeColor="#fff" |
| | | android:strokeLineCap="round" /> |
| | | </vector> |
New file |
| | |
| | | <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="M24,44C35.046,44 44,35.046 44,24C44,12.954 35.046,4 24,4C12.954,4 4,12.954 4,24C4,35.046 12.954,44 24,44Z" |
| | | android:strokeLineJoin="round" |
| | | android:strokeWidth="4" |
| | | android:fillColor="#00000000" |
| | | android:fillType="evenOdd" |
| | | android:strokeColor="#333" |
| | | android:strokeLineCap="round"/> |
| | | <path |
| | | android:pathData="M24,23C26.761,23 29,20.761 29,18C29,15.239 26.761,13 24,13C21.239,13 19,15.239 19,18C19,20.761 21.239,23 24,23Z" |
| | | android:strokeLineJoin="round" |
| | | android:strokeWidth="4" |
| | | android:fillColor="#00000000" |
| | | android:strokeColor="#333"/> |
| | | <path |
| | | android:pathData="M10.022,38.332C10.366,33.121 14.702,29 20,29H28C33.291,29 37.623,33.11 37.977,38.311" |
| | | android:strokeLineJoin="round" |
| | | android:strokeWidth="4" |
| | | android:fillColor="#00000000" |
| | | android:strokeColor="#333" |
| | | android:strokeLineCap="round"/> |
| | | </vector> |
New file |
| | |
| | | <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="M24,44C35.046,44 44,35.046 44,24C44,12.954 35.046,4 24,4C12.954,4 4,12.954 4,24C4,35.046 12.954,44 24,44Z" |
| | | android:strokeLineJoin="round" |
| | | android:strokeWidth="4" |
| | | android:fillColor="#00000000" |
| | | android:fillType="evenOdd" |
| | | android:strokeColor="#fff" |
| | | android:strokeLineCap="round"/> |
| | | <path |
| | | android:pathData="M24,23C26.761,23 29,20.761 29,18C29,15.239 26.761,13 24,13C21.239,13 19,15.239 19,18C19,20.761 21.239,23 24,23Z" |
| | | android:strokeLineJoin="round" |
| | | android:strokeWidth="4" |
| | | android:fillColor="#00000000" |
| | | android:strokeColor="#fff"/> |
| | | <path |
| | | android:pathData="M10.022,38.332C10.366,33.121 14.702,29 20,29H28C33.291,29 37.623,33.11 37.977,38.311" |
| | | android:strokeLineJoin="round" |
| | | android:strokeWidth="4" |
| | | android:fillColor="#00000000" |
| | | android:strokeColor="#fff" |
| | | android:strokeLineCap="round"/> |
| | | </vector> |
New file |
| | |
| | | <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="M33.05,7H38C39.105,7 40,7.895 40,9V42C40,43.105 39.105,44 38,44H10C8.895,44 8,43.105 8,42L8,9C8,7.895 8.895,7 10,7H16H17V10H31V7H33.05Z" |
| | | android:strokeLineJoin="round" |
| | | android:strokeWidth="4" |
| | | android:fillColor="#00000000" |
| | | android:strokeColor="#333"/> |
| | | <path |
| | | android:pathData="M17,4h14v6h-14z" |
| | | android:strokeLineJoin="round" |
| | | android:strokeWidth="4" |
| | | android:fillColor="#00000000" |
| | | android:strokeColor="#333" |
| | | android:strokeLineCap="round"/> |
| | | <path |
| | | android:pathData="M27,19L19,27.001H29.004L21,35.002" |
| | | android:strokeLineJoin="round" |
| | | android:strokeWidth="4" |
| | | android:fillColor="#00000000" |
| | | android:strokeColor="#333" |
| | | android:strokeLineCap="round"/> |
| | | </vector> |
New file |
| | |
| | | <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="M33.05,7H38C39.105,7 40,7.895 40,9V42C40,43.105 39.105,44 38,44H10C8.895,44 8,43.105 8,42L8,9C8,7.895 8.895,7 10,7H16H17V10H31V7H33.05Z" |
| | | android:strokeLineJoin="round" |
| | | android:strokeWidth="4" |
| | | android:fillColor="#00000000" |
| | | android:strokeColor="#ffffff"/> |
| | | <path |
| | | android:pathData="M17,4h14v6h-14z" |
| | | android:strokeLineJoin="round" |
| | | android:strokeWidth="4" |
| | | android:fillColor="#00000000" |
| | | android:strokeColor="#fff" |
| | | android:strokeLineCap="round"/> |
| | | <path |
| | | android:pathData="M27,19L19,27.001H29.004L21,35.002" |
| | | android:strokeLineJoin="round" |
| | | android:strokeWidth="4" |
| | | android:fillColor="#00000000" |
| | | android:strokeColor="#fff" |
| | | android:strokeLineCap="round"/> |
| | | </vector> |
New file |
| | |
| | | <vector android:height="24dp" android:tint="#FFFFFF" |
| | | android:viewportHeight="24" android:viewportWidth="24" |
| | | android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> |
| | | <path android:fillColor="@android:color/white" android:pathData="M12,2C6.49,2 2,6.49 2,12s4.49,10 10,10 10,-4.49 10,-10S17.51,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM15,12c0,1.66 -1.34,3 -3,3s-3,-1.34 -3,-3 1.34,-3 3,-3 3,1.34 3,3z"/> |
| | | </vector> |
New file |
| | |
| | | <vector android:height="24dp" android:tint="#CCCCCC" |
| | | android:viewportHeight="24" android:viewportWidth="24" |
| | | android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> |
| | | <path android:fillColor="@android:color/white" android:pathData="M9,11L7,11v2h2v-2zM13,11h-2v2h2v-2zM17,11h-2v2h2v-2zM19,4h-1L18,2h-2v2L8,4L8,2L6,2v2L5,4c-1.11,0 -1.99,0.9 -1.99,2L3,20c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,6c0,-1.1 -0.9,-2 -2,-2zM19,20L5,20L5,9h14v11z"/> |
| | | </vector> |
New file |
| | |
| | | <vector android:height="24dp" android:tint="#CCCCCC" |
| | | android:viewportHeight="24" android:viewportWidth="24" |
| | | android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> |
| | | <path android:fillColor="@android:color/white" android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/> |
| | | </vector> |
New file |
| | |
| | | <vector xmlns:android="http://schemas.android.com/apk/res/android" |
| | | android:width="24dp" |
| | | android:height="24dp" |
| | | android:viewportWidth="24" |
| | | android:viewportHeight="24" |
| | | android:tint="?attr/colorControlNormal"> |
| | | <path |
| | | android:fillColor="@android:color/white" |
| | | android:pathData="M12,10.9c-0.61,0 -1.1,0.49 -1.1,1.1s0.49,1.1 1.1,1.1c0.61,0 1.1,-0.49 1.1,-1.1s-0.49,-1.1 -1.1,-1.1zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM14.19,14.19L6,18l3.81,-8.19L18,6l-3.81,8.19z"/> |
| | | </vector> |
New file |
| | |
| | | <vector android:height="24dp" android:tint="#FFFFFF" |
| | | android:viewportHeight="24" android:viewportWidth="24" |
| | | android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> |
| | | <path android:fillColor="@android:color/white" android:pathData="M19,3L5,3c-1.1,0 -2,0.9 -2,2v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM14,17L7,17v-2h7v2zM17,13L7,13v-2h10v2zM17,9L7,9L7,7h10v2z"/> |
| | | </vector> |
New file |
| | |
| | | <vector android:height="24dp" android:tint="#FFFFFF" |
| | | android:viewportHeight="24" android:viewportWidth="24" |
| | | android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> |
| | | <path android:fillColor="@android:color/white" android:pathData="M12,2C8.14,2 5,5.14 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.86 -3.14,-7 -7,-7zM16,10h-3v3h-2v-3L8,10L8,8h3L11,5h2v3h3v2z"/> |
| | | </vector> |
New file |
| | |
| | | <vector android:height="24dp" android:tint="#606060" |
| | | android:viewportHeight="24" android:viewportWidth="24" |
| | | android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> |
| | | <path android:fillColor="@android:color/white" android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z"/> |
| | | </vector> |
New file |
| | |
| | | <vector android:height="24dp" android:tint="#FFFFFF" |
| | | android:viewportHeight="24" android:viewportWidth="24" |
| | | android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> |
| | | <path android:fillColor="@android:color/white" android:pathData="M12,4L12,1L8,5l4,4L12,6c3.31,0 6,2.69 6,6 0,1.01 -0.25,1.97 -0.7,2.8l1.46,1.46C19.54,15.03 20,13.57 20,12c0,-4.42 -3.58,-8 -8,-8zM12,18c-3.31,0 -6,-2.69 -6,-6 0,-1.01 0.25,-1.97 0.7,-2.8L5.24,7.74C4.46,8.97 4,10.43 4,12c0,4.42 3.58,8 8,8v3l4,-4 -4,-4v3z"/> |
| | | </vector> |
New file |
| | |
| | | <vector android:height="10dp" android:tint="#D4D4D6" |
| | | android:viewportHeight="24" android:viewportWidth="24" |
| | | android:width="10dp" xmlns:android="http://schemas.android.com/apk/res/android"> |
| | | <path android:fillColor="@android:color/white" android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"/> |
| | | <path android:fillColor="@android:color/white" android:pathData="M9,2L7.17,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2L9,2zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z"/> |
| | | </vector> |
New file |
| | |
| | | <vector xmlns:android="http://schemas.android.com/apk/res/android" |
| | | android:width="24dp" |
| | | android:height="24dp" |
| | | android:viewportWidth="24" |
| | | android:viewportHeight="24" |
| | | android:tint="?attr/colorControlNormal"> |
| | | <path |
| | | android:fillColor="@android:color/white" |
| | | android:pathData="M15,1L9,1v2h6L15,1zM11,14h2L13,8h-2v6zM19.03,7.39l1.42,-1.42c-0.43,-0.51 -0.9,-0.99 -1.41,-1.41l-1.42,1.42C16.07,4.74 14.12,4 12,4c-4.97,0 -9,4.03 -9,9s4.02,9 9,9 9,-4.03 9,-9c0,-2.12 -0.74,-4.07 -1.97,-5.61zM12,20c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7z"/> |
| | | </vector> |
| | |
| | | <?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" |
| | | xmlns:tools="http://schemas.android.com/tools" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" |
| | |
| | | android:id="@+id/viewPager" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" |
| | | android:layout_above="@id/tabLayout" /> |
| | | android:layout_above="@id/bottom_navigation" /> |
| | | |
| | | |
| | | <com.google.android.material.tabs.TabLayout |
| | | android:id="@+id/tabLayout" |
| | | <LinearLayout |
| | | android:id="@+id/bottom_navigation" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="wrap_content" |
| | | android:layout_height="70dp" |
| | | android:layout_alignParentBottom="true" |
| | | android:background="?attr/colorPrimary" |
| | | app:tabGravity="fill" |
| | | app:tabIndicatorColor="#FFC107" |
| | | app:tabMode="fixed" |
| | | app:tabSelectedTextColor="#FFC107" |
| | | app:tabTextColor="#000000"> |
| | | android:layout_marginTop="-20dp" |
| | | android:background="#00ffffff" |
| | | android:gravity="bottom" |
| | | android:orientation="horizontal"> |
| | | |
| | | <!-- <com.google.android.material.tabs.TabItem--> |
| | | <!-- android:layout_width="match_parent"--> |
| | | <!-- android:layout_height="match_parent"--> |
| | | <!-- android:text="首页" />--> |
| | | <LinearLayout |
| | | android:id="@+id/orderLL" |
| | | android:layout_width="0dp" |
| | | android:layout_height="50dp" |
| | | android:layout_weight="1" |
| | | android:background="@color/bottom_color" |
| | | android:gravity="center" |
| | | android:orientation="vertical"> |
| | | |
| | | <!-- <com.google.android.material.tabs.TabItem--> |
| | | <!-- android:layout_width="match_parent"--> |
| | | <!-- android:layout_height="match_parent"--> |
| | | <!-- android:text="地图" />--> |
| | | <ImageView |
| | | android:id="@+id/orderImg" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="25dp" |
| | | android:layout_marginTop="8dp" |
| | | android:src="@drawable/bottom_order_black" /> |
| | | |
| | | <!-- <com.google.android.material.tabs.TabItem--> |
| | | <!-- android:layout_width="match_parent"--> |
| | | <!-- android:layout_height="match_parent"--> |
| | | <!-- android:text="我的" />--> |
| | | </com.google.android.material.tabs.TabLayout> |
| | | <TextView |
| | | android:id="@+id/orderText" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:layout_marginBottom="3dp" |
| | | android:text="工单" |
| | | android:textSize="12sp" /> |
| | | |
| | | </LinearLayout> |
| | | |
| | | <FrameLayout |
| | | android:id="@+id/mapLL" |
| | | android:layout_width="0dp" |
| | | android:layout_height="match_parent" |
| | | android:layout_weight="1" |
| | | android:gravity="bottom" |
| | | android:orientation="vertical"> |
| | | |
| | | <View |
| | | android:layout_width="match_parent" |
| | | android:layout_height="50dp" |
| | | android:layout_gravity="bottom" |
| | | android:background="@color/bottom_color" |
| | | android:orientation="vertical" /> |
| | | |
| | | <LinearLayout |
| | | android:layout_width="80dp" |
| | | android:layout_height="70dp" |
| | | android:layout_gravity="center" |
| | | android:background="@drawable/bottom_circle_bg" |
| | | android:gravity="center" |
| | | android:orientation="vertical"> |
| | | |
| | | <ImageView |
| | | android:id="@+id/mapImg" |
| | | android:layout_width="40dp" |
| | | android:layout_height="40dp" |
| | | android:layout_marginTop="8dp" |
| | | android:src="@drawable/bottom_map_white" /> |
| | | |
| | | <TextView |
| | | android:id="@+id/mapText" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:text="地图" |
| | | android:textColor="@color/white" |
| | | android:textSize="15sp" /> |
| | | |
| | | </LinearLayout> |
| | | |
| | | </FrameLayout> |
| | | |
| | | <LinearLayout |
| | | android:id="@+id/myLL" |
| | | android:layout_width="0dp" |
| | | android:layout_height="50dp" |
| | | android:layout_weight="1" |
| | | android:background="@color/bottom_color" |
| | | android:gravity="center" |
| | | android:orientation="vertical"> |
| | | |
| | | <ImageView |
| | | android:id="@+id/myImg" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="25dp" |
| | | android:layout_marginTop="8dp" |
| | | android:src="@drawable/bottom_my_black" /> |
| | | |
| | | <TextView |
| | | android:id="@+id/myText" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | android:layout_marginBottom="3dp" |
| | | android:text="我的" |
| | | android:textSize="12sp" /> |
| | | |
| | | </LinearLayout> |
| | | |
| | | </LinearLayout> |
| | | |
| | | |
| | | <!-- <!– BottomNavigationView 用于底部导航 –>--> |
| | | <!-- <com.google.android.material.bottomnavigation.BottomNavigationView--> |
| | | <!-- android:id="@+id/bottom_navigation"--> |
| | | <!-- android:layout_width="match_parent"--> |
| | | <!-- android:layout_height="wrap_content"--> |
| | | <!-- android:layout_alignParentBottom="true"--> |
| | | <!-- android:background="@color/bottom_color"--> |
| | | <!-- app:menu="@menu/main_bottom_nav_menu"--> |
| | | <!-- app:itemIconTint="@color/bottom_selector_nav_item"--> |
| | | <!-- app:itemTextColor="@color/bottom_selector_nav_item"--> |
| | | |
| | | <!-- />--> |
| | | |
| | | |
| | | </RelativeLayout> |
| | |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent"> |
| | | |
| | | <com.github.lzyzsd.jsbridge.BridgeWebView |
| | | android:id="@+id/webView" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" /> |
| | | |
| | | <!-- <com.github.lzyzsd.jsbridge.BridgeWebView--> |
| | | <!-- android:id="@+id/webView"--> |
| | | <!-- android:layout_width="match_parent"--> |
| | | <!-- android:layout_height="match_parent" />--> |
| | | <WebView |
| | | android:id="@+id/webView" |
| | | android:layout_width="match_parent" |
| | | android:layout_height="match_parent" /> |
| | | |
| | | <TextView |
| | | android:id="@+id/flyBtn" |
| | |
| | | android:id="@+id/tv_title_middle" |
| | | android:layout_width="wrap_content" |
| | | android:layout_height="wrap_content" |
| | | |
| | | android:layout_centerInParent="true" |
| | | android:textColor="@color/white" |
| | | android:textSize="@dimen/title_center_text_size" /> |
New file |
| | |
| | | <?xml version="1.0" encoding="utf-8"?> |
| | | <menu xmlns:android="http://schemas.android.com/apk/res/android"> |
| | | |
| | | <item |
| | | android:id="@+id/navigation_order" |
| | | android:icon="@drawable/bottom_order_black" |
| | | android:title="工单"/> |
| | | |
| | | <item |
| | | android:id="@+id/navigation_map" |
| | | android:icon="@drawable/bottom_map_black" |
| | | android:title="地图"/> |
| | | |
| | | <item |
| | | android:id="@+id/navigation_profile" |
| | | android:icon="@drawable/bottom_my_black" |
| | | android:title="我的"/> |
| | | </menu> |
| | |
| | | <color name="title_color">#1890FF</color> |
| | | <color name="bg_color">#F5F5F5</color> |
| | | <color name="grey">#757575</color> |
| | | <color name="colorSelected">#ffffff</color> |
| | | <color name="colorUnselected">#000000</color> |
| | | <color name="bottom_color">#1890FF</color> |
| | | </resources> |
| | |
| | | <dimen name="my_item_text_size">17sp</dimen> |
| | | <dimen name="common_btn_text_size">20sp</dimen> |
| | | <dimen name="title_height">45dp</dimen> |
| | | <dimen name="title_center_text_size">18sp</dimen> |
| | | </resources> |