四则运算APP版

  • 2020 年 3 月 29 日
  • 筆記

(一)四则运算APP版

这这个Demo的目的就是强化一下本周学习的Android的Jetpack里的新内容,接下来我将通过这个Demo来展示我所学到的新知识。

先列出新学到的知识:ViewModel,Navigation,MutableLiveData,ViewModelSaveState,SharedPreferences,AndroidViewModel,DataBinding

设计思路:

UI设计思路:

一共四个页面:首页,习题页,成功页,失败页

将这四个页面通过Navigation连接起来形成一条逻辑关系。

 

 

 接下来就是对每个页面进行设计。

首页:一个TextView和一个ImageView还有一个Button,顶部还有一个最高分Textview,通过button来进入出题页面

<?xml version="1.0" encoding="utf-8"?>  <layout 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">        <data>          <variable              name="data"              type="com.example.calculation.MyViewModel" />      </data>        <androidx.constraintlayout.widget.ConstraintLayout          android:layout_width="match_parent"          android:layout_height="match_parent"          tools:context=".TitleFragment">            <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" />            <androidx.constraintlayout.widget.Guideline              android:id="@+id/guideline2"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:orientation="vertical"              app:layout_constraintGuide_percent="0.9" />            <TextView              android:id="@+id/textView"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="@string/CalName"              android:textSize="@dimen/huge_size"              app:layout_constraintBottom_toBottomOf="parent"              app:layout_constraintEnd_toStartOf="@+id/guideline2"              app:layout_constraintStart_toStartOf="@+id/guideline"              app:layout_constraintTop_toTopOf="parent"              app:layout_constraintVertical_bias="0.106" />            <ImageView              android:id="@+id/imageView"              android:layout_width="320dp"              android:layout_height="349dp"              android:contentDescription="@string/title_image"              android:src="@drawable/size"              app:layout_constraintBottom_toBottomOf="parent"              app:layout_constraintDimensionRatio="w,1:1"              app:layout_constraintEnd_toStartOf="@+id/guideline2"              app:layout_constraintHorizontal_bias="0.56"              app:layout_constraintStart_toStartOf="@+id/guideline"              app:layout_constraintTop_toTopOf="parent" />            <Button              android:id="@+id/button"              android:layout_width="0dp"              android:layout_height="wrap_content"              android:text="@string/title_button"              app:layout_constraintBottom_toBottomOf="parent"              app:layout_constraintEnd_toStartOf="@+id/guideline2"              app:layout_constraintHorizontal_bias="0.0"              app:layout_constraintStart_toStartOf="@+id/guideline"              app:layout_constraintTop_toTopOf="parent"              app:layout_constraintVertical_bias="0.862" />            <TextView              android:id="@+id/textView2"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="@{@string/higer_score(data.highScore)}"              app:layout_constraintBottom_toBottomOf="parent"              app:layout_constraintEnd_toEndOf="parent"              app:layout_constraintHorizontal_bias="0.883"              app:layout_constraintStart_toStartOf="parent"              app:layout_constraintTop_toTopOf="parent"              app:layout_constraintVertical_bias="0.036"              tools:text="High Score:%d" />      </androidx.constraintlayout.widget.ConstraintLayout>  </layout>

View Code

 

 

 

 

出题页面:顶部一个textview代表目前的得分情况,中间是一个算式,下面是你的答案,接下来是4行3列,12个按钮代表你的操作。

<?xml version="1.0" encoding="utf-8"?>  <layout 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">        <data>          <variable              name="data"              type="com.example.calculation.MyViewModel" />      </data>        <androidx.constraintlayout.widget.ConstraintLayout          android:layout_width="match_parent"          android:layout_height="match_parent"          tools:context=".QuestionFragment">            <androidx.constraintlayout.widget.Guideline              android:id="@+id/guideline3"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:orientation="horizontal"              app:layout_constraintGuide_percent="0.1" />            <androidx.constraintlayout.widget.Guideline              android:id="@+id/guideline4"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:orientation="horizontal"              app:layout_constraintGuide_percent="0.2" />            <androidx.constraintlayout.widget.Guideline              android:id="@+id/guideline5"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:orientation="horizontal"              app:layout_constraintGuide_percent="0.33" />            <androidx.constraintlayout.widget.Guideline              android:id="@+id/guideline6"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:orientation="horizontal"              app:layout_constraintGuide_percent="0.4" />            <androidx.constraintlayout.widget.Guideline              android:id="@+id/guideline10"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:orientation="horizontal"              app:layout_constraintGuide_percent="0.5" />            <androidx.constraintlayout.widget.Guideline              android:id="@+id/guideline11"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:orientation="horizontal"              app:layout_constraintGuide_percent="0.6" />            <androidx.constraintlayout.widget.Guideline              android:id="@+id/guideline12"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:orientation="horizontal"              app:layout_constraintGuide_percent="0.7" />            <androidx.constraintlayout.widget.Guideline              android:id="@+id/guideline7"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:orientation="horizontal"              app:layout_constraintGuide_percent="0.8" />            <TextView              android:id="@+id/textView3"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="@{@string/Current_Score(data.currentScore)}"              app:layout_constraintBottom_toTopOf="@+id/guideline3"              app:layout_constraintEnd_toStartOf="@+id/guideline9"              app:layout_constraintHorizontal_bias="0.537"              app:layout_constraintStart_toStartOf="@+id/guideline8"              app:layout_constraintTop_toTopOf="@+id/guideline3"              app:layout_constraintVertical_bias="0.473"              tools:text="Score:0" />            <androidx.constraintlayout.widget.Guideline              android:id="@+id/guideline8"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:orientation="vertical"              app:layout_constraintGuide_percent="0.1" />            <androidx.constraintlayout.widget.Guideline              android:id="@+id/guideline9"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:orientation="vertical"              app:layout_constraintGuide_percent="0.9" />            <TextView              android:id="@+id/textView4"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:textSize="@dimen/huge_size"              android:text="@{String.valueOf(data.leftNumber)}"              app:layout_constraintBottom_toBottomOf="@+id/textView5"              app:layout_constraintEnd_toStartOf="@+id/textView5"              app:layout_constraintHorizontal_bias="0.5"              app:layout_constraintStart_toStartOf="@+id/guideline8"              app:layout_constraintTop_toTopOf="@+id/textView5"              tools:text="1" />            <TextView              android:id="@+id/textView5"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:textSize="@dimen/huge_size"              android:text="@{String.valueOf(data.operator)}"              app:layout_constraintBottom_toBottomOf="@+id/textView6"              app:layout_constraintEnd_toStartOf="@+id/textView6"              app:layout_constraintHorizontal_bias="0.5"              app:layout_constraintStart_toEndOf="@+id/textView4"              app:layout_constraintTop_toTopOf="@+id/textView6"              tools:text="+" />            <TextView              android:id="@+id/textView6"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:textSize="@dimen/huge_size"              android:text="@{String.valueOf(data.rigthNumber)}"              app:layout_constraintBottom_toBottomOf="@+id/textView7"              app:layout_constraintEnd_toStartOf="@+id/textView7"              app:layout_constraintHorizontal_bias="0.5"              app:layout_constraintStart_toEndOf="@+id/textView5"              app:layout_constraintTop_toTopOf="@+id/textView7"              tools:text="2" />            <TextView              android:id="@+id/textView7"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="="              android:textSize="@dimen/huge_size"              app:layout_constraintBottom_toBottomOf="@+id/textView8"              app:layout_constraintEnd_toStartOf="@+id/textView8"              app:layout_constraintHorizontal_bias="0.5"              app:layout_constraintStart_toEndOf="@+id/textView6"              app:layout_constraintTop_toTopOf="@+id/textView8"              tools:text="=" />            <TextView              android:id="@+id/textView8"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="@string/Cal_Answer"              android:textSize="@dimen/huge_size"              app:layout_constraintBottom_toTopOf="@+id/guideline4"              app:layout_constraintEnd_toStartOf="@+id/guideline9"              app:layout_constraintHorizontal_bias="0.5"              app:layout_constraintStart_toEndOf="@+id/textView7"              app:layout_constraintTop_toTopOf="@+id/guideline4" />            <TextView              android:id="@+id/textView9"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="Your Answer:"              android:textSize="@dimen/mid_size"              app:layout_constraintBottom_toTopOf="@+id/guideline5"              app:layout_constraintEnd_toStartOf="@+id/guideline9"              app:layout_constraintStart_toStartOf="@+id/guideline8"              app:layout_constraintTop_toTopOf="@+id/guideline5" />            <Button              android:id="@+id/button1"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="1"              android:textSize="@dimen/button_size"              app:layout_constraintBottom_toTopOf="@+id/guideline10"              app:layout_constraintEnd_toStartOf="@+id/button2"              app:layout_constraintHorizontal_bias="0.5"              app:layout_constraintStart_toStartOf="@+id/guideline8"              app:layout_constraintTop_toTopOf="@+id/guideline6" />            <Button              android:id="@+id/button2"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="2"              android:textSize="@dimen/button_size"              app:layout_constraintBottom_toBottomOf="@+id/button1"              app:layout_constraintEnd_toStartOf="@+id/button3"              app:layout_constraintHorizontal_bias="0.5"              app:layout_constraintStart_toEndOf="@+id/button1"              app:layout_constraintTop_toTopOf="@+id/button1" />            <Button              android:id="@+id/button3"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="3"              android:textSize="@dimen/button_size"              app:layout_constraintBottom_toBottomOf="@+id/button2"              app:layout_constraintEnd_toStartOf="@+id/guideline9"              app:layout_constraintHorizontal_bias="0.5"              app:layout_constraintStart_toEndOf="@+id/button2"              app:layout_constraintTop_toTopOf="@+id/button2" />            <Button              android:id="@+id/button4"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="4"              android:textSize="@dimen/button_size"              app:layout_constraintBottom_toTopOf="@+id/guideline11"              app:layout_constraintEnd_toStartOf="@+id/button5"              app:layout_constraintHorizontal_bias="0.5"              app:layout_constraintStart_toStartOf="@+id/guideline8"              app:layout_constraintTop_toTopOf="@+id/guideline10" />            <Button              android:id="@+id/button5"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="5"              android:textSize="@dimen/button_size"              app:layout_constraintBottom_toBottomOf="@+id/button4"              app:layout_constraintEnd_toStartOf="@+id/button6"              app:layout_constraintHorizontal_bias="0.5"              app:layout_constraintStart_toEndOf="@+id/button4"              app:layout_constraintTop_toTopOf="@+id/button4" />            <Button              android:id="@+id/button6"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="6"              android:textSize="@dimen/button_size"              app:layout_constraintBottom_toBottomOf="@+id/button5"              app:layout_constraintEnd_toStartOf="@+id/guideline9"              app:layout_constraintHorizontal_bias="0.5"              app:layout_constraintStart_toEndOf="@+id/button5"              app:layout_constraintTop_toTopOf="@+id/button5" />            <Button              android:id="@+id/button7"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="7"              android:textSize="@dimen/button_size"              app:layout_constraintBottom_toTopOf="@+id/guideline12"              app:layout_constraintEnd_toStartOf="@+id/button8"              app:layout_constraintHorizontal_bias="0.5"              app:layout_constraintStart_toStartOf="@+id/guideline8"              app:layout_constraintTop_toTopOf="@+id/guideline11" />            <Button              android:id="@+id/button8"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="8"              android:textSize="@dimen/button_size"              app:layout_constraintBottom_toBottomOf="@+id/button7"              app:layout_constraintEnd_toStartOf="@+id/button9"              app:layout_constraintHorizontal_bias="0.5"              app:layout_constraintStart_toEndOf="@+id/button7"              app:layout_constraintTop_toTopOf="@+id/button7" />            <Button              android:id="@+id/button9"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="9"              android:textSize="@dimen/button_size"              app:layout_constraintBottom_toBottomOf="@+id/button8"              app:layout_constraintEnd_toStartOf="@+id/guideline9"              app:layout_constraintHorizontal_bias="0.5"              app:layout_constraintStart_toEndOf="@+id/button8"              app:layout_constraintTop_toTopOf="@+id/button8" />            <Button              android:id="@+id/clear"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="Clear"              android:textSize="@dimen/button_size"              app:layout_constraintBottom_toTopOf="@+id/guideline7"              app:layout_constraintEnd_toStartOf="@+id/button0"              app:layout_constraintHorizontal_bias="0.5"              app:layout_constraintStart_toStartOf="@+id/guideline8"              app:layout_constraintTop_toTopOf="@+id/guideline12" />            <Button              android:id="@+id/button0"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="0"              android:textSize="@dimen/button_size"              app:layout_constraintBottom_toBottomOf="@+id/clear"              app:layout_constraintEnd_toStartOf="@+id/submit"              app:layout_constraintHorizontal_bias="0.5"              app:layout_constraintStart_toEndOf="@+id/clear"              app:layout_constraintTop_toTopOf="@+id/clear" />            <Button              android:id="@+id/submit"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="OK"              android:textSize="@dimen/button_size"              app:layout_constraintBottom_toBottomOf="@+id/button0"              app:layout_constraintEnd_toStartOf="@+id/guideline9"              app:layout_constraintHorizontal_bias="0.5"              app:layout_constraintStart_toEndOf="@+id/button0"              app:layout_constraintTop_toTopOf="@+id/button0" />      </androidx.constraintlayout.widget.ConstraintLayout>  </layout>

View Code

 

 

 

 

成功页面:一个Imageview笑脸,两个Textview还有一个Button来返回首页

<?xml version="1.0" encoding="utf-8"?>  <layout 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">        <data>          <variable              name="data"              type="com.example.calculation.MyViewModel" />      </data>        <androidx.constraintlayout.widget.ConstraintLayout          android:layout_width="match_parent"          android:layout_height="match_parent"          tools:context=".WinFragment">            <androidx.constraintlayout.widget.Guideline              android:id="@+id/guideline13"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:orientation="horizontal"              app:layout_constraintGuide_percent="0.1" />            <androidx.constraintlayout.widget.Guideline              android:id="@+id/guideline14"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:orientation="horizontal"              app:layout_constraintGuide_percent="0.35" />            <ImageView              android:id="@+id/imageView2"              android:layout_width="0dp"              android:layout_height="0dp"              android:contentDescription="@string/image_win"              android:src="@drawable/ic_sentiment_satisfied_black_24dp"              app:layout_constraintBottom_toTopOf="@+id/guideline14"              app:layout_constraintEnd_toEndOf="parent"              app:layout_constraintStart_toStartOf="parent"              app:layout_constraintTop_toTopOf="@+id/guideline13" />            <TextView              android:id="@+id/textView10"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="恭喜你!创下新纪录"              android:textSize="@dimen/bige_size"              app:layout_constraintBottom_toBottomOf="parent"              app:layout_constraintEnd_toEndOf="parent"              app:layout_constraintStart_toStartOf="parent"              app:layout_constraintTop_toTopOf="@+id/guideline14"              app:layout_constraintVertical_bias="0.1" />            <TextView              android:id="@+id/textView11"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="@{@string/New_Score(data.highScore)}"              android:textSize="@dimen/bige_size"              app:layout_constraintBottom_toBottomOf="parent"              app:layout_constraintEnd_toEndOf="parent"              app:layout_constraintStart_toStartOf="parent"              app:layout_constraintTop_toBottomOf="@+id/imageView2"              app:layout_constraintVertical_bias="0.3"              tools:text="你的成绩是:%d" />            <Button              android:id="@+id/button10"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="返回"              app:layout_constraintBottom_toBottomOf="parent"              app:layout_constraintEnd_toEndOf="parent"              app:layout_constraintHorizontal_bias="0.498"              app:layout_constraintStart_toStartOf="parent"              app:layout_constraintTop_toTopOf="@+id/guideline14"              app:layout_constraintVertical_bias="0.5" />      </androidx.constraintlayout.widget.ConstraintLayout>  </layout>

View Code

 

 

 

 

失败页面:一个Imageview哭脸,两个Textview还有一个Button来返回首页

<?xml version="1.0" encoding="utf-8"?>  <layout 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">        <data>          <variable              name="data"              type="com.example.calculation.MyViewModel" />      </data>        <androidx.constraintlayout.widget.ConstraintLayout          android:layout_width="match_parent"          android:layout_height="match_parent"          tools:context=".LoseFragment">            <androidx.constraintlayout.widget.Guideline              android:id="@+id/guideline15"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:orientation="horizontal"              app:layout_constraintGuide_percent="0.1" />            <androidx.constraintlayout.widget.Guideline              android:id="@+id/guideline16"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:orientation="horizontal"              app:layout_constraintGuide_percent="0.35" />            <ImageView              android:id="@+id/imageView3"              android:layout_width="0dp"              android:layout_height="0dp"              android:src="@drawable/ic_sentiment_dissatisfied_black_24dp"              app:layout_constraintBottom_toTopOf="@+id/guideline16"              app:layout_constraintEnd_toEndOf="parent"              app:layout_constraintStart_toStartOf="parent"              app:layout_constraintTop_toTopOf="@+id/guideline15" />            <TextView              android:id="@+id/textView13"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="@{@string/New_Score(data.currentScore)}"              android:textSize="@dimen/bige_size"              app:layout_constraintBottom_toBottomOf="parent"              app:layout_constraintEnd_toEndOf="parent"              app:layout_constraintStart_toStartOf="parent"              app:layout_constraintTop_toTopOf="@+id/guideline16"              app:layout_constraintVertical_bias="0.3"              tools:text="你的成绩是:%d" />            <Button              android:id="@+id/button11"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="返回"              app:layout_constraintBottom_toBottomOf="parent"              app:layout_constraintEnd_toEndOf="parent"              app:layout_constraintHorizontal_bias="0.498"              app:layout_constraintStart_toStartOf="parent"              app:layout_constraintTop_toTopOf="@+id/guideline16"              app:layout_constraintVertical_bias="0.5" />            <TextView              android:id="@+id/textView14"              android:layout_width="wrap_content"              android:layout_height="wrap_content"              android:text="挑战失败!"              android:textSize="@dimen/bige_size"              app:layout_constraintBottom_toBottomOf="parent"              app:layout_constraintEnd_toEndOf="parent"              app:layout_constraintStart_toStartOf="parent"              app:layout_constraintTop_toBottomOf="@+id/imageView3"              app:layout_constraintVertical_bias="0.1" />      </androidx.constraintlayout.widget.ConstraintLayout>  </layout>

View Code

 

 

 

 

程序设计:

首先是设计我们的MyViewModel里的数据,有最高分,目前得分,左操作数,右操作数,操作符,答案

通过SharedPreferences来保存数据,livedata可以随时的刷新数据,故用它来显示数据。

package com.example.calculation;    import android.app.Application;  import android.content.Context;  import android.content.SharedPreferences;    import androidx.annotation.NonNull;  import androidx.lifecycle.AndroidViewModel;  import androidx.lifecycle.MutableLiveData;  import androidx.lifecycle.SavedStateHandle;  import androidx.lifecycle.ViewModel;    import java.util.Random;    public class MyViewModel extends AndroidViewModel {      private SavedStateHandle handle;      private static String KEY_HIGH_SCORE="key_high_score";      private static String KEY_LEFT_NUMBER="key_left_number";      private static String KEY_RIGHT_NUMBER="key_right_number";      private static String KEY_OPERATOR="key_operator";      private static String KEY_ANSWER="key_answer";      private static String SAVE_SHP_DATA_NAME="save_shp_data_name";      private static String KEY_CURRENT_SCORE="key_current_score";      public boolean win_flag=false;            public MyViewModel(@NonNull Application application,SavedStateHandle handle) {          super(application);          if(!handle.contains(KEY_HIGH_SCORE)){              SharedPreferences shp=getApplication().getSharedPreferences(SAVE_SHP_DATA_NAME, Context.MODE_PRIVATE);              handle.set(KEY_HIGH_SCORE,shp.getInt(KEY_HIGH_SCORE,0));              handle.set(KEY_LEFT_NUMBER,0);              handle.set(KEY_RIGHT_NUMBER,0);              handle.set(KEY_OPERATOR,"+");              handle.set(KEY_ANSWER,0);              handle.set(KEY_CURRENT_SCORE,0);          }          this.handle=handle;      }      public MutableLiveData<Integer> getLeftNumber(){          return handle.getLiveData(KEY_LEFT_NUMBER);      }      public MutableLiveData<Integer> getRigthNumber(){          return handle.getLiveData(KEY_RIGHT_NUMBER);      }      public MutableLiveData<String> getOperator(){          return handle.getLiveData(KEY_OPERATOR);      }      public MutableLiveData<Integer> getHighScore(){          return handle.getLiveData(KEY_HIGH_SCORE);      }      public MutableLiveData<Integer> getCurrentScore(){          return handle.getLiveData(KEY_CURRENT_SCORE);      }      public MutableLiveData<Integer> getAnswer(){          return handle.getLiveData(KEY_ANSWER);      }        public void setCurrentScore(){          handle.set(KEY_CURRENT_SCORE,0);      }        void generator(){          int level=100;          Random random=new Random();          int a=random.nextInt(level)+1;          int b=random.nextInt(level)+1;          if(a%4==0){              getOperator().setValue("+");              if(a>b){                  getAnswer().setValue(a);                  getLeftNumber().setValue(b);                  getRigthNumber().setValue(a-b);              }else{                  getOperator().setValue("+");                  getAnswer().setValue(b);                  getLeftNumber().setValue(a);                  getRigthNumber().setValue(b-a);              }          }          else if(a%4==1){              getOperator().setValue("-");              if(a>b){                  getAnswer().setValue(a-b);                  getLeftNumber().setValue(a);                  getRigthNumber().setValue(b);              }else{                  getOperator().setValue("-");                  getAnswer().setValue(b-a);                  getLeftNumber().setValue(b);                  getRigthNumber().setValue(a);              }          }          else if(a%4==2){              getOperator().setValue("*");              getLeftNumber().setValue(a);              getRigthNumber().setValue(b);              getAnswer().setValue(a*b);          }          else if(a%4==3){              getOperator().setValue("/");              while(a%b!=0){                  a=random.nextInt(level)+1;                  b=random.nextInt(level)+1;              }              getLeftNumber().setValue(a);              getRigthNumber().setValue(b);              getAnswer().setValue(a/b);          }      }      void save(){          SharedPreferences shp=getApplication().getSharedPreferences(SAVE_SHP_DATA_NAME,Context.MODE_PRIVATE);          SharedPreferences.Editor editor=shp.edit();          editor.putInt(KEY_HIGH_SCORE,getHighScore().getValue());          editor.apply();      }      void answerCurrent(){          getCurrentScore().setValue(getCurrentScore().getValue()+1);          if(getCurrentScore().getValue()>getHighScore().getValue()){              getHighScore().setValue(getCurrentScore().getValue());              win_flag=true;          }          generator();      }  }

View Code

TieleFragment的设计:设计一个按钮的绑定事件,进行跳转到出题页面

package com.example.calculation;    import android.app.AppComponentFactory;  import android.app.Application;  import android.content.pm.ApplicationInfo;  import android.os.Bundle;    import androidx.annotation.NonNull;  import androidx.appcompat.app.AppCompatActivity;  import androidx.databinding.DataBindingUtil;  import androidx.fragment.app.Fragment;  import androidx.lifecycle.SavedStateViewModelFactory;  import androidx.lifecycle.ViewModelProvider;  import androidx.lifecycle.ViewModelProviders;  import androidx.navigation.NavController;  import androidx.navigation.Navigation;    import android.view.LayoutInflater;  import android.view.View;  import android.view.ViewGroup;    import com.example.calculation.databinding.FragmentTitleBinding;      /**   * A simple {@link Fragment} subclass.   */  public class TitleFragment extends Fragment{          public TitleFragment() {          // Required empty public constructor      }          @Override      public View onCreateView(@NonNull LayoutInflater inflater, final ViewGroup container,                               Bundle savedInstanceState) {            FragmentTitleBinding binding;          binding= DataBindingUtil.inflate(inflater,R.layout.fragment_title,container,false);          MyViewModel myViewModel = ViewModelProviders.of(requireActivity(), new SavedStateViewModelFactory(requireActivity().getApplication(),requireActivity())).get(MyViewModel.class);          binding.setData(myViewModel);          binding.setLifecycleOwner(requireActivity());          binding.button.setOnClickListener(new View.OnClickListener() {              @Override              public void onClick(View v) {                  NavController controller=Navigation.findNavController(v);                  controller.navigate(R.id.action_titleFragment_to_questionFragment);              }          });          return binding.getRoot();          // Inflate the layout for this fragment          //return inflater.inflate(R.layout.fragment_title, container, false);      }      }

View Code

QuestionFragment的设计:通过按钮点击来获取用户的答案,然后从数据里获取当前的viewmodel,判断结果是否相同,之后进行相应的操作。

里面有代码注释

package com.example.calculation;    import android.os.Bundle;    import androidx.databinding.DataBindingUtil;  import androidx.fragment.app.Fragment;  import androidx.lifecycle.SavedStateViewModelFactory;  import androidx.lifecycle.ViewModelProvider;  import androidx.lifecycle.ViewModelProviders;  import androidx.navigation.NavController;  import androidx.navigation.Navigation;    import android.view.LayoutInflater;  import android.view.View;  import android.view.ViewGroup;  import android.widget.Toast;    import com.example.calculation.databinding.FragmentQuestionBinding;      /**   * A simple {@link Fragment} subclass.   */  public class QuestionFragment extends Fragment {        public QuestionFragment() {          // Required empty public constructor      }          @Override      public View onCreateView(LayoutInflater inflater, final ViewGroup container,                               Bundle savedInstanceState) {          final MyViewModel myViewModel;          myViewModel= ViewModelProviders.of(requireActivity(),new SavedStateViewModelFactory(requireActivity().getApplication(),requireActivity())).get(MyViewModel.class);          //获取运算表达式          myViewModel.generator();          //设置初始得分为0          myViewModel.setCurrentScore();          //获取页面的控制binding          final FragmentQuestionBinding binding;          binding= DataBindingUtil.inflate(inflater,R.layout.fragment_question,container,false);          //设置数据与生命周期          binding.setData(myViewModel);          binding.setLifecycleOwner(requireActivity());          //builder用来保存用户输入的数据          final StringBuilder builder=new StringBuilder();          View.OnClickListener listener=new View.OnClickListener() {              @Override              public void onClick(View v) {                      switch (v.getId()){                          case R.id.button0:                              builder.append(0);                              break;                          case R.id.button1:                              builder.append(1);                              break;                          case R.id.button2:                              builder.append(2);                              break;                          case R.id.button3:                              builder.append(3);                              break;                          case R.id.button4:                              builder.append(4);                              break;                          case R.id.button5:                              builder.append(5);                              break;                          case R.id.button6:                              builder.append(6);                              break;                          case R.id.button7:                              builder.append(7);                              break;                          case R.id.button8:                              builder.append(8);                              break;                          case R.id.button9:                              builder.append(9);                              break;                          case R.id.clear:                              //清楚代表用户的输入长度未0                              builder.setLength(0);                              break;                      }                      if(builder.length()==0){                          binding.textView9.setText("请输入你的答案:");                      }else{                          //显示到UI页面上                          binding.textView9.setText(builder.toString());                      }              }          };          //设置每一个按钮的点击事件          binding.button0.setOnClickListener(listener);          binding.button1.setOnClickListener(listener);          binding.button2.setOnClickListener(listener);          binding.button3.setOnClickListener(listener);          binding.button4.setOnClickListener(listener);          binding.button5.setOnClickListener(listener);          binding.button6.setOnClickListener(listener);          binding.button7.setOnClickListener(listener);          binding.button8.setOnClickListener(listener);          binding.button9.setOnClickListener(listener);          binding.clear.setOnClickListener(listener);          //提交按钮的设计          binding.submit.setOnClickListener(new View.OnClickListener() {              @Override              public void onClick(View v) {                  if(builder.length()!=0) {                      //当答案相同时                      if (Integer.valueOf(builder.toString()).intValue() == myViewModel.getAnswer().getValue()) {                          myViewModel.answerCurrent();                          builder.setLength(0);                          binding.textView9.setText("回答正确! 请继续!");                      } else {                          NavController controller = Navigation.findNavController(v);                          if (myViewModel.win_flag) {                              //当创造新纪录时,进入成功页面                              controller.navigate(R.id.action_questionFragment_to_winFragment);                              myViewModel.win_flag = false;                              myViewModel.save();                          } else {                              //否则进入失败页面                              controller.navigate(R.id.action_questionFragment_to_loseFragment);                          }                      }                  }else{                      Toast.makeText(v.getContext(), "请输入答案", Toast.LENGTH_SHORT).show();                  }              }          });          return binding.getRoot();          // Inflate the layout for this fragment          //return inflater.inflate(R.layout.fragment_question, container, false);      }  }

View Code

WinFragment的设计:设置它的返回按钮,与LoseFragment一样

package com.example.calculation;    import android.os.Bundle;    import androidx.databinding.DataBindingUtil;  import androidx.fragment.app.Fragment;  import androidx.lifecycle.SavedStateHandle;  import androidx.lifecycle.SavedStateViewModelFactory;  import androidx.lifecycle.ViewModelProvider;  import androidx.lifecycle.ViewModelProviders;  import androidx.navigation.NavController;  import androidx.navigation.Navigation;    import android.view.LayoutInflater;  import android.view.View;  import android.view.ViewGroup;    import com.example.calculation.databinding.FragmentWinBinding;      /**   * A simple {@link Fragment} subclass.   */  public class WinFragment extends Fragment {        public WinFragment() {          // Required empty public constructor      }          @Override      public View onCreateView(LayoutInflater inflater, ViewGroup container,                               Bundle savedInstanceState) {          MyViewModel myViewModel;          myViewModel= ViewModelProviders.of(requireActivity(), new SavedStateViewModelFactory(requireActivity().getApplication(),requireActivity())).get(MyViewModel.class);          FragmentWinBinding binding;          binding= DataBindingUtil.inflate(inflater,R.layout.fragment_win,container,false);          binding.setData(myViewModel);          binding.setLifecycleOwner(requireActivity());          binding.button10.setOnClickListener(new View.OnClickListener() {              @Override              public void onClick(View v) {                  NavController controller= Navigation.findNavController(v);                  controller.navigate(R.id.action_winFragment_to_titleFragment);              }          });          return binding.getRoot();          // Inflate the layout for this fragment          //return inflater.inflate(R.layout.fragment_win, container, false);      }  }

View Code

 

package com.example.calculation;    import android.os.Bundle;    import androidx.databinding.DataBindingUtil;  import androidx.fragment.app.Fragment;  import androidx.lifecycle.SavedStateViewModelFactory;  import androidx.lifecycle.ViewModelProvider;  import androidx.lifecycle.ViewModelProviders;  import androidx.navigation.NavController;  import androidx.navigation.Navigation;    import android.view.LayoutInflater;  import android.view.View;  import android.view.ViewGroup;    import com.example.calculation.databinding.FragmentLoseBinding;      /**   * A simple {@link Fragment} subclass.   */  public class LoseFragment extends Fragment {        public LoseFragment() {          // Required empty public constructor      }          @Override      public View onCreateView(LayoutInflater inflater, final ViewGroup container,                               Bundle savedInstanceState) {          MyViewModel myViewModel;          myViewModel= ViewModelProviders.of(requireActivity(),new  SavedStateViewModelFactory(requireActivity().getApplication(),requireActivity())).get(MyViewModel.class);          FragmentLoseBinding binding;          binding= DataBindingUtil.inflate(inflater,R.layout.fragment_lose,container,false);          binding.setData(myViewModel);          binding.setLifecycleOwner(requireActivity());          binding.button11.setOnClickListener(new View.OnClickListener() {              @Override              public void onClick(View v) {                  NavController controller= Navigation.findNavController(v);                  controller.navigate(R.id.action_loseFragment_to_titleFragment);              }          });          return binding.getRoot();          // Inflate the layout for this fragment          //return inflater.inflate(R.layout.fragment_lose, container, false);      }  }

View Code

MainActivity的设计:用来设置左上角的返回与手机左下方左三角的返回

package com.example.calculation;    import androidx.appcompat.app.AlertDialog;  import androidx.appcompat.app.AppCompatActivity;  import androidx.navigation.NavController;  import androidx.navigation.Navigation;  import androidx.navigation.ui.NavigationUI;    import android.app.Dialog;  import android.content.DialogInterface;  import android.os.Bundle;    public class MainActivity extends AppCompatActivity {      NavController controller;      @Override      protected void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.activity_main);          controller= Navigation.findNavController(this,R.id.fragment);          NavigationUI.setupActionBarWithNavController(this,controller);      }  //设置页面的左上角的返回操作      @Override      public boolean onSupportNavigateUp() {          if(controller.getCurrentDestination().getId()==R.id.questionFragment){              AlertDialog.Builder builder=new AlertDialog.Builder(this);              builder.setTitle("你确定要退出吗?");              builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {                  @Override                  public void onClick(DialogInterface dialog, int which) {                      controller.navigateUp();                  }              });              builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {                  @Override                  public void onClick(DialogInterface dialog, int which) {                    }              });              AlertDialog dialog=builder.create();              dialog.show();          }else{              controller.navigate(R.id.titleFragment);          }          return super.onSupportNavigateUp();      }  //设置手机的左三角的返回操作  @Override      public void onBackPressed() {          onSupportNavigateUp();      }  }

View Code


整个项目到此完结。。。
花费时间:
2020/3/29:上午10:00-11:10,休息10分钟,11:30-12:30,
2020/3/29:下午15:00-15:45,吃东西喝水10分钟,16:00-19:00,吃饭30分钟。
2020/3/29:晚上19:30-20:45,完成。
共花费:420分钟,代码量:450行,UI设计代码除外。