栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

串口通讯以及MPAndroidchart画图的使用(kotlin)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

串口通讯以及MPAndroidchart画图的使用(kotlin)

目录

一.Kotlin串口通讯实现... 2

1.1导入基础库... 2

1.2 效果展示... 3

1.3布局界面... 4

12.1 代码... 4

1.4 Activity实现代码... 9

13.1 实列化... 9

1.3.2 适配波特率以及获取本机串口号,进行串口监听... 9

二.MPAndroidChart图表使用... 13

2.1导入基础库... 13

2.1.1.引入开源库... 13

2.1.2在app根目录的buil.gradle文件中加入依赖... 13

2.2 LineChart曲线图... 14

2.2.1布局代码... 14

2.2.2 Activity实现代码... 14

2.3 BarChart柱状图... 23

2.3.1布局代码... 23

2.3.2 Activity实现代码... 23

2.4 曲线混合柱状图... 30

2.4.1布局代码... 30

2.4.2 Activity实现代码... 31

2.5 RadarChart雷达图... 32

2.5.1布局代码‘ 32

2.5.2 Activity实现代码... 32

2.6 PieChart饼状图... 35

2.6.1布局代码... 35

2.6.2 Activity实现代码... 35

三.单个房间温度图表显示功能实现... 36

3.1 效果展示... 36

3.2 数据库实现... 36

3.3布局代码... 36

3.4 Activity实现代码... 37

四.多个房间温度图表显示功能实现... 40

4.1 效果展示... 40

4.2布局代码... 41

4.3 Activity实现代码... 41

五.历史数据分析图显示功能实现... 46

5.1 效果展示... 47

5.2布局代码... 48

5.3 Activity实现代码... 51

一.Kotlin串口通讯实现

1.1导入基础库

1.为了方便大家。我把所有关于串口的资源打包成aar 文件,大家直接使用即可。

谷歌android串口开发 aar文件,地址如下所示:

使用过程

aar文件导入lib文件夹。

gradle文件

repositories {

        flatDir {

            dirs 'libs'

        }

    }
dependencies {

    implementation(name: 'serialport-1.0.1', ext: 'aar')

}

1.2 效果展示

1.3布局界面

12.1 代码






    



    



    

        

            

            

                



                

            

            

                

                    

                    

                    

                    

                

            

            

                

                    



                    

                    

                    



                

            

            

                

                    



                    



                

            





            

                

1.4 Activity实现代码

13.1 实列化
private var serialPortFinder: SerialPortFinder? = null

      private var serialHelper: SerialHelper? = null

       //局部变量

private val list = ArrayList>()

       var map: Map? = null

1.3.2 适配波特率以及获取本机串口号,进行串口监听

(1)适配器的编写

       名字:SpAdapter

public class SpAdapter extends baseAdapter {



    String[] datas;

    Context mContext;



    public SpAdapter(Context context) {

        this.mContext = context;

    }



    public void setDatas(String[] datas) {

        this.datas = datas;

        notifyDataSetChanged();

    }



    @Override

    public int getCount() {

        return datas == null ? 0 : datas.length;

    }



    @Override

    public Object getItem(int position) {

        return datas == null ? null : datas[position];

    }



    @Override

    public long getItemId(int position) {

        return position;

    }



    @Override

    public View getView(int position, View convertView, ViewGroup parent) {

        ViewHodler hodler = null;

        if (convertView == null) {

            hodler = new ViewHodler();

            convertView = LayoutInflater.from(mContext).inflate(R.layout.item_layout, null);

            hodler.mTextView = (TextView) convertView;

            convertView.setTag(hodler);

        } else {

            hodler = (ViewHodler) convertView.getTag();

        }



        hodler.mTextView.setText(datas[position]);



        return convertView;

    }



    private static class ViewHodler {

        TextView mTextView;

    }

}

  
(2)适配代码

serialPortFinder = SerialPortFinder()

        //获取串口地址

        val ports = serialPortFinder!!.allDevicesPath

        //设置波特率地址

        val botes = arrayOf(

            "0",

            "50",

            "75",

            "110",

            "134",

            "150",

            "200",

            "300",

            "600",

            "1200",

            "1800",

            "2400",

            "4800",

            "9600",

            "19200",

            "38400",

            "57600",

            "115200",

            "230400",

            "460800",

            "500000",

            "576000",

            "921600",

            "1000000",

            "1152000",

            "1500000",

            "2000000",

            "2500000",

            "3000000",

            "3500000",

            "4000000"

        )

        val spAdapter = SpAdapter(this)

        

        spAdapter.setDatas(ports)

        binding.spSerial.adapter = spAdapter

        binding.spSerial.onItemSelectedListener = object : onItemSelectedListener {

            override fun onItemSelected(

                parent: AdapterView<*>?,

                view: View,

                position: Int,

                id: Long

            ) {

                serialHelper?.close()



                serialHelper?.port = ports[position]



                binding.EditText1.setText(ports[position])

                binding.open.text = "关闭串口"



            }



            override fun onNothingSelected(parent: AdapterView<*>?) {}

        }

        

        val spAdapter2 = SpAdapter(this)

        spAdapter2.setDatas(botes)

        binding.spBote.adapter = spAdapter2

        binding.spBote.onItemSelectedListener = object : onItemSelectedListener {

            override fun onItemSelected(

                parent: AdapterView<*>?,

                view: View,

                position: Int,

                id: Long

            ) {

                serialHelper?.close()

                serialHelper?.setBaudRate(botes[position])

                binding.EditText2.setText(botes[position])

                binding.open.text = "关闭串口"



            }



            override fun onNothingSelected(parent: AdapterView<*>?) {}

        }

 
(3)开启串口监视


   serialHelper = object : SerialHelper() {

            override fun onDataReceived(comBean: ComBean) {

                runonUiThread {

//                    Toast.makeText(

//                        baseContext,

//                        FuncUtil.ByteArrToHex(comBean.bRec),

//                        Toast.LENGTH_SHORT

//                    ).show()

                    

                    map = HashMap()

                    (map as HashMap)["Value"] =comBean.sRecTime + ":   " +

                            ByteUtil.hexStringToString(ByteUtil.bytesToHexString(comBean.bRec))

                    list.add(map as HashMap)

                    Handler(Looper.getMainLooper()).postDelayed({

                        

                        if (list.size>12){

                            map = list[0]

                            list.remove(map)

                        }

                        initAdapter()

                    }, 300)

                }

            }

        }   

二.MPAndroidChart图表使用

2.1导入基础库



2.1.1.引入开源库

在项目根目录的build.gradle文件中加入如下代码

allprojects {

    repositories {

        maven { url "https://jitpack.io" }

    }



2.1.2在app根目录的buil.gradle文件中加入依赖

根据自己的需求添加对应的库文件

主要运用到的为下列两个开源库

api 'com.github.CymChad:baseRecyclerViewAdapterHelper:3.0.4'

//MPAndroidChart画图

    implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3'

dependencies {

//api表示对所有的module可见,如果没有在其他地方使用到版本号,则不用进行版本号的统一控制



    //使用开源的org.greenrobot.EventBus可以更好地维护事件处理

    api 'org.greenrobot:eventbus:3.0.0'

    //MultiDex,解决方法数超过65535限制

    api 'androidx.multidex:multidex:2.0.1'

    //leakcanary检测内存泄漏

    debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.4'

    //Kotlin

    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

    //RxJava

    api 'io.reactivex.rxjava2:rxandroid:2.1.0'

    api 'io.reactivex.rxjava2:rxjava:2.2.4'

    //侧滑返回框架

    api 'com.billy.android:smart-swipe:1.1.2'

    

    api 'com.gyf.immersionbar:immersionbar:3.0.0'

    

    api 'com.github.CymChad:baseRecyclerViewAdapterHelper:3.0.4'

    //下拉刷新框架

    api 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.2'

    //特殊Header

    api 'com.scwang.smartrefresh:SmartRefreshHeader:1.1.2'

    //MPAndroidChart画图

    implementation 'com.github.PhilJay:MPAndroidChart:v3.0.3'

    //底部选择器

    api 'com.contrarywind:Android-PickerView:4.1.8'

}

2.2 LineChart曲线图

2.2.1布局代码

2.2.2 Activity实现代码

1.写一个工具类以便我们使用

文件名:DynamicLineChartManager

public class DynamicLineChartManager {



    private LineChart lineChart;

    private YAxis leftAxis;

    private YAxis rightAxis;

    private XAxis xAxis;

    private LineData lineData;

    private LineDataSet lineDataSet;

    private List lineDataSets = new ArrayList<>();

    private SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");//设置日期格式

    private List timeList = new ArrayList<>(); //存储x轴的时间



    //一条曲线

    public DynamicLineChartManager(LineChart mLineChart, String name, int color) {

        this.lineChart = mLineChart;

        leftAxis = lineChart.getAxisLeft();

        rightAxis = lineChart.getAxisRight();

        xAxis = lineChart.getXAxis();

        initLineChart();

        initLineDataSet(name, color);

    }

    //警告曲线

    public DynamicLineChartManager(LineChart mLineChart, String name, int color,float High, String warn,int warn_color) {

        this.lineChart = mLineChart;

        leftAxis = lineChart.getAxisLeft();

        rightAxis = lineChart.getAxisRight();

        xAxis = lineChart.getXAxis();

        initLineChart();

        initLineDataWarn(name, color,High,warn,warn_color);

    }

    //多条曲线

    public DynamicLineChartManager(LineChart mLineChart, List names, List colors) {

        this.lineChart = mLineChart;

        leftAxis = lineChart.getAxisLeft();

        rightAxis = lineChart.getAxisRight();

        xAxis = lineChart.getXAxis();

        initLineChart();

        initLineDataSet(names, colors);



    }



    

    private void initLineChart() {



        lineChart.setDrawGridBackground(false);

        //显示边界

        lineChart.setDrawBorders(true);

        //折线图例 标签 设置

        Legend legend = lineChart.getLegend();

        legend.setForm(Legend.LegendForm.LINE);

        legend.setTextSize(11f);

        //显示位置

        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);

        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);

        legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);

        legend.setDrawInside(false);



        //X轴设置显示位置在底部

        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);

        xAxis.setGranularity(1f);

        xAxis.setLabelCount(10);



        xAxis.setValueFormatter(new IAxisValueFormatter() {

            @Override

            public String getFormattedValue(float value, Axisbase axis) {

                return timeList.get((int) value % timeList.size());

            }

        });



        //保证Y轴从0开始,不然会上移一点

        leftAxis.setAxisMinimum(0f);

        rightAxis.setAxisMinimum(0f);

    }



    

    private void initLineDataWarn(String name, int color,float High, String warn,int warn_color) {



        lineDataSet = new LineDataSet(null, name);

        lineDataSet.setLineWidth(1.5f);

        lineDataSet.setCircleRadius(1.5f);

        lineDataSet.setColor(color);

        lineDataSet.setCircleColor(color);

        lineDataSet.setHighLightColor(color);

        //设置曲线填充

        lineDataSet.setDrawFilled(true);

        lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);

        lineDataSet.setValueTextSize(10f);

        lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);

        //添加一个空的 LineData

        lineData = new LineData();

        lineChart.setData(lineData);

        lineChart.invalidate();

        setHightLimitLine(High,warn, warn_color);

    }

    

    private void initLineDataSet(String name, int color) {



        lineDataSet = new LineDataSet(null, name);

        lineDataSet.setLineWidth(1.5f);

        lineDataSet.setCircleRadius(1.5f);

        lineDataSet.setColor(color);

        lineDataSet.setCircleColor(color);

        lineDataSet.setHighLightColor(color);

        //设置曲线填充

        lineDataSet.setDrawFilled(true);

        lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);

        lineDataSet.setValueTextSize(10f);

        lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);

        //添加一个空的 LineData

        lineData = new LineData();

        lineChart.setData(lineData);

        lineChart.invalidate();



    }



    

    private void initLineDataSet(List names, List colors) {



        for (int i = 0; i < names.size(); i++) {

            lineDataSet = new LineDataSet(null, names.get(i));

            lineDataSet.setColor(colors.get(i));

            lineDataSet.setLineWidth(1.5f);

            lineDataSet.setCircleRadius(1.5f);

            lineDataSet.setColor(colors.get(i));



            lineDataSet.setDrawFilled(true);

            lineDataSet.setCircleColor(colors.get(i));

            lineDataSet.setHighLightColor(colors.get(i));

            lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);

            lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);

            lineDataSet.setValueTextSize(10f);

            lineDataSets.add(lineDataSet);



        }

        //添加一个空的 LineData

        lineData = new LineData();

        lineChart.setData(lineData);

        lineChart.invalidate();

    }



    

    public void addEntry(Float number) {



        //最开始的时候才添加 lineDataSet(一个lineDataSet 代表一条线)

        if (lineDataSet.getEntryCount() == 0) {

            lineData.addDataSet(lineDataSet);

        }

        lineChart.setData(lineData);

        //避免集合数据过多,及时清空(做这样的处理,并不知道有没有用,但还是这样做了)

        if (timeList.size() > 11) {

            timeList.clear();

        }



        timeList.add(df.format(System.currentTimeMillis()));



        Entry entry = new Entry(lineDataSet.getEntryCount(), number);

        lineData.addEntry(entry, 0);

        //通知数据已经改变

        lineData.notifyDataChanged();

        lineChart.notifyDataSetChanged();

        //设置在曲线图中显示的最大数量

        lineChart.setVisibleXRangeMaximum(10);

        //移到某个位置

        lineChart.moveViewToX(lineData.getEntryCount() - 5);



    }

    

    public void HistoryEntry(Float number,String time,String str) {



        //最开始的时候才添加 lineDataSet(一个lineDataSet 代表一条线)

        if (lineDataSet.getEntryCount() == 0) {

            lineData.addDataSet(lineDataSet);

        }

        lineChart.setData(lineData);

        //避免集合数据过多,及时清空(做这样的处理,并不知道有没有用,但还是这样做了)

        if (timeList.size() > 100) {

            timeList.clear();

        }



        timeList.add(time);



        Entry entry = new Entry(lineDataSet.getEntryCount(), number);

        lineData.addEntry(entry, 0);

        //通知数据已经改变

        lineData.notifyDataChanged();

        lineChart.notifyDataSetChanged();

        //设置在曲线图中显示的最大数量

        lineChart.setVisibleXRangeMaximum(10);

        //移到某个位置

        lineChart.moveViewToX(lineData.getEntryCount() - 5);

        setDescription(str);

    }

    

    public void addEntry(List numbers) {



        if (lineDataSets.get(0).getEntryCount() == 0) {

            lineData = new LineData(lineDataSets);

            lineChart.setData(lineData);

        }

        if (timeList.size() > 11) {

            timeList.clear();

        }

        timeList.add(df.format(System.currentTimeMillis()));

        for (int i = 0; i < numbers.size(); i++) {

            Entry entry = new Entry(lineDataSet.getEntryCount(), numbers.get(i));

            lineData.addEntry(entry, i);

            lineData.notifyDataChanged();

            lineChart.notifyDataSetChanged();

            lineChart.setVisibleXRangeMaximum(6);

            lineChart.moveViewToX(lineData.getEntryCount() - 5);

        }

    }



    

    public void setYAxis(float max, float min, int labelCount) {

        if (max < min) {

            return;

        }

        leftAxis.setAxisMaximum(max);

        leftAxis.setAxisMinimum(min);

        leftAxis.setLabelCount(labelCount, false);



        rightAxis.setAxisMaximum(max);

        rightAxis.setAxisMinimum(min);

        rightAxis.setLabelCount(labelCount, false);

        lineChart.invalidate();

    }

    

    public void setHightLimitLine(float high, String name, int color) {

        if (name == null) {

            name = "高限制线";

        }

        LimitLine hightLimit = new LimitLine(high, name);

        hightLimit.setLineWidth(4f);

        hightLimit.setTextSize(10f);

        hightLimit.setLineColor(color);

        hightLimit.setTextColor(color);

        leftAxis.addLimitLine(hightLimit);

        lineChart.invalidate();

    }



    

    public void setLowLimitLine(int low, String name) {

        if (name == null) {

            name = "低限制线";

        }

        LimitLine hightLimit = new LimitLine(low, name);

        hightLimit.setLineWidth(4f);

        hightLimit.setTextSize(10f);

        leftAxis.addLimitLine(hightLimit);

        lineChart.invalidate();

    }



    

    public void setDescription(String str) {

        Description description = new Description();

        description.setText(str);

        description.setTextColor(Color.MAGENTA);

        description.setTextSize(15);



        lineChart.setDescription(description);

        lineChart.invalidate();

    }

}

2.在activity里面使用

(1)实列化工具类

private var dynamicLineChartManager1: DynamicLineChartManager? = null

局部数据



    private val list: MutableList = ArrayList() //数据集合



    private val names: MutableList = ArrayList() //折线名字集合



    private val colour: MutableList = ArrayList() //折线颜色集合

(2)添加局部数据以及实现曲线

//折线名字

        names.add("温度")

        names.add("压强")

        names.add("其他")

        //折线颜色

        colour.add(Color.CYAN)

        colour.add(Color.GREEN)

        colour.add(Color.BLUE)

//实现一条曲线

dynamicLineChartManager1 = DynamicLineChartManager(binding.dynamicChart1, names[0], colour[0])

      //实现多条曲线

        dynamicLineChartManager2 = DynamicLineChartManager(binding.dynamicChart2, names, colour)

(3)添加数据到曲线内

//添加一条曲线的数据

            dynamicLineChartManager1?.addEntry((Math.random() * 100).toFloat())

//添加多条曲线的数据

                    list.add((Math.random() * 50).toFloat() + 10)

                    list.add((Math.random() * 80).toFloat() + 10)

                    list.add((Math.random() * 100).toFloat())

                    dynamicLineChartManager2!!.addEntry(list)

                    list.clear()

2.3 BarChart柱状图

2.3.1布局代码

2.3.2 Activity实现代码

1.写一个工具类以便我们使用

类名字为:CombinedChartManager

public class CombinedChartManager {



    private CombinedChart mCombinedChart;

    private YAxis leftAxis;

    private YAxis rightAxis;

    private XAxis xAxis;



    public CombinedChartManager(CombinedChart combinedChart) {

        this.mCombinedChart = combinedChart;

        leftAxis = mCombinedChart.getAxisLeft();

        rightAxis = mCombinedChart.getAxisRight();

        xAxis = mCombinedChart.getXAxis();

    }



    

    private void initChart() {

        //不显示描述内容

        mCombinedChart.getDescription().setEnabled(false);



        mCombinedChart.setDrawOrder(new CombinedChart.DrawOrder[]{

                CombinedChart.DrawOrder.BAR,

                CombinedChart.DrawOrder.LINE

        });



        mCombinedChart.setBackgroundColor(Color.WHITE);

        mCombinedChart.setDrawGridBackground(false);

        mCombinedChart.setDrawBarShadow(false);

        mCombinedChart.setHighlightFullBarEnabled(false);

        //显示边界

        mCombinedChart.setDrawBorders(true);

        //图例说明

        Legend legend = mCombinedChart.getLegend();

        legend.setWordWrapEnabled(true);



        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);

        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);

        legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);

        legend.setDrawInside(false);

        //Y轴设置

        rightAxis.setDrawGridLines(false);

        rightAxis.setAxisMinimum(0f);



        leftAxis.setDrawGridLines(false);

        leftAxis.setAxisMinimum(0f);



        mCombinedChart.animateX(2000); // 立即执行的动画,x轴

    }



    

    public void setXAxis(final List xAxisValues) {



        //设置X轴在底部

        XAxis xAxis = mCombinedChart.getXAxis();

        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);

        xAxis.setGranularity(1f);



        xAxis.setLabelCount(xAxisValues.size() - 1,false);

        xAxis.setValueFormatter(new IAxisValueFormatter() {

            @Override

            public String getFormattedValue(float value, Axisbase axis) {

                return xAxisValues.get((int) value % xAxisValues.size());

            }

        });

        mCombinedChart.invalidate();

    }



    

    private LineData getLineData(List lineChartY, String lineName, int lineColor) {

        LineData lineData = new LineData();



        ArrayList yValue = new ArrayList<>();

        for (int i = 0; i < lineChartY.size(); i++) {

            yValue.add(new Entry(i, lineChartY.get(i)));

        }

        LineDataSet dataSet = new LineDataSet(yValue, lineName);



        dataSet.setColor(lineColor);

        dataSet.setCircleColor(lineColor);

        dataSet.setValueTextColor(lineColor);



        dataSet.setCircleSize(1);

        //显示值

        dataSet.setDrawValues(true);

        dataSet.setValueTextSize(10f);

        dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);

        dataSet.setAxisDependency(YAxis.AxisDependency.LEFT);

        lineData.addDataSet(dataSet);

        return lineData;

    }



    

    private LineData getLineData(List> lineChartYs, List lineNames, List lineColors) {

        LineData lineData = new LineData();



        for (int i = 0; i < lineChartYs.size(); i++) {

            ArrayList yValues = new ArrayList<>();

            for (int j = 0; j < lineChartYs.get(i).size(); j++) {

                yValues.add(new Entry(j, lineChartYs.get(i).get(j)));

            }

            LineDataSet dataSet = new LineDataSet(yValues, lineNames.get(i));

            dataSet.setColor(lineColors.get(i));

            dataSet.setCircleColor(lineColors.get(i));

            dataSet.setValueTextColor(lineColors.get(i));



            dataSet.setCircleSize(1);

            dataSet.setDrawValues(true);

            dataSet.setValueTextSize(10f);

            dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);

            dataSet.setAxisDependency(YAxis.AxisDependency.LEFT);

            lineData.addDataSet(dataSet);

        }

        return lineData;

    }



    



    private BarData getBarData(List barChartY, String barName, int barColor) {

        BarData barData = new BarData();

        ArrayList yValues = new ArrayList<>();

        for (int i = 0; i < barChartY.size(); i++) {

            yValues.add(new BarEntry(i, barChartY.get(i)));

        }



        BarDataSet barDataSet = new BarDataSet(yValues, barName);

        barDataSet.setColor(barColor);

        barDataSet.setValueTextSize(10f);

        barDataSet.setValueTextColor(barColor);

        barDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);

        barData.addDataSet(barDataSet);



        //以下是为了解决 柱状图 左右两边只显示了一半的问题 根据实际情况 而定

        xAxis.setAxisMinimum(-0.5f);

        xAxis.setAxisMaximum((float) (barChartY.size()- 0.5));

        return barData;

    }



    



    private BarData getBarData(List> barChartYs, List barNames, List barColors) {

        List lists = new ArrayList<>();

        for (int i = 0; i < barChartYs.size(); i++) {

            ArrayList entries = new ArrayList<>();



            for (int j = 0; j < barChartYs.get(i).size(); j++) {

                entries.add(new BarEntry(j, barChartYs.get(i).get(j)));

            }

            BarDataSet barDataSet = new BarDataSet(entries, barNames.get(i));



            barDataSet.setColor(barColors.get(i));

            barDataSet.setValueTextColor(barColors.get(i));

            barDataSet.setValueTextSize(10f);

            barDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);

            lists.add(barDataSet);

        }

        BarData barData = new BarData(lists);



        int amount = barChartYs.size(); //需要显示柱状图的类别 数量

        float groupSpace = 0.12f; //柱状图组之间的间距

        float barSpace = (float) ((1 - 0.12) / amount / 10); // x4 DataSet

        float barWidth = (float) ((1 - 0.12) / amount / 10 * 9); // x4 DataSet



        // (0.2 + 0.02) * 4 + 0.12 = 1.00 即100% 按照百分百布局

        //柱状图宽度

        barData.setBarWidth(barWidth);

        //(起始点、柱状图组间距、柱状图之间间距)

        barData.groupBars(0, groupSpace, barSpace);

        return barData;

    }



    



    public void showCombinedChart(

            List xAxisValues, List barChartY, List lineChartY

            , String barName, String lineName, int barColor, int lineColor) {

        initChart();

        setXAxis(xAxisValues);



        CombinedData combinedData = new CombinedData();



        combinedData.setData(getBarData(barChartY, barName, barColor));

        combinedData.setData(getLineData(lineChartY, lineName, lineColor));

        mCombinedChart.setData(combinedData);

        mCombinedChart.invalidate();

    }

    



    public void showbinedChart(

            List xAxisValues, List barChartY

            , String barName, int barColor) {

        initChart();

        setXAxis(xAxisValues);



        CombinedData combinedData = new CombinedData();



        combinedData.setData(getBarData(barChartY, barName, barColor));



        mCombinedChart.setData(combinedData);

        mCombinedChart.invalidate();

    }

    



    public void showCombinedChart(

            List xAxisValues, List> barChartYs, List> lineChartYs,

            List barNames, List lineNames, List barColors, List lineColors) {

        initChart();

        setXAxis(xAxisValues);



        CombinedData combinedData = new CombinedData();



        combinedData.setData(getBarData(barChartYs, barNames, barColors));

        combinedData.setData(getLineData(lineChartYs, lineNames, lineColors));



        mCombinedChart.setData(combinedData);

        mCombinedChart.invalidate();

    }

}

2在Activity里面使用



(1)添加局部数据以及实现曲线

       private fun intDate(){

        //x轴数据

        val xdata: MutableList = ArrayList()

        for (i in 0..20) {

            xData.add(i.toString())

        }

        //y轴数据集合

        val yBarDatas: MutableList> = ArrayList()

        //4种直方图

        for (i in 0..3) {

            //y轴数

            val ydata: MutableList = ArrayList()

            for (j in 0..20) {

                yData.add((Math.random() * 100).toFloat())

            }

            yBarDatas.add(yData)

        }

        //颜色集合

        val colors: MutableList = ArrayList()

        colors.add(Color.BLUE)

        colors.add(Color.RED)

        colors.add(Color.YELLOW)

        colors.add(Color.CYAN)



        //管理类

        val combineChartManager1 = CombinedChartManager(binding.chart1)



        combineChartManager1.showbinedChart(

            xData, yBarDatas.get(0),

            "直方图", colors.get(0)

        )

    }

2.4 曲线混合柱状图

2.4.1布局代码
  

2.4.2 Activity实现代码

1..实现混合显示(工具类已经提供)

private fun intDate(){

        //x轴数据

        val xdata: MutableList = ArrayList()

        for (i in 0..20) {

            xData.add(i.toString())

        }

        //y轴数据集合

        val yBarDatas: MutableList> = ArrayList()

        //4种直方图

        for (i in 0..3) {

            //y轴数

            val ydata: MutableList = ArrayList()

            for (j in 0..20) {

                yData.add((Math.random() * 100).toFloat())

            }

            yBarDatas.add(yData)

        }

        //y轴数据集合

        val yLineDatas: MutableList> = ArrayList()

        //4种直方图

        for (i in 0..3) {

            //y轴数

            val ydata: MutableList = ArrayList()

            for (j in 0..20) {

                yData.add((Math.random() * 100).toFloat())

            }

            yLineDatas.add(yData)

        }

        //名字集合

        val barNames: MutableList = ArrayList()

        barNames.add("直方图一")

        barNames.add("直方图二")

        barNames.add("直方图三")

        barNames.add("直方图四")

        //颜色集合

        val colors: MutableList = ArrayList()

        colors.add(Color.BLUE)

        colors.add(Color.RED)

        colors.add(Color.YELLOW)

        colors.add(Color.CYAN)

        //竖状图管理类

        val lineNames: MutableList = ArrayList()

        lineNames.add("折线图一")

        lineNames.add("折线图二")

        lineNames.add("折线图三")

        lineNames.add("折线图四")





        //管理类

        val combineChartManager1 = CombinedChartManager(binding.chart1)

        combineChartManager1.showCombinedChart(xData, yBarDatas.get(0), yLineDatas.get(0),

                "直方图", "线性图", colors.get(0), colors.get(1));



        val combineChartManager2 = CombinedChartManager(binding.chart2)

        combineChartManager2.showCombinedChart(

            xData, yBarDatas, yLineDatas, barNames, lineNames,

            colors, colors

        )



    }

2.5 RadarChart雷达图

2.5.1布局代码‘

2.5.2 Activity实现代码

1.实现代码

   fun radar(){

        val radar: RadarChart? = binding.radar

        var list: MutableList? = null

        var list2: MutableList? = null

        list = ArrayList()

        list2 = ArrayList()

        list.add(RadarEntry(30F))

        list.add(RadarEntry(35F))

        list.add(RadarEntry(40F))

        list.add(RadarEntry(35F))

        list.add(RadarEntry(20F))

        list2.add(RadarEntry(50F))

        list2.add(RadarEntry(45F))

        list2.add(RadarEntry(55F))

        list2.add(RadarEntry(40F))

        list2.add(RadarEntry(60F))

        val radarDataSet = RadarDataSet(list, "男性")

        radarDataSet.color = Color.RED

        val radarDataSet1 = RadarDataSet(list2, "女性")

        radarDataSet1.color = Color.BLUE

        val radarData = RadarData(radarDataSet)

        radarData.addDataSet(radarDataSet1)

        radar!!.data = radarData



        //Y轴最小值不设置会导致数据中最小值默认成为Y轴最小值

        radar.yAxis.axisMinimum = 0f



        //大字的颜色(中心点和各顶点的连线)

        radar.webColor = Color.CYAN

        //所有五边形的颜色

        radar.webColorInner = Color.CYAN

        //整个控件的背景颜色

        radar.setBackgroundColor(Color.LTGRAY)

        val xAxis = radar.xAxis

        xAxis.textColor = Color.RED //X轴字体颜色

        xAxis.textSize = 16f //X轴字体大小

        //自定义X轴坐标描述(也就是五个顶点上的文字,默认是0、1、2、3、4)

        xAxis.valueFormatter =

            IAxisValueFormatter { v, axisbase ->

                if (v == 0f) {

                    return@IAxisValueFormatter "语文"

                }

                if (v == 1f) {

                    return@IAxisValueFormatter "数学"

                }

                if (v == 2f) {

                    return@IAxisValueFormatter "英语"

                }

                if (v == 3f) {

                    return@IAxisValueFormatter "生物"

                }

                if (v == 4f) {

                    "地理"

                } else ""

            }





        //是否绘制雷达框上对每个点的数据的标注    和Y轴坐标点一般不同时存在 否则显得很挤  默认为true

        radarDataSet.setDrawValues(false)

        radarDataSet1.setDrawValues(false)

        radarDataSet.valueTextSize = 12f //数据值得字体大小(这里只是写在这)

        radarDataSet.valueTextColor = Color.CYAN //数据值得字体颜色(这里只是写在这)

        val yAxis = radar!!.yAxis

        //是否绘制Y轴坐标点  和雷达框数据一般不同时存在 否则显得很挤 默认为true

        yAxis.setDrawLabels(true)

        yAxis.textColor = Color.GRAY //Y轴坐标数据的颜色

        yAxis.axisMaximum = 80f //Y轴最大数值

        yAxis.axisMinimum = 0f //Y轴最小数值

        //Y轴坐标的个数    第二个参数一般填false     true表示强制设置标签数 可能会导致X轴坐标显示不全等问题

        yAxis.setLabelCount(10, false)





        //对于右下角一串字母的操作

        radar.description.isEnabled = false //是否显示右下角描述

        radar.description.text = "这是修改那串英文的方法" //修改右下角字母的显示

        radar.description.textSize = 20f //字体大小

        radar.description.textColor = Color.CYAN //字体颜色



        //图例

        val legend = radar.legend

        legend.isEnabled = true //是否显示图例

        legend.position = Legend.LegendPosition.BELOW_CHART_CENTER //图例的位置

    }

2.6 PieChart饼状图

2.6.1布局代码


        

2.6.2 Activity实现代码

1.实现代码

fun pie(){

        val pie: PieChart = binding.pie

        list = ArrayList()

        (list as ArrayList).add(PieEntry(56F, "男性"))

        (list as ArrayList).add(PieEntry(44F, "女性"))

        val pieDataSet = PieDataSet(list, "")

        val pieData = PieData(pieDataSet)

        pie.data = pieData

        pie.setBackgroundColor(Color.GRAY)



        //设置各个数据的颜色

        pieDataSet.setColors(Color.RED, Color.BLUE)

        //实体扇形的空心圆的半径   设置成0时就是一个圆 而不是一个环

        pie.holeRadius = 30f

        //中间半透明白色圆的半径    设置成0时就是隐藏

        pie.transparentCircleRadius = 30f

        //设置中心圆的颜色

        pie.setHoleColor(Color.CYAN)

        //设置中心部分的字  (一般中间白色圆不隐藏的情况下才设置)

        pie.centerText = "男女比例"

        //设置中心字的字体颜色

        pie.setCenterTextColor(Color.RED)

        //设置中心字的字体大小

        pie.setCenterTextSize(16f)

        //设置描述的字体大小(图中的  男性  女性)

        pie.setEntryLabelTextSize(20f)

        //设置数据的字体大小  (图中的  44     56)

        pieDataSet.valueTextSize = 20f

        //设置描述的位置

        pieDataSet.xValuePosition = PieDataSet.ValuePosition.OUTSIDE_SLICE

        pieDataSet.valueLinePart1Length = 0.6f //设置描述连接线长度

        //设置数据的位置

        pieDataSet.yValuePosition = PieDataSet.ValuePosition.OUTSIDE_SLICE

        pieDataSet.valueLinePart2Length = 0.6f //设置数据连接线长度

        //设置两根连接线的颜色

        pieDataSet.valueLineColor = Color.WHITE



        //对于右下角一串字母的操作

        pie.description.isEnabled = false //是否显示右下角描述

        pie.description.text = "这是修改那串英文的方法" //修改右下角字母的显示

        pie.description.textSize = 20f //字体大小

        pie.description.textColor = Color.RED //字体颜色



        //图例

        val legend = pie.legend

        legend.isEnabled = true //是否显示图例

        legend.position = Legend.LegendPosition.BELOW_CHART_CENTER //图例的位置





        //数据更新

        pie.notifyDataSetChanged()

        pie.invalidate()



        //动画(如果使用了动画可以则省去更新数据的那一步)

        pie.animateY(3000) //在Y轴的动画  参数是动画执行时间 毫秒为单位

        //        line.animateX(2000); //X轴动画

    //        line.animateXY(2000,2000);//XY两轴混合动画

    }

三.单个房间温度图表显示功能实现

3.1 效果展示

3.2 数据库实现

1. 创建数据库

类名:(MyDatabaseHelper)

class MyDatabaseHelper(

    private val mContext: Context, name: String?,

    factory: CursorFactory?, version: Int

) :

    SQLiteOpenHelper(mContext, name, factory, version) {

    override fun onCreate(db: SQLiteDatabase) {

        db.execSQL(CREATE)

        //Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show()

    }



    override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {}

    // TODO 创建数据库后,对数据库的操作

    // sql中Constant是用来存放一些关于数据库的常量的类

    // 类型有:Integer、text文本、varchar(n)、real浮点型、blob二进制类型

    companion object {

        const val CREATE =  "create table temp(_id integer primary key autoincrement,Home text,Date text,time text,temperatures real,hum real)"

    }





    fun deleteDatabase(context: Context, databaseName: String?): Boolean {

        return context.deleteDatabase(databaseName)

    }

}

2. 数据库的使用

(1)实例化

private var dbHelper: MyDatabaseHelper? = null



dbHelper = MyDatabaseHelper(this, "temperature.db", null, 1)(放到开始运行部分)

(2)创建数据库

private fun sql() {

        dbHelper?.writableDatabase;

}

(3)删除数据库

      private fun Detele(){

        dbHelper?.deleteDatabase(applicationContext, "temperature.db");

}

(4)插入数据

fun add(){



        val formatter = SimpleDateFormat("yyyy-MM-dd")

        val date: String = formatter.format(Date())

        

        val formatte = SimpleDateFormat("HH:mm:ss")

        val time = formatte.format(Date())



        val db: SQLiteDatabase = dbHelper!!.writableDatabase

        val values = ContentValues()

        // 开始组装第一条数据

        values.put("Home", (Math.random() * 100).toString())

        values.put("Date", date)

        values.put("time", time)

        values.put("temperatures", (Math.random() * 100).toFloat())

        values.put("hum", (Math.random() * 100).toFloat())

        db.insert("temp", null, values) // 插入第一条数据



        values.clear()



}

  (5)查询数据

fun find(){

var sql : String = "select * from `temp` where `Date` = '2021-11-02';"

        val cursor: Cursor = db.rawQuery(sql,null)



        if (cursor.moveToFirst()) {

            do {

                val name: String = cursor.getString(

                    cursor.getColumnIndex("Date")

                )

                val author: String = cursor.getString(

                    cursor.getColumnIndex("time")

                )

                val pages: Float = cursor.getFloat(

                    cursor.getColumnIndex("temperatures")

                )

                Log.d("MainActivity", "book name is $name")

                Log.d("MainActivity", "book author is $author")

                Log.d("MainActivity", "book pages is $pages")

            } while (cursor.moveTonext())

        }

        cursor.close()

}

3.3布局代码






    



        



        



        

            

                



                



                

                



            

        

        

            



                



                





                

                



            

        



        

            

3.4 Activity实现代码

1.实列化以及局部数据

//串口

    private var serialPortFinder: SerialPortFinder? = null

    private var serialHelper: SerialHelper? = null

    //曲线

    private var dynamicLineChartManager1: DynamicLineChartManager? = null

    private val list: MutableList = ArrayList() //数据集合

    private val names: MutableList = ArrayList() //折线名字集合

private val colour: MutableList = ArrayList() //折线颜色集合

//线程使用

private val mHandler = Handler()

2.串口实现函数以及数据跟新


 private fun openSerialPort(){



        serialPortFinder = SerialPortFinder()

        serialHelper = object : SerialHelper() {

            override fun onDataReceived(comBean: ComBean) {

                runonUiThread {

                    

                    val home =

                        ByteUtil.hexStringToString(ByteUtil.bytesToHexString(comBean.bRec)).toString().substring(0, 2)

                    val tem =

                        ByteUtil.hexStringToString(ByteUtil.bytesToHexString(comBean.bRec)).toString().substring(5, 9)

                    val hum =

                        ByteUtil.hexStringToString(ByteUtil.bytesToHexString(comBean.bRec)).toString().substring(12, 16)



                    when(home.toInt()) {

                        1 -> {

                            list.add(tem.toFloat())

                            list.add(hum.toFloat())

                            dynamicLineChartManager1!!.addEntry(list)

                            list.clear()

                        }

                        2 -> LogUtil.d("home","2")

                        3 -> LogUtil.d("home","3")

                        4 -> LogUtil.d("home","4")

                        else -> {

                        }

                    }

                }

            }

        }

        //获取串口地址

        val ports = serialPortFinder!!.allDevicesPath

        //设置波特率地址

        val botes = arrayOf(

            "0",

            "50",

            "75",

            "110",

            "134",

            "150",

            "200",

            "300",

            "600",

            "1200",

            "1800",

            "2400",

            "4800",

            "9600",

            "19200",

            "38400",

            "57600",

            "115200",

            "230400",

            "460800",

            "500000",

            "576000",

            "921600",

            "1000000",

            "1152000",

            "1500000",

            "2000000",

            "2500000",

            "3000000",

            "3500000",

            "4000000"

        )

        val spAdapter = SpAdapter(this)

        

        spAdapter.setDatas(ports)

        binding.spSerial.adapter = spAdapter

        binding.spSerial.onItemSelectedListener = object : AdapterView.onItemSelectedListener {

            override fun onItemSelected(

                parent: AdapterView<*>?,

                view: View,

                position: Int,

                id: Long

            ) {

                serialHelper?.close()

                serialHelper?.port = ports[position]

                binding.EditText1.setText(ports[position])

                binding.open.text = "关闭串口"

                //btOpen.setEnabled(true)

            }



            override fun onNothingSelected(parent: AdapterView<*>?) {}

        }

        

        val spAdapter2 = SpAdapter(this)

        spAdapter2.setDatas(botes)

        binding.spBote.adapter = spAdapter2



        binding.spBote.onItemSelectedListener = object : AdapterView.onItemSelectedListener {

            override fun onItemSelected(

                parent: AdapterView<*>?,

                view: View,

                position: Int,

                id: Long

            ) {

                serialHelper?.close()

                serialHelper?.setBaudRate(botes[position])

                binding.EditText2.setText(botes[position])

                binding.open.text = "关闭串口"

                // btOpen.setEnabled(true)

            }



            override fun onNothingSelected(parent: AdapterView<*>?) {}

        }

    }

3.模拟数据跟新


    private val mRunnable: Runnable = object : Runnable {

        override fun run() {

            dynamicLineChartManager1?.addEntry((Math.random() * 100).toFloat())

            // 每3秒执行一次

            mHandler.postDelayed(this, 3000) //给自己发送消息,自运行

        }

}

4.开启该线程

//模拟数据(simulated data)

        binding.SimulateData.setOnClickListener{

            //启动线程

            mHandler.post(mRunnable);

            //设置模拟数据不能被点击

            binding.SimulateData.isEnabled = false

        }

5.退出时关闭模拟线程

override fun onDestroy() {

        //将线程销毁掉

        mHandler.removeCallbacks(mRunnable)

        super.onDestroy()

    }

四.多个房间温度图表显示功能实现

4.1 效果展示

4.2布局代码






    



        



        



        

            

                



                



                

                



            

        

        

            



                



                





                

                



            

        



        

            

4.3 Activity实现代码

1.实列化以及局部数据

//串口

    private var serialPortFinder: SerialPortFinder? = null

    private var serialHelper: SerialHelper? = null

    //曲线

    private var dynamicLineChartManager1: DynamicLineChartManager? = null

    private var dynamicLineChartManager2: DynamicLineChartManager? = null

    private var dynamicLineChartManager3: DynamicLineChartManager? = null

    private var dynamicLineChartManager4: DynamicLineChartManager? = null

    //房间数据集

    private val list: MutableList = ArrayList() //数据集合

    private val list2: MutableList = ArrayList() //数据集合

    private val list3: MutableList = ArrayList() //数据集合

    private val list4: MutableList = ArrayList() //数据集合



    private val names: MutableList = ArrayList() //折线名字集合

    private val colour: MutableList = ArrayList() //折线颜色集合

    //数据库

    private var dbHelper: MyDatabaseHelper? = null

private val mHandler = Handler()



2.串口实现函数以及数据跟新



    private fun openSerialPort(){

        serialPortFinder = SerialPortFinder()

        serialHelper = object : SerialHelper() {

            override fun onDataReceived(comBean: ComBean) {

                runonUiThread {

                    

                    val formatter = SimpleDateFormat("yyyy-MM-dd")

                    val date: String = formatter.format(Date())

                    

                    val formatte = SimpleDateFormat("HH:mm:ss")

                    val time = formatte.format(Date())



                    val db: SQLiteDatabase = dbHelper!!.writableDatabase



                    val home =

                        ByteUtil.hexStringToString(ByteUtil.bytesToHexString(comBean.bRec)).toString().substring(0, 2)

                    val tem =

                        ByteUtil.hexStringToString(ByteUtil.bytesToHexString(comBean.bRec)).toString().substring(5, 9)

                    val hum =

                        ByteUtil.hexStringToString(ByteUtil.bytesToHexString(comBean.bRec)).toString().substring(12, 16)



                    when(home.toInt()) {

                        1 -> {

                            val values = ContentValues()

                            //保存到数据库中

                            values.put("Home",home.toInt())

                            values.put("Date", date)

                            values.put("time", time)

                            values.put("temperatures", tem)

                            values.put("hum", hum)

                            db.insert("temp", null, values) // 插入第一条数据

                            values.clear()

                            //更新列表

                            list.add(tem.toFloat())

                            list.add(hum.toFloat())

                            dynamicLineChartManager1!!.addEntry(list)

                            list.clear()

                        }

                        2 -> {

                            val values = ContentValues()

                            //保存到数据库中

                            values.put("Home",home.toInt())

                            values.put("Date", date)

                            values.put("time", time)

                            values.put("temperatures", tem)

                            values.put("hum", hum)

                            db.insert("temp", null, values) // 插入第一条数据

                            values.clear()



                            list2.add(tem.toFloat())

                            list2.add(hum.toFloat())

                            dynamicLineChartManager2!!.addEntry(list2)

                            list2.clear()

                        }

                        3 -> {

                            val values = ContentValues()

                            //保存到数据库中

                            values.put("Home",home.toInt())

                            values.put("Date", date)

                            values.put("time", time)

                            values.put("temperatures", tem)

                            values.put("hum", hum)

                            db.insert("temp", null, values) // 插入第一条数据

                            values.clear()



                            list3.add(tem.toFloat())

                            list3.add(hum.toFloat())

                            dynamicLineChartManager3!!.addEntry(list3)

                            list3.clear()

                        }

                        4 -> {

                            val values = ContentValues()

                            //保存到数据库中

                            values.put("Home",home.toInt())

                            values.put("Date", date)

                            values.put("time", time)

                            values.put("temperatures", tem)

                            values.put("hum", hum)

                            db.insert("temp", null, values) // 插入第一条数据

                            values.clear()



                            list4.add(tem.toFloat())

                            list4.add(hum.toFloat())

                            dynamicLineChartManager4!!.addEntry(list4)

                            list4.clear()

                        }

                        else -> {

                        }

                    }



                }

            }

        }

        //获取串口地址

        val ports = serialPortFinder!!.allDevicesPath

        //设置波特率地址

        val botes = arrayOf(

            "0",

            "50",

            "75",

            "110",

            "134",

            "150",

            "200",

            "300",

            "600",

            "1200",

            "1800",

            "2400",

            "4800",

            "9600",

            "19200",

            "38400",

            "57600",

            "115200",

            "230400",

            "460800",

            "500000",

            "576000",

            "921600",

            "1000000",

            "1152000",

            "1500000",

            "2000000",

            "2500000",

            "3000000",

            "3500000",

            "4000000"

        )

        val spAdapter = SpAdapter(this)

        

        spAdapter.setDatas(ports)

        binding.spSerial.adapter = spAdapter

        binding.spSerial.onItemSelectedListener = object : AdapterView.onItemSelectedListener {

            override fun onItemSelected(

                parent: AdapterView<*>?,

                view: View,

                position: Int,

                id: Long

            ) {

                serialHelper?.close()

                serialHelper?.port = ports[position]

                binding.EditText1.setText(ports[position])

                binding.open.text = "关闭串口"

                //btOpen.setEnabled(true)

            }



            override fun onNothingSelected(parent: AdapterView<*>?) {}

        }

        

        val spAdapter2 = SpAdapter(this)

        spAdapter2.setDatas(botes)

        binding.spBote.adapter = spAdapter2



        binding.spBote.onItemSelectedListener = object : AdapterView.onItemSelectedListener {

            override fun onItemSelected(

                parent: AdapterView<*>?,

                view: View,

                position: Int,

                id: Long

            ) {

                serialHelper?.close()

                serialHelper?.setBaudRate(botes[position])

                binding.EditText2.setText(botes[position])

                binding.open.text = "关闭串口"

                // btOpen.setEnabled(true)

            }



            override fun onNothingSelected(parent: AdapterView<*>?) {}

        }

    }

3.模拟数据跟新


    private val mRunnable: Runnable = object : Runnable {

        override fun run() {

            dynamicLineChartManager1?.addEntry((Math.random() * 100).toFloat())

            dynamicLineChartManager2?.addEntry((Math.random() * 100).toFloat())

            dynamicLineChartManager3?.addEntry((Math.random() * 100).toFloat())

            dynamicLineChartManager4?.addEntry((Math.random() * 100).toFloat())

            // 每3秒执行一次

            mHandler.postDelayed(this, 3000) //给自己发送消息,自运行

        }

    }4.开启该线程

//模拟数据(simulated data)

        binding.SimulateData.setOnClickListener{

            //启动线程

            mHandler.post(mRunnable);

            //设置模拟数据不能被点击

            binding.SimulateData.isEnabled = false

        }

5.退出时关闭模拟线程

override fun onDestroy() {

        //将线程销毁掉

        mHandler.removeCallbacks(mRunnable)

        super.onDestroy()

    }

五.历史数据分析图显示功能实现

5.1 效果展示

5.2布局代码






    



    



    

        

            



                



                    



                    

                

            

            



                



                    



                    

                

            



            

            

        

    

5.3 Activity实现代码

1.实列化以及局部数据

private var dynamicLineChartManager1: DynamicLineChartManager? = null



    private val names: MutableList = ArrayList() //折线名字集合

    private var dbHelper: MyDatabaseHelper? = null

    private val colour: MutableList = ArrayList() //折线颜色集合

    private val list: MutableList = ArrayList() //数据集合

    private var enddata: String? = null

    private var startdata: String? = null

2. 开始时间选择

//开始时间选择

        binding.startText.setonClickListener {

            val startTime = "1990-01-01 00:00:00"

            val endTime = "2100-01-01 12:00:00"

            val formatStr = DateUtil.Y_M_D_H_M_S

            val type = booleanArrayOf(true, true, true, true, true, true)

            val currentTime = DateUtil.convertOtherFormat(DateUtil.getCurrentDateTime(), DateUtil.Y_M_D, DateUtil.Y_M_D_H_M_S)

            PickerViewUtil.selectDateTime(

                this, { date: Date?, v1: View? ->

                    startData = DateUtil.dateToString(date, "yyyy-MM-ddHH:mm:ss")

                    val sb: StringBuilder = StringBuilder(startData)

                    Log.d("字符串:", "" + sb.toString() + " 字符长度:" + sb.length)

                    val string =sb.toString().substring(0, 10)

                    startData = string

                    Log.d("字符串:", "" + startData)

                    binding.startText.text = DateUtil.date2String(date!!, formatStr)

                }, currentTime, startTime, endTime, formatStr,

                "选择日期时间", "取消", "确定", type

            )



            //accessUrlRxJava(UrlConstant.ONE_NET_URL)

        }

3. 结束时间选择

  //结束时间选择

        binding.endText.setonClickListener {

            val startTime = "1990-01-01 00:00:00"

            var endTime = "2100-01-01 12:00:00"

            val formatStr = DateUtil.Y_M_D_H_M_S

            val type = booleanArrayOf(true, true, true, true, true, true)

            val currentsTime = DateUtil.convertOtherFormat(DateUtil.getCurrentDateTime(), DateUtil.Y_M_D, DateUtil.Y_M_D_H_M_S)

            PickerViewUtil.selectDateTime(

                this, onTimeSelectListener { date: Date?, v1: View? ->

                    endData = DateUtil.dateToString(date, "yyyy-MM-ddHH:mm:ss")

                    val sb: StringBuilder = StringBuilder(endData)

                    Log.d("字符串:", "" + sb.toString() + " 字符长度:" + sb.length)

                    val string = sb.substring(0, 10)

                    endData = string.toString()

                    Log.d("字符串:", "" + endData)

                    binding.endText.text = DateUtil.date2String(date!!, formatStr)

                    binding.time.text = "等待中....!"

                    Handler(Looper.getMainLooper()).postDelayed({

                        

                        findHistoryData()

                    }, 300)



                }, currentsTime, startTime, endTime, formatStr,

                "选择日期时间", "取消", "确定", type

            )



            //accessUrlRxJava(UrlConstant.ONE_NET_URL)

        }

4.数据库查找数据显示

private fun findHistoryData(){

        val db: SQLiteDatabase = dbHelper!!.writableDatabase

        val sql : String = "select * from `temp` where `Date` Between '$startData' and '$endData';"

        val cursor: Cursor = db.rawQuery(sql,null)

        if (cursor.moveToFirst()) {

            do {

                val Datas: String = cursor.getString(

                    cursor.getColumnIndex("Date")

                )

                val times: String = cursor.getString(

                    cursor.getColumnIndex("time")

                )

                val temp: Float = cursor.getFloat(

                    cursor.getColumnIndex("temperatures")

                )

                val hum: Float = cursor.getFloat(

                    cursor.getColumnIndex("hum")

                )

                list.add(temp.toFloat())

                list.add(hum.toFloat())

                dynamicLineChartManager1!!.HistoryAddEntry(list)

                list.clear()

            } while (cursor.moveTonext())

        }

        cursor.close()

        Handler(Looper.getMainLooper()).postDelayed({

            

            binding.time.text = "数据加载完成!"

        }, 200)

    }

End

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/459972.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号