加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入

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

04/24 08:54
901
服务支持:
技术交流群

完成交易后在“购买成功”页面扫码入群,即可与技术大咖们分享疑惑和经验、收获成长和认同、领取优惠和红包等。

虚拟商品不可退

当前内容为数字版权作品,购买后不支持退换且无法转移使用。

加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论
放大
实物图
  • 方案介绍
    • 一.Kotlin串口通讯实现
    • 二.MPAndroidChart图表使用
    • 三.单个房间温度图表显示功能实现
    • 四.多个房间温度图表显示功能实现
    • 五.历史数据分析图显示功能实现
  • 相关文件
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

一.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 代码

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical">



    <androidx.appcompat.widget.Toolbar

        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"

        android:background="@color/shape3"

        android:id="@+id/toolbar"

        android:layout_width="match_parent"

        android:layout_height="?actionBarSize"

        app:title="History Data"

        app:titleTextColor="@android:color/white"

        >



    </androidx.appcompat.widget.Toolbar>



    <FrameLayout

        android:id="@+id/main_layout"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        >

        <LinearLayout

            android:layout_width="match_parent"

            android:layout_height="match_parent"

            android:orientation="vertical">

            <androidx.recyclerview.widget.RecyclerView

                android:id="@+id/recycler_view"

                style="@style/RecyclerViewStyle"

                android:layout_weight="1"/>

            <RadioGroup

                android:id="@+id/radioGroup"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:layout_marginBottom="8dp"

                android:layout_marginStart="8dp"

                android:orientation="horizontal"

                app:layout_constraintBottom_toTopOf="@+id/sp_bote"

                app:layout_constraintStart_toStartOf="parent">

                <RadioButton

                    android:id="@+id/radioButton1"

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:layout_weight="1"

                    android:text="发送Text" />



                <RadioButton

                    android:id="@+id/radioButton2"

                    android:layout_width="wrap_content"

                    android:layout_height="wrap_content"

                    android:layout_marginLeft="10dp"

                    android:layout_weight="1"

                    android:checked="true"

                    android:text="发送Hex" />

            </RadioGroup>

            <androidx.cardview.widget.CardView

                style="@style/CardViews"

                app:cardCornerRadius="22dp">

                <LinearLayout

                    android:layout_width="match_parent"

                    android:layout_height="wrap_content"

                    android:gravity="center_vertical"

                    android:layout_marginLeft="20dp">

                    <TextView

                        android:layout_width="66dp"

                        android:layout_height="wrap_content"

                        android:layout_marginTop="12dp"

                        android:layout_marginBottom="12dp"

                        android:alpha="0.4"

                        android:text="串口号"

                        android:gravity="center"

                        android:textColor="@color/black"

                        android:textSize="14sp" />

                    <EditText

                        android:layout_weight="1"

                        android:id="@+id/EditText1"

                        android:layout_width="match_parent"

                        android:layout_height="match_parent"

                        android:background="@null"

                        android:hint="无"

                        android:inputType="number"

                        android:textColor="@color/shape1"

                        android:textSize="14sp"

                        android:layout_marginLeft="14dp" />

                    <Spinner

                        android:id="@+id/sp_serial"

                        android:layout_width="100dp"

                        android:layout_height="wrap_content"

                        android:layout_marginStart="8dp"

                        android:layout_marginEnd="15dp">

                    </Spinner>

                </LinearLayout>

            </androidx.cardview.widget.CardView>

            <androidx.cardview.widget.CardView

                style="@style/CardViews"

                app:cardCornerRadius="22dp">

                <LinearLayout

                    android:layout_width="match_parent"

                    android:layout_height="wrap_content"

                    android:gravity="center_vertical"

                    android:layout_marginLeft="20dp">

                    <TextView

                        android:layout_width="66dp"

                        android:layout_height="wrap_content"

                        android:layout_marginTop="12dp"

                        android:layout_marginBottom="12dp"

                        android:alpha="0.4"

                        android:gravity="center"

                        android:text="波特率"

                        android:textColor="@color/black"

                        android:textSize="14sp" />



                    <EditText

                        android:id="@+id/EditText2"

                        android:layout_weight="1"

                        android:layout_width="match_parent"

                        android:layout_height="match_parent"

                        android:background="@null"

                        android:hint="无"

                        android:inputType="number"

                        android:textColor="@color/shape1"

                        android:textSize="14sp"

                        android:layout_marginLeft="14dp" />

                    <Spinner

                        android:id="@+id/sp_bote"

                        android:layout_width="100dp"

                        android:layout_height="wrap_content"

                        android:layout_marginStart="8dp"

                        android:layout_marginEnd="15dp">

                    </Spinner>



                </LinearLayout>

            </androidx.cardview.widget.CardView>

            <androidx.cardview.widget.CardView

                style="@style/CardViews"

                app:cardCornerRadius="22dp">

                <LinearLayout

                    android:layout_width="match_parent"

                    android:layout_height="wrap_content"

                    android:gravity="center_vertical"

                    android:layout_marginLeft="20dp">

                    <TextView

                        android:layout_width="66dp"

                        android:layout_height="wrap_content"

                        android:layout_marginTop="12dp"

                        android:layout_marginBottom="12dp"

                        android:alpha="0.4"

                        android:text="发送消息"

                        android:gravity="center"

                        android:textColor="@color/black"

                        android:textSize="14sp" />



                    <EditText

                        android:id="@+id/SendText"

                        android:layout_width="match_parent"

                        android:layout_height="match_parent"

                        android:layout_marginLeft="14dp"

                        android:layout_weight="1"

                        android:background="@null"

                        android:hint="请输入"

                        android:textColor="@color/teal_200"

                        android:textSize="14sp" />



                </LinearLayout>

            </androidx.cardview.widget.CardView>





            <LinearLayout

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:gravity="center"

                android:layout_marginTop="20dp"

                android:layout_marginBottom="25dp"



                android:orientation="horizontal">

                <Button

                    android:id="@+id/open"

                    android:layout_width="wrap_content"

                    android:layout_height="44dp"

                    android:background="@drawable/shape_bt"

                    android:gravity="center"

                    android:text="打开串口"

                    android:textColor="@android:color/white"

                    android:textSize="@dimen/sp_14" />

                <View

                    android:layout_width="100dp"

                    android:layout_height="match_parent"

                    >

                </View>

                <Button

                    android:id="@+id/send"

                    android:layout_width="wrap_content"

                    android:layout_height="44dp"

                    android:background="@drawable/shape_bt"

                    android:gravity="center"

                    android:text="发送"

                    android:textColor="@android:color/white"

                    android:textSize="@dimen/sp_14" />

            </LinearLayout>

        </LinearLayout>

    </FrameLayout>

</LinearLayout>

1.4 Activity实现代码

13.1 实列化

private var serialPortFinder: SerialPortFinder? = null

      private var serialHelper: SerialHelper? = null

       //局部变量

private val list = ArrayList<Map<String, Any>>()

       var map: Map<String, Any>? = 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)

        /*

         * TODO 适配下拉列表(串口地址)

        * */

        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<*>?) {}

        }

        /*

         * TODO 适配下拉列表(波特率地址)

        * */

        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()

                    /*

                    * TODO 将获取的数据进行列表适配

                    * */

                    map = HashMap()

                    (map as HashMap<String, Any>)["Value"] =comBean.sRecTime + ":   " +

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

                    list.add(map as HashMap<String, Any>)

                    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文件中加入依赖

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

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

/*安卓项目实战之:开源框架BaseRecyclerViewAdapterHelper的使用*/

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

//MPAndroidChart画图

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

dependencies {

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

/*    *//*一个非常好用的开源库,调试Android数据库有救了*//*

    debugImplementation 'com.glance.guolindev:glance:1.0.0-alpha01'*/

    //使用开源的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'

    /*android4.4以上沉浸式状态栏和导航栏实现以及Bar的其他管理*/

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

    /*安卓项目实战之:开源框架BaseRecyclerViewAdapterHelper的使用*/

    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布局代码

<com.github.mikephil.charting.charts.LineChart

            android:id="@+id/dynamic_chart1"

            android:layout_width="match_parent"

            android:layout_height="380dp"/>

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<ILineDataSet> lineDataSets = new ArrayList<>();

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

    private List<String> 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<String> names, List<Integer> colors) {

        this.lineChart = mLineChart;

        leftAxis = lineChart.getAxisLeft();

        rightAxis = lineChart.getAxisRight();

        xAxis = lineChart.getXAxis();

        initLineChart();

        initLineDataSet(names, colors);



    }



    /**

     * 初始化LineChar

     */

    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);

    }



    /**

     * 初始警告线化折线(一条线)

     *

     * @param name

     * @param color

     */

    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);

    }

    /**

     * 初始化折线(一条线)

     *

     * @param name

     * @param 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();



    }



    /**

     * 初始化折线(多条线)

     *

     * @param names

     * @param colors

     */

    private void initLineDataSet(List<String> names, List<Integer> 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();

    }



    /**

     * 动态添加数据(一条折线图)

     *

     * @param number

     */

    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);



    }

    /**

     * 动态添加数据(一条折线图)

     *

     * @param number

     * @param time

     * @param str

     */

    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);

    }

    /**

     * 动态添加数据(多条折线图)

     *

     * @param numbers

     */

    public void addEntry(List<Float> 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);

        }

    }



    /**

     * 设置Y轴值

     *

     * @param max

     * @param min

     * @param labelCount

     */

    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();

    }

    /**

     * 设置高限制线

     *

     * @param high

     * @param name

     */

    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();

    }



    /**

     * 设置低限制线

     *

     * @param low

     * @param name

     */

    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();

    }



    /**

     * 设置描述信息

     *

     * @param str

     */

    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

局部数据

/*

    * 1.关于List在kotlin里面没有add(),clear() 方法解决办法

    *   将List改变成MutableList,MutableList源码可以发现,常用的clear、addAll等方法都有定义

    *   解决的办法就是将变量类型使用"MutableList"代替"List"就可以了,完整的定义如下代码:

    * */

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



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



    private val colour: MutableList<Int> = 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布局代码

<com.github.mikephil.charting.charts.CombinedChart

            android:id="@+id/chart1"

            android:layout_width="match_parent"

            android:layout_height="360dp"/>

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();

    }



    /**

     * 初始化Chart

     */

    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轴

    }



    /**

     * 设置X轴坐标值

     *

     * @param xAxisValues x轴坐标集合

     */

    public void setXAxis(final List<String> 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();

    }



    /**

     * 得到折线图(一条)

     *

     * @param lineChartY 折线Y轴值

     * @param lineName   折线图名字

     * @param lineColor  折线颜色

     * @return

     */

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

        LineData lineData = new LineData();



        ArrayList<Entry> 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;

    }



    /**

     * 得到折线图(多条)

     *

     * @param lineChartYs 折线Y轴值

     * @param lineNames   折线图名字

     * @param lineColors  折线颜色

     * @return

     */

    private LineData getLineData(List<List<Float>> lineChartYs, List<String> lineNames, List<Integer> lineColors) {

        LineData lineData = new LineData();



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

            ArrayList<Entry> 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;

    }



    /**

     * 得到柱状图

     *

     * @param barChartY Y轴值

     * @param barName   柱状图名字

     * @param barColor  柱状图颜色

     * @return

     */



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

        BarData barData = new BarData();

        ArrayList<BarEntry> 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;

    }



    /**

     * 得到柱状图(多条)

     *

     * @param barChartYs Y轴值

     * @param barNames   柱状图名字

     * @param barColors  柱状图颜色

     * @return

     */



    private BarData getBarData(List<List<Float>> barChartYs, List<String> barNames, List<Integer> barColors) {

        List<IBarDataSet> lists = new ArrayList<>();

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

            ArrayList<BarEntry> 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;

    }



    /**

     * 显示混合图(柱状图+折线图)

     *

     * @param xAxisValues X轴坐标

     * @param barChartY   柱状图Y轴值

     * @param lineChartY  折线图Y轴值

     * @param barName     柱状图名字

     * @param lineName    折线图名字

     * @param barColor    柱状图颜色

     * @param lineColor   折线图颜色

     */



    public void showCombinedChart(

            List<String> xAxisValues, List<Float> barChartY, List<Float> 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();

    }

    /**

     * 显示混合图(柱状图)

     *

     * @param xAxisValues X轴坐标

     * @param barChartY   柱状图Y轴值

     * @param lineChartY  折线图Y轴值

     * @param barName     柱状图名字

     * @param lineName    折线图名字

     * @param barColor    柱状图颜色

     * @param lineColor   折线图颜色

     */



    public void showbinedChart(

            List<String> xAxisValues, List<Float> barChartY

            , String barName, int barColor) {

        initChart();

        setXAxis(xAxisValues);



        CombinedData combinedData = new CombinedData();



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



        mCombinedChart.setData(combinedData);

        mCombinedChart.invalidate();

    }

    /**

     * 显示混合图(柱状图+折线图)

     *

     * @param xAxisValues X轴坐标

     * @param barChartYs  柱状图Y轴值

     * @param lineChartYs 折线图Y轴值

     * @param barNames    柱状图名字

     * @param lineNames   折线图名字

     * @param barColors   柱状图颜色

     * @param lineColors  折线图颜色

     */



    public void showCombinedChart(

            List<String> xAxisValues, List<List<Float>> barChartYs, List<List<Float>> lineChartYs,

            List<String> barNames, List<String> lineNames, List<Integer> barColors, List<Integer> 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<String> = ArrayList()

        for (i in 0..20) {

            xData.add(i.toString())

        }

        //y轴数据集合

        val yBarDatas: MutableList<List<Float>> = ArrayList()

        //4种直方图

        for (i in 0..3) {

            //y轴数

            val yData: MutableList<Float> = ArrayList()

            for (j in 0..20) {

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

            }

            yBarDatas.add(yData)

        }

        //颜色集合

        val colors: MutableList<Int> = 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布局代码

  <com.github.mikephil.charting.charts.CombinedChart

            android:id="@+id/chart1"

            android:layout_width="match_parent"

            android:layout_height="360dp"/>

2.4.2 Activity实现代码

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

private fun intDate(){

        //x轴数据

        val xData: MutableList<String> = ArrayList()

        for (i in 0..20) {

            xData.add(i.toString())

        }

        //y轴数据集合

        val yBarDatas: MutableList<List<Float>> = ArrayList()

        //4种直方图

        for (i in 0..3) {

            //y轴数

            val yData: MutableList<Float> = ArrayList()

            for (j in 0..20) {

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

            }

            yBarDatas.add(yData)

        }

        //y轴数据集合

        val yLineDatas: MutableList<List<Float>> = ArrayList()

        //4种直方图

        for (i in 0..3) {

            //y轴数

            val yData: MutableList<Float> = ArrayList()

            for (j in 0..20) {

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

            }

            yLineDatas.add(yData)

        }

        //名字集合

        val barNames: MutableList<String> = ArrayList()

        barNames.add("直方图一")

        barNames.add("直方图二")

        barNames.add("直方图三")

        barNames.add("直方图四")

        //颜色集合

        val colors: MutableList<Int> = ArrayList()

        colors.add(Color.BLUE)

        colors.add(Color.RED)

        colors.add(Color.YELLOW)

        colors.add(Color.CYAN)

        //竖状图管理类

        val lineNames: MutableList<String> = 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布局代码‘

<com.github.mikephil.charting.charts.RadarChart

            android:id="@+id/radar"

            android:layout_marginTop="20dp"

            android:layout_width="match_parent"

            android:layout_height="300dp">

2.5.2 Activity实现代码

1.实现代码

   fun radar(){

        val radar: RadarChart? = binding.radar

        var list: MutableList<RadarEntry>? = null

        var list2: MutableList<RadarEntry>? = 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布局代码

<com.github.mikephil.charting.charts.PieChart

            android:id="@+id/pie"

            android:layout_width="match_parent"

            android:layout_height="300dp">

        </com.github.mikephil.charting.charts.PieChart>

2.6.2 Activity实现代码

1.实现代码


fun pie(){

        val pie: PieChart = binding.pie

        list = ArrayList()

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

        (list as ArrayList<PieEntry>).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())

        /*

        * HH-mm-ss(24时制)

        * hh-mm-ss(12时制)

        * */

        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布局代码

<?xml version="1.0" encoding="utf-8"?>

<ScrollView

    xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    >



    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:orientation="vertical">



        <androidx.appcompat.widget.Toolbar

            android:background="@color/shape3"

            android:id="@+id/toolbar"

            android:layout_width="match_parent"

            android:layout_height="?actionBarSize"

            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"

            app:title="SeriaPortHome"

            app:titleTextColor="@android:color/white"

            >



        </androidx.appcompat.widget.Toolbar>



        <androidx.cardview.widget.CardView

            style="@style/CardViews"

            app:cardCornerRadius="22dp">

            <LinearLayout

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:gravity="center_vertical"

                android:layout_marginLeft="20dp">

                <TextView

                    android:layout_width="66dp"

                    android:layout_height="wrap_content"

                    android:layout_marginTop="12dp"

                    android:layout_marginBottom="12dp"

                    android:alpha="0.4"

                    android:text="串口号"

                    android:gravity="center"

                    android:textColor="@color/black"

                    android:textSize="14sp" />



                <EditText

                    android:layout_weight="1"

                    android:id="@+id/EditText1"

                    android:layout_width="match_parent"

                    android:layout_height="match_parent"

                    android:background="@null"

                    android:hint="无"

                    android:inputType="number"

                    android:textColor="@color/shape1"

                    android:textSize="14sp"

                    android:layout_marginLeft="14dp" />



                <Spinner

                    android:id="@+id/sp_serial"

                    android:layout_width="100dp"

                    android:layout_height="wrap_content"

                    android:layout_marginStart="8dp"

                    android:layout_marginEnd="15dp">

                </Spinner>



            </LinearLayout>

        </androidx.cardview.widget.CardView>

        <androidx.cardview.widget.CardView

            style="@style/CardViews"

            app:cardCornerRadius="22dp">

            <LinearLayout

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:gravity="center_vertical"

                android:layout_marginLeft="20dp">



                <TextView

                    android:layout_width="66dp"

                    android:layout_height="wrap_content"

                    android:layout_marginTop="12dp"

                    android:layout_marginBottom="12dp"

                    android:alpha="0.4"

                    android:gravity="center"

                    android:text="波特率"

                    android:textColor="@color/black"

                    android:textSize="14sp" />



                <EditText

                    android:id="@+id/EditText2"

                    android:layout_weight="1"

                    android:layout_width="match_parent"

                    android:layout_height="match_parent"

                    android:background="@null"

                    android:hint="无"

                    android:inputType="number"

                    android:textColor="@color/shape1"

                    android:textSize="14sp"

                    android:layout_marginLeft="14dp" />





                <Spinner

                    android:id="@+id/sp_bote"

                    android:layout_width="100dp"

                    android:layout_height="wrap_content"

                    android:layout_marginStart="8dp"

                    android:layout_marginEnd="15dp">

                </Spinner>



            </LinearLayout>

        </androidx.cardview.widget.CardView>



        <LinearLayout

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:gravity="center"

            android:layout_marginTop="20dp"

            android:layout_marginBottom="25dp"



            android:orientation="horizontal">

            <Button

                android:id="@+id/open"

                android:layout_width="wrap_content"

                android:layout_height="44dp"

                android:background="@drawable/shape_bt"

                android:gravity="center"

                android:text="打开串口"



                android:textColor="@android:color/white"

                android:textSize="@dimen/sp_14" />

            <View

                android:layout_width="100dp"

                android:layout_height="match_parent"

                >

            </View>

            <Button

                android:id="@+id/SimulateData"

                android:layout_width="wrap_content"

                android:layout_height="44dp"

                android:background="@drawable/shape_bt"

                android:gravity="center"

                android:text="模拟数据"

                android:textColor="@android:color/white"

                android:textSize="@dimen/sp_14" />

        </LinearLayout>

        <com.github.mikephil.charting.charts.LineChart

            android:id="@+id/dynamic_chart1"

            android:layout_width="match_parent"

            android:layout_height="380dp"/>



        <Button

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:id="@+id/addEntry"



            android:text="随机数据"

            />

    </LinearLayout>

</ScrollView>

3.4 Activity实现代码

1.实列化以及局部数据

//串口

    private var serialPortFinder: SerialPortFinder? = null

    private var serialHelper: SerialHelper? = null

    //曲线

    private var dynamicLineChartManager1: DynamicLineChartManager? = null

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

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

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

//线程使用

private val mHandler = Handler()

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

/*

    * TODO 串口使用初始化

    * */

 private fun openSerialPort(){



        serialPortFinder = SerialPortFinder()

        serialHelper = object : SerialHelper() {

            override fun onDataReceived(comBean: ComBean) {

                runOnUiThread {

                    /*

                    * TODO 获取串口数据已经保存数据

                    *  */

                    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)

        /*

         * TODO 适配下拉列表(串口地址)

        * */

        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<*>?) {}

        }

        /*

         * TODO 适配下拉列表(波特率地址)

        * */

        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.模拟数据跟新

/*

    * TODO 线程更新处理

    * */

    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布局代码

<?xml version="1.0" encoding="utf-8"?>

<ScrollView

    xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    >



    <LinearLayout

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        android:orientation="vertical">



        <androidx.appcompat.widget.Toolbar

            android:background="@color/shape3"

            android:id="@+id/toolbar"

            android:layout_width="match_parent"

            android:layout_height="?actionBarSize"

            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"

            app:title="SeriaPortHome"

            app:titleTextColor="@android:color/white"

            >



        </androidx.appcompat.widget.Toolbar>



        <androidx.cardview.widget.CardView

            style="@style/CardViews"

            app:cardCornerRadius="22dp">

            <LinearLayout

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:gravity="center_vertical"

                android:layout_marginLeft="20dp">

                <TextView

                    android:layout_width="66dp"

                    android:layout_height="wrap_content"

                    android:layout_marginTop="12dp"

                    android:layout_marginBottom="12dp"

                    android:alpha="0.4"

                    android:text="串口号"

                    android:gravity="center"

                    android:textColor="@color/black"

                    android:textSize="14sp" />



                <EditText

                    android:layout_weight="1"

                    android:id="@+id/EditText1"

                    android:layout_width="match_parent"

                    android:layout_height="match_parent"

                    android:background="@null"

                    android:hint="无"

                    android:inputType="number"

                    android:textColor="@color/shape1"

                    android:textSize="14sp"

                    android:layout_marginLeft="14dp" />



                <Spinner

                    android:id="@+id/sp_serial"

                    android:layout_width="100dp"

                    android:layout_height="wrap_content"

                    android:layout_marginStart="8dp"

                    android:layout_marginEnd="15dp">

                </Spinner>



            </LinearLayout>

        </androidx.cardview.widget.CardView>

        <androidx.cardview.widget.CardView

            style="@style/CardViews"

            app:cardCornerRadius="22dp">

            <LinearLayout

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:gravity="center_vertical"

                android:layout_marginLeft="20dp">



                <TextView

                    android:layout_width="66dp"

                    android:layout_height="wrap_content"

                    android:layout_marginTop="12dp"

                    android:layout_marginBottom="12dp"

                    android:alpha="0.4"

                    android:gravity="center"

                    android:text="波特率"

                    android:textColor="@color/black"

                    android:textSize="14sp" />



                <EditText

                    android:id="@+id/EditText2"

                    android:layout_weight="1"

                    android:layout_width="match_parent"

                    android:layout_height="match_parent"

                    android:background="@null"

                    android:hint="无"

                    android:inputType="number"

                    android:textColor="@color/shape1"

                    android:textSize="14sp"

                    android:layout_marginLeft="14dp" />





                <Spinner

                    android:id="@+id/sp_bote"

                    android:layout_width="100dp"

                    android:layout_height="wrap_content"

                    android:layout_marginStart="8dp"

                    android:layout_marginEnd="15dp">

                </Spinner>



            </LinearLayout>

        </androidx.cardview.widget.CardView>



        <LinearLayout

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:gravity="center"

            android:layout_marginTop="20dp"

            android:layout_marginBottom="25dp"



            android:orientation="horizontal">

            <Button

                android:id="@+id/open"

                android:layout_width="wrap_content"

                android:layout_height="44dp"

                android:background="@drawable/shape_bt"

                android:gravity="center"

                android:text="打开串口"



                android:textColor="@android:color/white"

                android:textSize="@dimen/sp_14" />

            <View

                android:layout_width="100dp"

                android:layout_height="match_parent"

                >

            </View>

            <Button

                android:id="@+id/SimulateData"

                android:layout_width="wrap_content"

                android:layout_height="44dp"

                android:background="@drawable/shape_bt"

                android:gravity="center"

                android:text="模拟数据"

                android:textColor="@android:color/white"

                android:textSize="@dimen/sp_14" />

        </LinearLayout>



        <com.github.mikephil.charting.charts.LineChart

            android:id="@+id/dynamic_chart1"

            android:layout_width="match_parent"

            android:layout_height="380dp"/>



        <com.github.mikephil.charting.charts.LineChart

            android:id="@+id/dynamic_chart2"

            android:layout_width="match_parent"

            android:layout_height="380dp"/>



        <com.github.mikephil.charting.charts.LineChart

            android:id="@+id/dynamic_chart3"

            android:layout_width="match_parent"

            android:layout_height="380dp"/>

       

        <com.github.mikephil.charting.charts.LineChart

            android:id="@+id/dynamic_chart4"

            android:layout_width="match_parent"

            android:layout_height="380dp"/>

        <Button

            android:layout_width="match_parent"

            android:layout_height="wrap_content"

            android:id="@+id/addEntry"



            android:text="随机数据"

            />



    </LinearLayout>

</ScrollView>

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<Float> = ArrayList() //数据集合

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

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

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



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

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

    //数据库

    private var dbHelper: MyDatabaseHelper? = null

private val mHandler = Handler()



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

/*

    * TODO 串口使用初始化

    * */

    private fun openSerialPort(){

        serialPortFinder = SerialPortFinder()

        serialHelper = object : SerialHelper() {

            override fun onDataReceived(comBean: ComBean) {

                runOnUiThread {

                    /*

                    * TODO 获取串口数据已经保存数据

                    *  */

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

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

                    /*

                    * HH-mm-ss(24时制)

                    * hh-mm-ss(12时制)

                    * */

                    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)

        /*

         * TODO 适配下拉列表(串口地址)

        * */

        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<*>?) {}

        }

        /*

         * TODO 适配下拉列表(波特率地址)

        * */

        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.模拟数据跟新

/*

    * TODO 线程更新处理

    * */

    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布局代码

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:orientation="vertical">



    <androidx.appcompat.widget.Toolbar

        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"

        android:background="@color/shape3"

        android:id="@+id/toolbar"

        android:layout_width="match_parent"

        android:layout_height="?actionBarSize"

        app:title="History Data"

        app:titleTextColor="@android:color/white"

        >



    </androidx.appcompat.widget.Toolbar>



    <FrameLayout

        xmlns:android="http://schemas.android.com/apk/res/android"

        xmlns:tools="http://schemas.android.com/tools"

        xmlns:fab="http://schemas.android.com/apk/res-auto"

        android:id="@+id/main_layout"

        android:layout_width="match_parent"

        android:layout_height="match_parent"

        >

        <LinearLayout

            android:layout_width="match_parent"

            android:layout_height="match_parent"

            android:orientation="vertical">

            <androidx.cardview.widget.CardView

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:layout_marginStart="30dp"

                android:layout_marginTop="16dp"

                android:layout_marginEnd="30dp"

                android:background="@android:color/white"

                app:cardCornerRadius="22dp">



                <LinearLayout

                    android:layout_width="match_parent"

                    android:layout_height="wrap_content"

                    android:layout_marginStart="20dp"

                    android:layout_marginEnd="20dp"

                    android:gravity="center_vertical">



                    <TextView

                        android:layout_width="66dp"

                        android:layout_height="wrap_content"

                        android:layout_marginTop="12dp"

                        android:layout_marginBottom="12dp"

                        android:alpha="0.4"

                        android:text="开始日期"

                        android:textColor="@color/black"

                        android:textSize="14sp" />



                    <TextView

                        android:id="@+id/start_text"

                        android:layout_width="match_parent"

                        android:layout_height="match_parent"

                        android:gravity="center"



                        android:background="@null"

                        android:hint="yyyy-MM-ddHH:mm:ss"

                        android:inputType="number"

                        android:textColor="@color/colorPrimary"

                        android:textSize="14sp"

                        android:layout_marginLeft="14dp" />

                </LinearLayout>

            </androidx.cardview.widget.CardView>

            <androidx.cardview.widget.CardView

                android:layout_width="match_parent"

                android:layout_height="wrap_content"

                android:layout_marginStart="30dp"

                android:layout_marginTop="16dp"

                android:layout_marginEnd="30dp"

                android:layout_marginBottom="16dp"

                android:background="@android:color/white"

                app:cardCornerRadius="22dp">



                <LinearLayout

                    android:layout_width="match_parent"

                    android:layout_height="wrap_content"

                    android:layout_marginStart="20dp"

                    android:layout_marginEnd="20dp"

                    android:gravity="center_vertical">



                    <TextView

                        android:layout_width="66dp"

                        android:layout_height="wrap_content"

                        android:layout_marginTop="12dp"

                        android:layout_marginBottom="12dp"

                        android:alpha="0.4"

                        android:text="结束日期"

                        android:textColor="@color/black"

                        android:textSize="14sp" />



                    <TextView

                        android:id="@+id/end_text"

                        android:layout_width="match_parent"

                        android:layout_height="match_parent"



                        android:background="@null"

                        android:gravity="center"

                        android:hint="yyyy-MM-ddHH:mm:ss"

                        android:inputType="number"

                        android:textColor="@color/colorPrimary"

                        android:textSize="14sp"

                        android:layout_marginLeft="14dp" />

                </LinearLayout>

            </androidx.cardview.widget.CardView>



            <com.github.mikephil.charting.charts.LineChart

                android:id="@+id/dynamic_chart1"

                android:layout_marginTop="20dp"

                android:layout_width="match_parent"

                android:layout_height="400dp"/>

            <TextView

                android:id="@+id/time"

                android:layout_width="wrap_content"

                android:layout_height="wrap_content"

                android:layout_marginTop="12dp"

                android:layout_marginBottom="12dp"

                android:alpha="0.4"

                android:layout_gravity="center"

                android:text="等待"

                android:textColor="@color/black"

                android:textSize="14sp" />

        </LinearLayout>

    </FrameLayout>

</LinearLayout>

5.3 Activity实现代码

1.实列化以及局部数据

private var dynamicLineChartManager1: DynamicLineChartManager? = null



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

    private var dbHelper: MyDatabaseHelper? = null

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

    private val list: MutableList<Float> = 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({

                        /**

                         * 数据初始化(200毫秒)AddDeviceActivity

                         * */

                        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({

            /**

             * 数据初始化(200毫秒)AddDeviceActivity

             * */

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

        }, 200)

    }

End

联系方式 微信号:13648103287

  • 联系方式.docx

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
HMC987LP5ETR 1 Hittite Microwave Corp Support Circuit, 1-Func, PQCC32, 5 X 5 MM, ROHS COMPLIANT, PLASTIC, SMT-32
$18.85 查看
DP83848CVVX/NOPB 1 Texas Instruments Commercial temperature, 10/100-Mbps Ethernet PHY transceiver with SNI interface &amp; JTAG support 48-LQFP 0 to 70

ECAD模型

下载ECAD模型
$4.35 查看
TJA1051T/E/1J 1 NXP Semiconductors TJA1051 - High-speed CAN transceiver SOIC 8-Pin

ECAD模型

下载ECAD模型
$0.39 查看

相关推荐

电子产业图谱

方案定制,程序设计方案、单片机程序设计与讲解、APP定制开发。本公众号致力于向读者传递关于程序设计和开发的相关知识,并分享一些关于软件开发的最佳实践。如果您有什么问题或建议,请随时联系我们。我们将竭诚为您服务