From a1a032391e8af7eec01fde25a02d80dfde17661c Mon Sep 17 00:00:00 2001 From: xiaowusky Date: Thu, 6 Jul 2023 17:46:12 +0800 Subject: [PATCH] =?UTF-8?q?desc:=E6=B0=94=E4=BD=93=E6=B5=93=E5=BA=A6?= =?UTF-8?q?=E6=8A=98=E7=BA=BF=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 2 + app/src/main/AndroidManifest.xml | 8 + .../safetywatcher/watcher/ui/ChartActivity.kt | 161 ++++++++++++++++++ .../watcher/ui/GasListActivity.kt | 44 +++++ .../watcher/ui/QueryDataActivity.kt | 19 ++- .../watcher/ui/adapter/GasListAdapter.kt | 37 ++++ .../watcher/utils/ChartBridge.kt | 26 +++ app/src/main/res/layout/activity_chart.xml | 21 +++ app/src/main/res/layout/layout_item_gas.xml | 17 ++ app/src/main/res/values/strings.xml | 2 + build.gradle | 1 + 11 files changed, 336 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/yinuo/safetywatcher/watcher/ui/ChartActivity.kt create mode 100644 app/src/main/java/com/yinuo/safetywatcher/watcher/ui/GasListActivity.kt create mode 100644 app/src/main/java/com/yinuo/safetywatcher/watcher/ui/adapter/GasListAdapter.kt create mode 100644 app/src/main/java/com/yinuo/safetywatcher/watcher/utils/ChartBridge.kt create mode 100644 app/src/main/res/layout/activity_chart.xml create mode 100644 app/src/main/res/layout/layout_item_gas.xml diff --git a/app/build.gradle b/app/build.gradle index 7ad4604..7f379c8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -67,4 +67,6 @@ dependencies { implementation 'com.google.android.material:material:1.5.0' annotationProcessor 'androidx.lifecycle:lifecycle-compiler:2.0.0' + + implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3eed49f..a3b2e5c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -114,6 +114,14 @@ android:screenOrientation="landscape" android:exported="false" android:theme="@style/FullscreenTheme" /> + + \ No newline at end of file diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/ChartActivity.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/ChartActivity.kt new file mode 100644 index 0000000..68cfe4c --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/ChartActivity.kt @@ -0,0 +1,161 @@ +package com.yinuo.safetywatcher.watcher.ui + +import android.graphics.Color +import android.view.KeyEvent +import android.view.View +import com.common.commonlib.db.entity.Gas +import com.github.mikephil.charting.components.XAxis +import com.github.mikephil.charting.data.Entry +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet +import com.github.mikephil.charting.formatter.IndexAxisValueFormatter +import com.yinuo.safetywatcher.R +import com.yinuo.safetywatcher.databinding.ActivityChartBinding +import com.yinuo.safetywatcher.watcher.base.NoOptionsActivity +import com.yinuo.safetywatcher.watcher.utils.ChartBridge +import java.text.SimpleDateFormat +import java.util.Locale + + +class ChartActivity : NoOptionsActivity() { + private val mBinding: ActivityChartBinding by lazy { + ActivityChartBinding.inflate(layoutInflater) + } + + override fun getTopBarTitle(): String { + return getString(R.string.chart) + } + + override fun generateContentView(): View { + return mBinding.root + } + + private val dataFormat = SimpleDateFormat("MM/dd HH:mm:ss", Locale.ROOT) + + var mSelectGas: String? = "" + var mGases: List? = null + private var mXPositionIndex = 0 + var mXScale = 5f + private val pointCountPerPage = 8 + + override fun initView() { + initData() + setKeyControl() + setChartView() + setXAxis() + setData() + } + + private fun initData() { + mSelectGas = ChartBridge.getSelectGas() + val mapData = ChartBridge.getMapData() + mGases = mapData?.get(mSelectGas) + } + + private fun setKeyControl() { + mBinding.container.setOnKeyListener { v, keyCode, event -> + if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT && event.action == KeyEvent.ACTION_DOWN) { + // 获取图标Matrix参数 + if (mXPositionIndex < mXScale - 1) { + mXPositionIndex++ + // 获取图标Matrix参数 + val mMatrix = mBinding.chart.viewPortHandler.matrixTouch + // 设置平移距离(这里是平移到图标的最右边) + val distance: Float = mBinding.chart.contentRect.width() * (mXPositionIndex) + mMatrix.setTranslate(-distance, 0f) + //两个参数分别是x,y轴的缩放比例。 + mMatrix.preScale(mXScale, 1f) + // 刷新 + mBinding.chart.viewPortHandler.refresh(mMatrix, mBinding.chart, true) + return@setOnKeyListener true + } + } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT && event.action == KeyEvent.ACTION_DOWN) { + // 获取图标Matrix参数 + if (mXPositionIndex > 0) { + mXPositionIndex-- + // 获取图标Matrix参数 + val mMatrix = mBinding.chart.viewPortHandler.matrixTouch + // 设置平移距离(这里是平移到图标的最右边) + val distance: Float = mBinding.chart.contentRect.width() * (mXPositionIndex) + mMatrix.setTranslate(-distance, 0f) + //两个参数分别是x,y轴的缩放比例。 + mMatrix.preScale(mXScale, 1f) + // 刷新 + mBinding.chart.viewPortHandler.refresh(mMatrix, mBinding.chart, true) + return@setOnKeyListener true + } + } + return@setOnKeyListener false + } + } + + private fun setChartView() { + mBinding.chart.apply { + // disable description text + description.isEnabled = false + // enable touch gestures + setTouchEnabled(true) + setDrawGridBackground(false) + isScaleYEnabled = false + + legend.isEnabled = false + } + } + + private fun setXAxis() { + mBinding.chart.apply { + xAxis.apply { + position = XAxis.XAxisPosition.BOTTOM + textColor = Color.WHITE + textSize = 16f + + setLabelCount((pointCountPerPage + 1).toInt(), true) + setVisibleXRangeMaximum(pointCountPerPage.toFloat()) + granularity = 1f; // 设置X轴坐标之间的最小间隔 + valueFormatter = object : IndexAxisValueFormatter() { + override fun getFormattedValue(value: Float): String { + if (value < (mGases?.size ?: 0)) { + val baseTime = mGases?.get(value.toInt())?.time + return dataFormat.format(baseTime) + } + return "" + } + } + } + + axisRight.isEnabled = false + axisLeft.textColor = Color.WHITE + axisLeft.textSize = 20f + } + } + + private fun setData() { + mBinding.chart.apply { + //设置数据 + val entries = arrayListOf() + mGases?.forEachIndexed { index, gas -> + entries.add(Entry(index.toFloat(), gas.gasValue.toFloat())) + } + //一个LineDataSet就是一条线 + val lineDataSet = LineDataSet(entries, mSelectGas); + lineDataSet.valueTextColor = Color.WHITE + lineDataSet.valueTextSize = 20f + lineDataSet.color = Color.GREEN + + val index = entries.size - 1 + val scale = if (index % pointCountPerPage == 0) ( + index / pointCountPerPage + ) else ( + (index + pointCountPerPage) / pointCountPerPage + ) + mBinding.chart.xAxis.axisMaximum = (scale * pointCountPerPage).toFloat() + mXScale = scale.toFloat() + val data = LineData(lineDataSet); + setData(data) + + val mMatrix = mBinding.chart.viewPortHandler.matrixTouch + mMatrix.postScale(mXScale, 1f);//两个参数分别是x,y轴的缩放比例。例如:将x轴的数据放大为之前的1.5倍 + mBinding.chart.viewPortHandler.refresh(mMatrix, this, false) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/GasListActivity.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/GasListActivity.kt new file mode 100644 index 0000000..fc2840c --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/GasListActivity.kt @@ -0,0 +1,44 @@ +package com.yinuo.safetywatcher.watcher.ui + +import android.view.View +import androidx.recyclerview.widget.LinearLayoutManager +import com.yinuo.safetywatcher.R +import com.yinuo.safetywatcher.databinding.ActivitySensorBinding +import com.yinuo.safetywatcher.watcher.base.NoOptionsActivity +import com.yinuo.safetywatcher.watcher.ui.adapter.GasListAdapter +import com.yinuo.safetywatcher.watcher.utils.ChartBridge + +class GasListActivity : NoOptionsActivity() { + + private val mBingding by lazy { + ActivitySensorBinding.inflate(layoutInflater) + } + + private val mAdapter by lazy { + GasListAdapter() + } + + override fun getTopBarTitle(): String? { + return getString(R.string.gas_list) + } + + override fun generateContentView(): View { + return mBingding.root + } + + override fun initView() { + mBingding.rvSensor.layoutManager = LinearLayoutManager(this@GasListActivity) + mBingding.rvSensor.adapter = mAdapter + + queryData() + } + + private fun queryData() { + val mapData = ChartBridge.getMapData() + val list = arrayListOf() + mapData?.forEach { (t, u) -> + list.add(t) + } + mAdapter.setData(list) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/QueryDataActivity.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/QueryDataActivity.kt index 1940103..9730b5b 100644 --- a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/QueryDataActivity.kt +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/QueryDataActivity.kt @@ -1,6 +1,7 @@ package com.yinuo.safetywatcher.watcher.ui import android.annotation.SuppressLint +import android.content.Intent import android.view.View import androidx.activity.result.contract.ActivityResultContracts import androidx.lifecycle.lifecycleScope @@ -15,6 +16,7 @@ import com.yinuo.safetywatcher.watcher.constant.DEFAULT_QUERY_TIME_INTERVAL import com.yinuo.safetywatcher.watcher.constant.TimeStep import com.yinuo.safetywatcher.watcher.ui.adapter.HistoryDataAdapter import com.yinuo.safetywatcher.watcher.ui.view.CommonTopBar +import com.yinuo.safetywatcher.watcher.utils.ChartBridge import com.yinuo.safetywatcher.watcher.utils.DateUtils import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -25,11 +27,22 @@ class QueryDataActivity : BaseActivity() { ActivityQueryDataBinding.inflate(layoutInflater) } + private var mGasNewMap: HashMap>? = null + override fun onOptionClick(type: Int, target: View) { if (0 == type) { queryData() } else if (1 == type) { doExportData() + } else if (2 == type) { + goToChartPage() + } + } + + private fun goToChartPage() { + mGasNewMap?.let { + ChartBridge.setMapData(it) + startActivity(Intent(this@QueryDataActivity, GasListActivity::class.java)) } } @@ -37,6 +50,7 @@ class QueryDataActivity : BaseActivity() { val ops = mutableListOf() ops.add(CommonTopBar.Option(0, getString(R.string.search))) ops.add(CommonTopBar.Option(1, getString(R.string.export))) + ops.add(CommonTopBar.Option(2, getString(R.string.chart))) return ops } @@ -184,11 +198,12 @@ class QueryDataActivity : BaseActivity() { } } } - - val newList = mutableListOf() + mGasNewMap = gasNewMap + var newList = mutableListOf() gasNewMap.forEach { (t, u) -> newList.addAll(u) } + newList = newList.filter { it.gasValue >= 0.0 } as MutableList newList.sortWith { o1, o2 -> (o2.time - o1.time).toInt() } diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/adapter/GasListAdapter.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/adapter/GasListAdapter.kt new file mode 100644 index 0000000..513f001 --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/ui/adapter/GasListAdapter.kt @@ -0,0 +1,37 @@ +package com.yinuo.safetywatcher.watcher.ui.adapter + +import android.content.Intent +import android.view.LayoutInflater +import android.view.ViewGroup +import com.yinuo.safetywatcher.databinding.LayoutItemGasBinding +import com.yinuo.safetywatcher.watcher.base.BaseRvAdapter +import com.yinuo.safetywatcher.watcher.ui.ChartActivity +import com.yinuo.safetywatcher.watcher.ui.SensorSettingActivity +import com.yinuo.safetywatcher.watcher.utils.ChartBridge + +class GasListAdapter : + BaseRvAdapter() { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SensorViewHolder { + return SensorViewHolder( + LayoutItemGasBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + ); + } + + class SensorViewHolder(private val binding: LayoutItemGasBinding) : + BaseViewHolder(binding) { + + override fun bindView(data: String) { + val context = binding.root.context + binding.root.setOnClickListener { + ChartBridge.setSelectGas(data) + context.startActivity(Intent(context, ChartActivity::class.java)) + } + binding.gasName.text = data + } + } +} diff --git a/app/src/main/java/com/yinuo/safetywatcher/watcher/utils/ChartBridge.kt b/app/src/main/java/com/yinuo/safetywatcher/watcher/utils/ChartBridge.kt new file mode 100644 index 0000000..13df9af --- /dev/null +++ b/app/src/main/java/com/yinuo/safetywatcher/watcher/utils/ChartBridge.kt @@ -0,0 +1,26 @@ +package com.yinuo.safetywatcher.watcher.utils + +import com.common.commonlib.db.entity.Gas +import java.util.HashMap + +object ChartBridge { + + private var mGasNewMap: HashMap>? = null + private var mSelectGas:String? = null + + fun setMapData(it: HashMap>) { + mGasNewMap = it + } + + fun getMapData(): HashMap>? { + return mGasNewMap + } + + fun setSelectGas(data: String) { + mSelectGas = data + } + + fun getSelectGas(): String? { + return mSelectGas + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_chart.xml b/app/src/main/res/layout/activity_chart.xml new file mode 100644 index 0000000..03724a8 --- /dev/null +++ b/app/src/main/res/layout/activity_chart.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/layout_item_gas.xml b/app/src/main/res/layout/layout_item_gas.xml new file mode 100644 index 0000000..c1be0cf --- /dev/null +++ b/app/src/main/res/layout/layout_item_gas.xml @@ -0,0 +1,17 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 82c843a..0b0b62a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -26,6 +26,8 @@ 搜索 导出 + 折线图 + 气体列表 正常 离线 diff --git a/build.gradle b/build.gradle index b5d2f24..fbab203 100644 --- a/build.gradle +++ b/build.gradle @@ -3,6 +3,7 @@ buildscript { repositories { google() jcenter() + maven { url "https://jitpack.io" } } dependencies { classpath 'com.android.tools.build:gradle:7.1.2'