• 2.9 学习总结 之 【Android】体温统计APP


    一、说在前面

    昨天 学习了JQ的相关知识
    今天 编写体温统计APP

    我的工程源码:https://github.com/xiaotian12-call/Take-body-temperature

    二、所有知识

    1、使用Room管理数据库。

    2、使用ViewModel管理UI数据。

    3、使用hellochart图表展示数据。

    4、使用liveData管理数据库数据(观察者),时时更新界面数据。

    三、设计思路

    1、构建底层数据库。

    2、UI设计(卡片视图界面,单个卡片界面,折线图表界面,录入体温界面,菜单界面)。

    3、编写Navigation,将卡片视图界面,折线图表界面,录入体温界面加入其中,并确定界面跳转关系。

    4、编写适配器,体温数据工厂。

    5、编写ViewModel,通过‘工厂’操控数据。

    6、完善各个界面的逻辑代码。

    1)卡片视图界面,组件绑定,菜单绑定及菜单功能实现,界面跳转。

    2)折线图表界面,根据数据库数据,封装好点,线,轴的相关数据。

    3)录入体温界面,绑定组件,根据输入数据及当前系统时间更新数据库。

    四、体温统计APP编写

    1、构建底层数据库。

    1)表结构

     2)代码实体 :Entity

    package com.me.temperature;
    
    import androidx.room.ColumnInfo;
    import androidx.room.Entity;
    import androidx.room.PrimaryKey;
    
    @Entity(tableName = "temperature")
    public class temperature {
        @PrimaryKey(autoGenerate = true)
        private int id;
        @ColumnInfo(name = "tp")
        private String tp;
        @ColumnInfo(name = "time")
        private String time;
    
        public temperature(String tp, String time) {
            this.tp = tp;
            this.time = time;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getTp() {
            return tp;
        }
    
        public void setTp(String tp) {
            this.tp = tp;
        }
    
        public String getTime() {
            return time;
        }
    
        public void setTime(String time) {
            this.time = time;
        }
    }

    3)Dao

    package com.me.temperature;
    
    import androidx.lifecycle.LiveData;
    import androidx.room.Dao;
    import androidx.room.Delete;
    import androidx.room.Insert;
    import androidx.room.Query;
    import androidx.room.Update;
    
    import java.util.List;
    @Dao
    public interface TempDao {
        @Insert
        void insertTp (temperature ... temperatures);
        @Update
        void updateTp (temperature ... temperatures);
        @Delete
        void deleteTp (temperature ... temperatures);
        @Query("DELETE From TEMPERATURE")
        void deleteAllTp ();
        @Query("SELECT * From TEMPERATURE ORDER BY ID DESC")
        LiveData<List<temperature>> getAllTp ();
    }

    4)Database

    package com.me.temperature;
    
    import android.content.Context;
    
    import androidx.room.Database;
    import androidx.room.Room;
    import androidx.room.RoomDatabase;
    
    @Database(entities = {temperature.class },version = 1,exportSchema = false)
    public abstract class TempDatabase extends RoomDatabase {
        private static TempDatabase INSTANCE;
        public abstract TempDao getTempDao();
        static synchronized TempDatabase getTempDatabase(Context context){
            if (INSTANCE == null){
                INSTANCE = Room.databaseBuilder(context.getApplicationContext(),TempDatabase.class,"tp_database")
                        .build();
            }
            return INSTANCE;
        }
    }

    2、UI设计(卡片视图界面,单个卡片界面,折线图表界面,录入体温界面,菜单界面)

    1)卡片视图界面

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".AccountRecordFragment"
        android:id="@+id/frameLayout">
    
        <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/buttonTpAdd"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center_horizontal"
            android:layout_margin="16dp"
            android:clickable="true"
            android:focusable="true"
            android:src="@drawable/ic_add_witer_24dp"
            tools:layout_conversion_absoluteHeight="56dp"
            tools:layout_conversion_absoluteWidth="56dp"
            tools:layout_editor_absoluteX="178dp"
            tools:layout_editor_absoluteY="659dp" />
    
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            tools:layout_conversion_absoluteHeight="731dp"
            tools:layout_conversion_absoluteWidth="411dp"
            tools:layout_editor_absoluteX="0dp"
            tools:layout_editor_absoluteY="0dp" />
    </FrameLayout>

    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"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
    
        <androidx.cardview.widget.CardView
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <androidx.constraintlayout.widget.ConstraintLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginLeft="8dp"
                android:layout_marginTop="8dp"
                android:layout_marginRight="8dp"
                android:layout_marginBottom="4dp"
                android:foreground="?selectableItemBackground">
    
                <androidx.constraintlayout.widget.Guideline
                    android:id="@+id/guideline"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:orientation="vertical"
                    app:layout_constraintGuide_percent="0.1" />
    
                <TextView
                    android:id="@+id/textViewId"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="36sp"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toStartOf="@+id/guideline"
                    app:layout_constraintStart_toStartOf="parent"
                    app:layout_constraintTop_toTopOf="parent"
                    tools:text="1" />
    
                <TextView
                    android:id="@+id/textViewTp"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginTop="8dp"
                    android:layout_marginBottom="8dp"
                    android:textSize="36sp"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintEnd_toStartOf="@+id/textViewTime"
                    app:layout_constraintHorizontal_bias="0.5"
                    app:layout_constraintStart_toStartOf="@+id/guideline"
                    app:layout_constraintTop_toTopOf="parent" />
    
                <TextView
                    android:id="@+id/textViewTime"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginEnd="32dp"
                    android:layout_marginRight="32dp"
                    android:textSize="24sp"
                    app:layout_constraintBottom_toBottomOf="@+id/textViewTp"
                    app:layout_constraintEnd_toEndOf="parent"
                    app:layout_constraintHorizontal_bias="0.5"
                    app:layout_constraintStart_toEndOf="@+id/textViewTp"
                    app:layout_constraintTop_toTopOf="@+id/textViewTp" />
            </androidx.constraintlayout.widget.ConstraintLayout>
        </androidx.cardview.widget.CardView>
    </LinearLayout>

    3)折线图表界面

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="10dp">
    
        <lecho.lib.hellocharts.view.LineChartView
            android:id="@+id/chart"
            android:padding="20dp"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
    </LinearLayout>

    4)录入体温界面

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/frameLayout2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".AddFragment" >
    
        <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/add_title_tp"
            android:textSize="36sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.05" />
    
        <ImageView
            android:id="@+id/imageView2"
            android:layout_width="326dp"
            android:layout_height="262dp"
            android:layout_marginTop="8dp"
            android:contentDescription="@string/add_image"
            android:src="@drawable/temp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintDimensionRatio="1:1"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView"
            app:layout_constraintVertical_bias="0.05" />
    
        <Button
            android:id="@+id/buttonAdd"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="32dp"
            android:layout_marginLeft="32dp"
            android:layout_marginEnd="32dp"
            android:layout_marginRight="32dp"
            android:text="@string/add_but"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.7" />
    
        <EditText
            android:id="@+id/editTextTp"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginStart="32dp"
            android:layout_marginLeft="32dp"
            android:layout_marginEnd="32dp"
            android:layout_marginRight="32dp"
            android:ems="10"
            android:hint="@string/add_tp_in"
            android:importantForAutofill="no"
            android:inputType="number"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.6" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>

    5)菜单界面

    <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
    
        <item
            android:id="@+id/clearAll"
            android:title="@string/menu_claer" />
        <item
            android:id="@+id/chart"
            android:title="@string/menu_chart" />
    </menu>

    3、编写Navigation,将卡片视图界面,折线图表界面,录入体温界面加入其中,并确定界面跳转关系。

    <?xml version="1.0" encoding="utf-8"?>
    <navigation xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:id="@+id/navigation"
        app:startDestination="@id/investigationFragment">
    
        <fragment
            android:id="@+id/investigationFragment"
            android:name="com.me.temperature.InvestigationFragment"
            android:label="fragment_investigation"
            tools:layout="@layout/fragment_investigation" >
            <action
                android:id="@+id/action_investigationFragment_to_chartFragment"
                app:destination="@id/chartFragment" />
            <action
                android:id="@+id/action_investigationFragment_to_addFragment"
                app:destination="@id/addFragment" />
        </fragment>
        <fragment
            android:id="@+id/chartFragment"
            android:name="com.me.temperature.ChartFragment"
            android:label="fragment_chart"
            tools:layout="@layout/fragment_chart" />
        <fragment
            android:id="@+id/addFragment"
            android:name="com.me.temperature.AddFragment"
            android:label="fragment_add"
            tools:layout="@layout/fragment_add" >
            <action
                android:id="@+id/action_addFragment_to_investigationFragment"
                app:destination="@id/investigationFragment" />
        </fragment>
    </navigation>

    4、编写适配器,体温数据工厂。

    1)适配器

    package com.me.temperature;
    
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    import androidx.annotation.NonNull;
    import androidx.recyclerview.widget.RecyclerView;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class MyAdpter extends RecyclerView.Adapter <MyAdpter.MyViewHolder>{
        List<temperature> allTemperature = new ArrayList<>();
        public void setAllTemperature(List<temperature> allTemperature) {
            this.allTemperature = allTemperature;
        }
    
        @NonNull
        @Override
        public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
            View itemView = layoutInflater.inflate(R.layout.tp_cell,parent,false);
            MyViewHolder holder = new MyViewHolder(itemView);
            holder.itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
    
                }
            });
            return holder;
        }
    
    
        @Override
        public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
            temperature temperature = allTemperature.get(position);
            holder.textViewId.setText(String.valueOf(position+1));
            holder.textViewTime.setText(temperature.getTime());
            holder.textViewType.setText(temperature.getTp());
        }
    
        @Override
        public int getItemCount() {
            return allTemperature.size() ;
        }
    
        static class  MyViewHolder extends RecyclerView.ViewHolder{
            TextView textViewId,textViewType,textViewMoney,textViewTime;
            public MyViewHolder(@NonNull View itemView) {
                super(itemView);
                textViewId = itemView.findViewById(R.id.textViewId);
                textViewType = itemView.findViewById(R.id.textViewTp);
                textViewTime = itemView.findViewById(R.id.textViewTime);
            }
        }
    
    }

    2)工厂

    package com.me.temperature;
    
    import android.content.Context;
    import android.os.AsyncTask;
    
    import androidx.lifecycle.LiveData;
    
    import java.util.List;
    
    public class TpRepository {
        private LiveData<List<temperature>> allTemperature;
        private static List<temperature> allTemperatures;
    
        private TempDao tempDao;
        public TpRepository(Context context) {
            TempDatabase accountRecordDatabase = TempDatabase.getTempDatabase(context.getApplicationContext());
            tempDao = accountRecordDatabase.getTempDao();
            allTemperature = tempDao.getAllTp();
        }
    
        public LiveData<List<temperature>> getAllTemperature() {
            return allTemperature;
        }
        void insertTemperature(temperature ... temperatures){
            new InsertAsyncTask(tempDao).execute(temperatures);
        }
        void deleteAllTemperature(){
            new DeleteAsyncTask(tempDao).execute();
        }
        void deleteTemperature(temperature ... temperatures){
            new DeleteAsyncTask_2(tempDao).execute(temperatures);
        }
        static class InsertAsyncTask extends AsyncTask<temperature ,Void,Void> {
            private TempDao tempDao;
    
            public InsertAsyncTask(TempDao tempDao) {
                this.tempDao = tempDao;
            }
    
            @Override
            protected Void doInBackground(temperature... temperatures) {
                tempDao.insertTp(temperatures);
                return null;
            }
        }
        static class DeleteAsyncTask extends AsyncTask<Void ,Void,Void>{
            private TempDao tempDao;
    
            public DeleteAsyncTask(TempDao tempDao) {
                this.tempDao = tempDao;
            }
    
            @Override
            protected Void doInBackground(Void... Voids) {
                tempDao.deleteAllTp();
                return null;
            }
        }
        static class DeleteAsyncTask_2 extends AsyncTask<temperature ,Void,Void>{
            private TempDao tempDao;
    
            public DeleteAsyncTask_2(TempDao tempDao) {
                this.tempDao = tempDao;
            }
    
            @Override
            protected Void doInBackground(temperature... temperatures ) {
                tempDao.deleteTp(temperatures);
                return null;
            }
        }
    }

    5、编写ViewModel,通过‘工厂’操控数据。

    package com.me.temperature;
    
    import android.app.Application;
    
    import androidx.annotation.NonNull;
    import androidx.lifecycle.AndroidViewModel;
    import androidx.lifecycle.LiveData;
    
    import java.util.List;
    
    public class TpViewModel extends AndroidViewModel {
        private TpRepository tpRepository;
    
        public TpViewModel(@NonNull Application application) {
            super(application);
            tpRepository = new TpRepository((application));
        }
    
        public LiveData<List<temperature>> getAllTemperature() {
            return tpRepository.getAllTemperature();
        }
    
        void insertTemperature(temperature ... temperatures){
            tpRepository.insertTemperature(temperatures);
        }
        void deleteAllTemperature(){
            tpRepository.deleteAllTemperature();
        }
        void deleteTemperature(temperature ... temperatures){
            tpRepository.deleteTemperature(temperatures);
        }
    }

    6、完善各个界面的逻辑代码。

    1)卡片视图界面,组件绑定,菜单绑定及菜单功能实现,界面跳转。

    package com.me.temperature;
    
    
    import android.app.AlertDialog;
    import android.content.DialogInterface;
    import android.os.Bundle;
    import android.view.ContextMenu;
    import android.view.LayoutInflater;
    import android.view.Menu;
    import android.view.MenuInflater;
    import android.view.MenuItem;
    import android.view.View;
    import android.view.ViewGroup;
    
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.fragment.app.Fragment;
    import androidx.lifecycle.LiveData;
    import androidx.lifecycle.Observer;
    import androidx.lifecycle.ViewModelProviders;
    import androidx.navigation.NavController;
    import androidx.navigation.Navigation;
    import androidx.recyclerview.widget.ItemTouchHelper;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import androidx.recyclerview.widget.RecyclerView;
    
    import com.google.android.material.floatingactionbutton.FloatingActionButton;
    
    import java.util.List;
    
    
    /**
     * A simple {@link Fragment} subclass.
     */
    public class InvestigationFragment extends Fragment {
        private TpViewModel tpViewModel;
        private RecyclerView recyclerView;
        private MyAdpter myAdpter;
        private FloatingActionButton floatingActionButton;
        private LiveData<List<temperature>> findTemperature;
        private List<temperature> allTemperatures;
        public InvestigationFragment() {
            setHasOptionsMenu(true);
            // Required empty public constructor
        }
    
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            return inflater.inflate(R.layout.fragment_investigation, container, false);
        }
    
        @Override
        public boolean onOptionsItemSelected(@NonNull MenuItem item) {
    
            switch (item.getItemId()){
                case R.id.clearAll:
                    AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());
                    builder.setTitle("清空账单");
                    builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            tpViewModel.deleteAllTemperature();
                        }
                    });
                    builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
    
                        }
                    });
                    builder.create();
                    builder.show();
                    break;
                case R.id.chart:
                    NavController navController = Navigation.findNavController(requireActivity(),R.id.fragment);
                    navController.navigate(R.id.action_investigationFragment_to_chartFragment);
            }
            return super.onOptionsItemSelected(item);
        }
        @Override
        public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
            super.onCreateOptionsMenu(menu, inflater);
            inflater.inflate(R.menu.menu,menu);
        }
        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            tpViewModel = ViewModelProviders.of(requireActivity()).get(TpViewModel.class);
            recyclerView = requireActivity().findViewById(R.id.recyclerView);
            recyclerView.setLayoutManager(new LinearLayoutManager(requireActivity()));
            myAdpter = new MyAdpter();
            recyclerView.setAdapter(myAdpter);
            findTemperature =  tpViewModel.getAllTemperature();
            findTemperature.observe(requireActivity(), new Observer<List<temperature>>() {
                @Override
                public void onChanged(List<temperature> temperatures) {
                    allTemperatures = temperatures;
                    myAdpter.setAllTemperature(temperatures);
                    myAdpter.notifyDataSetChanged();
                }
            });
            new ItemTouchHelper(new ItemTouchHelper.SimpleCallback(0,ItemTouchHelper.START | ItemTouchHelper.END) {
                @Override
                public boolean onMove(@NonNull RecyclerView recyclerView, @NonNull RecyclerView.ViewHolder viewHolder, @NonNull RecyclerView.ViewHolder target) {
                    return false;
                }
    
                @Override
                public void onSwiped(@NonNull RecyclerView.ViewHolder viewHolder, int direction) {
                    temperature temperature = allTemperatures.get(viewHolder.getLayoutPosition());
                    tpViewModel.deleteTemperature(temperature);
                }
            }).attachToRecyclerView(recyclerView);
            floatingActionButton = requireActivity().findViewById(R.id.buttonTpAdd);
            floatingActionButton.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    NavController navController = Navigation.findNavController(v);
                    navController.navigate(R.id.action_investigationFragment_to_addFragment);
                }
            });
        }
    }

    2)折线图表界面,根据数据库数据,封装好点,线,轴的相关数据。

    package com.me.temperature;
    
    
    import android.graphics.Color;
    import android.os.Bundle;
    
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.fragment.app.Fragment;
    import androidx.lifecycle.ViewModelProviders;
    
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.TreeMap;
    
    import lecho.lib.hellocharts.model.Axis;
    import lecho.lib.hellocharts.model.AxisValue;
    import lecho.lib.hellocharts.model.Line;
    import lecho.lib.hellocharts.model.LineChartData;
    import lecho.lib.hellocharts.model.PointValue;
    import lecho.lib.hellocharts.model.ValueShape;
    import lecho.lib.hellocharts.util.ChartUtils;
    import lecho.lib.hellocharts.view.LineChartView;
    
    
    /**
     * A simple {@link Fragment} subclass.
     */
    public class ChartFragment extends Fragment {
        private LineChartView mChart;
        private Map<String,String> table = new TreeMap<>();
        private LineChartData mData;
        private TpViewModel tpViewModel;
        private List<AxisValue> mAxisXValues = new ArrayList<AxisValue>();
        private List<AxisValue> values = new ArrayList<>();
    
        public ChartFragment() {
            // Required empty public constructor
        }
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.fragment_chart, container, false);
        }
    
        @Override
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            mChart = view.findViewById(R.id.chart);
        }
    
        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            tpViewModel = ViewModelProviders.of(requireActivity()).get(TpViewModel.class);
            mData = new LineChartData();
            List<temperature> allDate = tpViewModel.getAllTemperature().getValue();
            generateValues(allDate);
            generateData();
        }
        private void generateData() {
            List<Line> lines = new ArrayList<>();
            List<PointValue> values = new ArrayList<>();
            int indexX = 0;
            for(String value : table.values()){
                char [] chars = value.toCharArray();
                String string = "";
                if(chars.length>0){
                    string += chars[0];
                }
                if(chars.length>1){
                    string += chars[1];
                }
                values.add(new PointValue(indexX, Integer.valueOf(string)));
                indexX++;
            }
            Line line = new Line(values);
            line.setColor(ChartUtils.COLORS[0]);
            line.setShape(ValueShape.CIRCLE);
            line.setPointColor(ChartUtils.COLORS[1]);
            lines.add(line);
            mData.setLines(lines);
            setAxis();
            mChart.setLineChartData(mData);
        }
    
        private void generateValues(List<temperature> allDate) {
            if(allDate != null){
                for (int i = 0; i < allDate.size(); i++) {
                    temperature costBean = allDate.get(i);
                    String costDate = costBean.getTime();
                    String costTp = costBean.getTp();
                    //mAxisXValues.add(new AxisValue(allDate.size() - i - 1).setLabel(costDate));
                    mAxisXValues.add(new AxisValue(i).setLabel(costDate));
                    if(!table.containsKey(costDate)){
                        table.put(costDate,costTp);
                        //mAxisXValues.add(new AxisValue(i).setLabel(costDate));
                    }else {
                        table.put(costDate,costTp);
                    }
                }
            }
        }
    
        private void setAxis() {
            //坐标轴
            Axis axisX = new Axis(); //X轴
            axisX.setHasTiltedLabels(true);  //X坐标轴字体是斜的显示还是直的,true是斜的显示
            axisX.setTextColor(Color.GRAY);  //设置字体颜色
            axisX.setName("日期");  //表格名称
            axisX.setTextSize(10);//设置字体大小
            axisX.setMaxLabelChars(7); //最多几个X轴坐标,意思就是你的缩放让X轴上数据的个数7<=x<=mAxisXValues.length
            axisX.setValues(mAxisXValues);  //填充X轴的坐标名称
            mData.setAxisXBottom(axisX); //x 轴在底部
            //data.setAxisXTop(axisX);  //x 轴在顶部
            axisX.setHasLines(true); //x 轴分割线
    
    
            Axis axisY = new Axis().setHasLines(true);
            axisY.setMaxLabelChars(6);//max label length, for example 60
    
            for(int i = 35; i < 45; i+= 1){
                AxisValue value = new AxisValue(i);
                String label = i + "℃";
                value.setLabel(label);
                values.add(value);
            }
            axisY.setValues(values);
            axisY.setName("体温");//y轴标注
            axisY.setTextSize(10);//设置字体大小
            mData.setAxisYLeft(axisY);  //Y轴设置在左边
            //data.setAxisYRight(axisY);  //y轴设置在右边
        }
    }

    3)录入体温界面,绑定组件,根据输入数据及当前系统时间更新数据库。

    package com.me.temperature;
    
    
    import android.os.Bundle;
    import android.text.Editable;
    import android.text.TextWatcher;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.Button;
    import android.widget.EditText;
    
    import androidx.annotation.Nullable;
    import androidx.fragment.app.Fragment;
    import androidx.fragment.app.FragmentActivity;
    import androidx.lifecycle.ViewModelProviders;
    import androidx.navigation.NavController;
    import androidx.navigation.Navigation;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    
    /**
     * A simple {@link Fragment} subclass.
     */
    public class AddFragment extends Fragment {
        private Button buttonSubmit;
        private EditText editTextTp;
        private TpViewModel tpViewModel;
    
        public AddFragment() {
            // Required empty public constructor
        }
    
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            // Inflate the layout for this fragment
            return inflater.inflate(R.layout.fragment_add, container, false);
        }
        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            FragmentActivity activity = requireActivity();
            tpViewModel = ViewModelProviders.of(activity).get(TpViewModel.class);
            buttonSubmit = activity.findViewById(R.id.buttonAdd);
            editTextTp = activity.findViewById(R.id.editTextTp);
            buttonSubmit.setEnabled(false);
            TextWatcher textWatcher = new TextWatcher() {
                @Override
                public void beforeTextChanged(CharSequence s, int start, int count, int after) {
                    String type = editTextTp.getText().toString().trim();
                    buttonSubmit.setEnabled(!type.isEmpty());
    
                }
    
                @Override
                public void onTextChanged(CharSequence s, int start, int before, int count) {
    
                }
    
                @Override
                public void afterTextChanged(Editable s) {
    
                }
            };
            editTextTp.addTextChangedListener(textWatcher);
            buttonSubmit.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String tp = editTextTp.getText().toString().trim();
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");// HH:mm:ss
                    //获取当前时间
                    Date date = new Date(System.currentTimeMillis());
                    temperature temperature = new temperature(tp+"℃",simpleDateFormat.format(date));
                    tpViewModel.insertTemperature(temperature);
                    NavController navController = Navigation.findNavController(v);
                    navController.navigate(R.id.action_addFragment_to_investigationFragment);
                }
            });
        }
    }
  • 相关阅读:
    java,jenkins
    docker compose,link,Odoo
    nginx,docker反向代理
    centos7上安装docker-ce社区版
    Install Rancher server
    docker公司测试环境搭建总结
    ansible+docker
    桥接物理网卡,pipwork指定ip,外网连接,研究salt+docker
    20170605
    20170602
  • 原文地址:https://www.cnblogs.com/20183544-wangzhengshuai/p/12286318.html
Copyright © 2020-2023  润新知