(一)四则运算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>

出题页面:顶部一个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>

成功页面:一个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>

失败页面:一个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>

程序设计:

首先是设计我们的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();
}
}

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

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

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();
}
}
整个项目到此完结。。。
花费时间:
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设计代码除外。

四则运算APP版的更多相关文章

  1. 结对编程项目——四则运算vs版

    结对编程项目--四则运算vs版 1)小伙伴信息:        学号:130201238 赵莹        博客地址:点我进入 小伙伴的博客 2)实现的功能: 实现带有用户界面的四则运算:将原只能在 ...

  2. 四则运算app工程的进展

    深入分析五个四则运算app: 1.ALM-Addition 缺点:版本是英文版,不利于孩子们弄懂.  用选择题的方法来选择正确的答案,固然有运气答对的成分,不利于统计真实的水平. 优点:有图标统计答题 ...

  3. 四则运算GUI版

    小学四则运算界面版 李永豪 201421123117 郑靖涛 201421123114 coding 地址:https://git.coding.net/ras/work2.git 一.题目描述 我们 ...

  4. 家居环境监測系统设计(PC上位机版)(手机APP版待定)

    下面是我的毕业设计:家居环境监測系统设计(PC上位机临时版.手机app版待定).本系统採用STC12C5A60S2单片机.结合传感器.分别对空气湿度.空气温度.气压.海拔.进水温度.出水温度.光照强度 ...

  5. 《软件工程》小组团队项目-小学生四则运算APP(First Sprint)

    <软件工程>团队项目我们小组选择了小学生四则运算APP,在上学期原有的项目基础上进行更新升级.(自我感觉我们团队上学期的小学生四则运算APP是较为成功且实用的,不过这学期学习到了新的知识, ...

  6. 小学四则运算APP 最后阶段

    团队成员:陈淑筠.杨家安.陈曦 团队选题:小学四则运算APP 这次发布的是我们APP的最终版本!图片背景有根据用户需求改变!还增加了草稿纸运算的画布功能! 运行结果如下: package com.ex ...

  7. 小学四则运算APP 第三阶段冲刺-第一天

    团队成员:陈淑筠.杨家安.陈曦 团队选题:小学四则运算APP 第三次冲刺阶段时间:12.12~12.19 本次发布的是音乐播放功能,可以根据用户需求一边播放音乐一边做题,也拥有暂停播放音乐的功能,增强 ...

  8. 小学四则运算APP 第二阶段冲刺-第五天

    团队成员:陈淑筠.杨家安.陈曦 团队选题:小学四则运算APP 第二次冲刺阶段时间:11.29~12.09 本次发布的是判断题代码,已经实现部分功能,,但是美中不足的是判断错误 panduanset.j ...

  9. 小学四则运算APP 第二次冲刺 第四天

    团队成员:陈淑筠.杨家安.陈曦 团队选题:小学四则运算APP 第二次冲刺阶段时间:11.29~12.09 本次发布的是合并后的选择题功能界面的设置: ChoiceSet.java: package c ...

随机推荐

  1. DJI大疆创新招聘-自动化测试工程师

    工作地点:深圳 简历发送:sue.li@dji.com 工作职责: 1. 参与自动化测试的设计和开发,参与需求分析和评审,评估合理性和完备性: 任职资格: 1. 本科及以上学历,计算机或软件工程相关专 ...

  2. All Tips

    Outlook分享心得 这是在爱奇艺的一场Outlook分享会上我记录的笔记. Read More 分享一点"关于应届生如何写简历"的人生经验 应届生如何写好一份求职简历是一件重要 ...

  3. 使用TensorFlow训练自己的语音识别AI

    这次来训练一个基于CNN的语音识别模型.训练完成后,我们将尝试将此模型用于Hotword detection. 人类是怎样听懂一句话的呢?以汉语为例,当听到"wo shi"的录音时 ...

  4. 斑马难题Step by Step

    问题描述 分析 代码 在exercism.io被这个 Zebra Puzzle 难住了.这里一步一步的解决... 1.There are five houses. 2.The Englishman l ...

  5. 7-49 求前n项的阶乘之和 (15 分)

    从键盘输入一个整数n,求前n项的阶乘之和,1+2!+3!+...+n!的和 输入格式: 输入一个大于1的整数.例如:输入20. 输出格式: 输出一个整数.例如:2561327494111820313. ...

  6. idea导入 spring framework项目

    准备的环境:gradle,idea 注意:gradle版本不一致会报各种错误,那么怎么查找依赖的版本呢? 首先在git上把spring framework项目拉取下来, 步骤一:复制URL路径 步骤二 ...

  7. [转帖]RSYNC 的核心算法

    RSYNC 的核心算法 https://coolshell.cn/articles/7425.html rsync是unix/linux下同步文件的一个高效算法,它能同步更新两处计算机的文件与目录,并 ...

  8. Python——工厂模式

    目录 前言 一.简单工厂 二.工厂方法 抽象工厂 结论 参考 前言 工厂模式,顾名思义就是我们可以通过一个指定的"工厂"获得需要的"产品". 在设计模式中主要用 ...

  9. Python爬虫 抓肺炎疫情实时数据

    数据下载 网上一搜,首先搜到的是腾讯的疫情实时追踪,那就用这个数据源吧. 有了网址怎么抓数据呢?这里,可以从纷乱中找到最靠谱的下载方式.我习惯用FireFox浏览器,下面的讲解就以FireFox为例( ...

  10. 研究开源源码之Myrmec

    好久没写博客了,自己也弄不清是懒了还是忙了.毕竟白天需要工作,晚上有时候看看资料,有时候陪家人,有时候约朋友......更加累了,可能由于累了就懒得总结了. 今天有同事问我关于代码检查文件类型的问题. ...