android------口算测试APP

时间:2022-08-04 17:50:23

    昨天一直在写一个测试口算的简单APP,但不知道怎么回事,算出题目的答案和存入的答案不一样,一直找,也没找到。导致昨天的博客没发,今天早上起来继续找,通过控制台发现题目给出的数字和控制台打印的数不一样,回过头看到界面,发现Textview太小,导致数字溢出。哎!!!!

  思想:首先就是需要四个fragment,一个首页,一个出题的,一个胜利,一个失败。打开app,进入首页,点击进入,进入到出题界面,然后答题,如果答题正确个数超过之前的记录,直到答错,回到胜利界面,然后点击返回就回到首页,如果答题正确个数没有超过之前的记录,则失败,回到失败界面,点击返回会到首页。自己的最高记录一直会在首页出现。

  首先我们想创建四个fragment(bank),(之前的文章有提过,不再说),然后在res创建一个类型为Navigation的文件夹,在生成的xml文件中将四个fragment按照跳转顺序连接起来,如下

   android------口算测试APP

 

 

   记住,最先来进来的是起始的fragmen,当然也可以改变。

  然后我们在绘制各个页面。

  TitleFragment:                              QuestionFragment:

android------口算测试APP                android------口算测试APP

 

 

 

 

  WinFragment:                              LoseFragment:

 

  android------口算测试APP             android------口算测试APP

 

 

    

 

    界面自己构造,关键是构造想法和各个组件的id。

 

    然后在activity_main.xml,将NavHostFragment拖入到ConstraintLayout里android------口算测试APP

 

 

    要保存数据,所以要新建一个ViewModel,因为要用LiveData,所以我们要在图像的xml文件里转换成liveData模式。

 

    以下为代码:

 

    MyViewModel(继承AndroidViewModel)

package com.example.calculationtest;

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 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"; // SharedPreferences 名字
    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 preferences = getApplication().getSharedPreferences(SAVE_SHP_DATA_NAME, Context.MODE_PRIVATE);
            // 第一次访问:初始化
            handle.set(KEY_HIGH_SCORE, preferences.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> getHighScore() { return handle.getLiveData(KEY_HIGH_SCORE); } public MutableLiveData<Integer> getLeftNumber() { return handle.getLiveData(KEY_LEFT_NUMBER); } public MutableLiveData<Integer> getRightNumber() { return handle.getLiveData(KEY_RIGHT_NUMBER); } public MutableLiveData<String> getOperator() { return handle.getLiveData(KEY_OPERATOR); } public MutableLiveData<Integer> getSaveName() { return handle.getLiveData(SAVE_SHP_DATA_NAME); } public MutableLiveData<Integer> getCurrentScore() { return handle.getLiveData(KEY_CURRENT_SCORE); } public MutableLiveData<Integer> getAnswer() { return handle.getLiveData(KEY_ANSWER); } // 产生式子 public void generator() { int LEVEL = 20, LEVEL2 = 2; int x, y; Random random = new Random(); // 产生随机数 // random.nextInt(LEVEL) 产生0-LEVEL-1范围的随机数 x = random.nextInt(LEVEL) 1; y = random.nextInt(LEVEL) 1; if (x%2 == 0) { // getOperator().setValue(" "); getLeftNumber().setValue(x); getRightNumber().setValue(y); getAnswer().setValue(x y); } else { // - getOperator().setValue("-"); if (x > y) { getLeftNumber().setValue(x); getRightNumber().setValue(y); getAnswer().setValue(x - y); } else { getLeftNumber().setValue(y); getRightNumber().setValue(x); getAnswer().setValue(y - x); } } } // 保留最高记录 public void save(){ SharedPreferences preferences = getApplication().getSharedPreferences(SAVE_SHP_DATA_NAME, Context.MODE_PRIVATE); SharedPreferences.Editor editor = preferences.edit(); // 保存最高记录 editor.putInt(KEY_HIGH_SCORE, getHighScore().getValue()); // 提交 editor.apply(); } // 回答正确 public void answerCorrect(){ // 当前分数 1 getCurrentScore().setValue(getCurrentScore().getValue() 1); // 如果当前的分数大于之前的最高立即,那么改变 if(getCurrentScore().getValue()>getHighScore().getValue()){ getHighScore().setValue(getCurrentScore().getValue()); win_flag = true; } // 回答正确,继续出题 generator(); } // 因为回答错误之间跳转到起始界面,所以这就不再写 }

 

 

 

 

    TitleFragment.java

package com.example.calculationtest;


import android.os.Bundle;

import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.SavedStateViewModelFactory;
import androidx.lifecycle.ViewModelProviders;
import androidx.lifecycle.ViewModelProvider;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.calculationtest.databinding.FragmentTitleFragment2Binding;


/**
 * A simple {@link Fragment} subclass.
 */
public class TitleFragment extends Fragment {


    public TitleFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, final ViewGroup container,
                             Bundle savedInstanceState) {
        MyViewModel myViewModel;
        myViewModel= ViewModelProviders.of(requireActivity(),new SavedStateViewModelFactory(getActivity().getApplication(), this)).get(MyViewModel.class);
        FragmentTitleFragment2Binding binding;
        binding = DataBindingUtil.inflate(inflater,R.layout.fragment_title_fragment2, 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_titleFragment2_to_questionFragment);
            }
        });
        return binding.getRoot();
        // Inflate the layout for this fragment
        //return inflater.inflate(R.layout.fragment_title_fragment2, container, false);
    }

}

 

  TitleFragment.xml

<?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.calculationtest.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/guideline27"
            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/guideline28"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.9" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@ id/guideline29"
            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/guideline30"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.25" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@ id/guideline31"
            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/guideline32"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.85" />

        <TextView
            android:id="@ id/textView16"
            android:layout_width="0dp"
            android:layout_height="40dp"
            android:layout_marginEnd="12dp"
            android:text="@{@string/best_grade(data.highScore)}"
            android:textSize="20sp"
            app:layout_constraintBottom_toTopOf="@ id/guideline29"
            app:layout_constraintEnd_toStartOf="@ id/guideline28"
            app:layout_constraintHorizontal_bias="1.0"
            app:layout_constraintStart_toStartOf="@ id/guideline"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.564"
            tools:text="@string/best_grade" />

        <TextView
            android:id="@ id/textView17"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/app_name"
            android:textSize="@dimen/big_font"
            app:layout_constraintBottom_toTopOf="@ id/guideline30"
            app:layout_constraintEnd_toStartOf="@ id/guideline28"
            app:layout_constraintStart_toStartOf="@ id/guideline27"
            app:layout_constraintTop_toTopOf="@ id/guideline29" />

        <ImageView
            android:id="@ id/imageView5"
            android:layout_width="289dp"
            android:layout_height="417dp"
            android:contentDescription="@string/Image_view"
            android:src="@drawable/calculation"
            app:layout_constraintBottom_toTopOf="@ id/guideline31"
            app:layout_constraintEnd_toStartOf="@ id/guideline28"
            app:layout_constraintStart_toStartOf="@ id/guideline27"
            app:layout_constraintTop_toTopOf="@ id/guideline30" />

        <Button
            android:id="@ id/button11"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:text="@string/button_name"
            android:textSize="18sp"
            app:layout_constraintBottom_toTopOf="@ id/guideline32"
            app:layout_constraintEnd_toStartOf="@ id/guideline28"
            app:layout_constraintStart_toStartOf="@ id/guideline27"
            app:layout_constraintTop_toTopOf="@ id/guideline31" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

 

       QuestionFragment.java:  

package com.example.calculationtest;


import android.os.Bundle;

import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.SavedStateViewModelFactory;
import androidx.lifecycle.ViewModelProviders;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.example.calculationtest.databinding.FragmentQuestionBinding;


/**
 * A simple {@link Fragment} subclass.
 */
public class QuestionFragment extends Fragment {


    public QuestionFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        final MyViewModel myViewModel;
        myViewModel= ViewModelProviders.of(requireActivity(),new SavedStateViewModelFactory(getActivity().getApplication(), this)).get(MyViewModel.class);
        // 出题
        myViewModel.generator();
        final FragmentQuestionBinding binding;
        binding = DataBindingUtil.inflate(inflater,R.layout.fragment_question,container, false);
        binding.setData(myViewModel);
        binding.setLifecycleOwner(requireActivity());
        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.buttonc:
                        builder.setLength(0);
                        break;
                }
                if(builder.length()==0){
                    binding.textView10.setText(getString(R.string.Answer));
                }else{
                    binding.textView10.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.buttonc.setOnClickListener(listener);
        binding.buttonOk.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 整型和String不能比较,得转换

                if(Integer.valueOf(builder.toString()).intValue() == myViewModel.getAnswer().getValue()){
                    myViewModel.answerCorrect();
                    builder.setLength(0);
                    binding.textView10.setText(getString(R.string.answer_correct_message));
                }else{// 回答错误
                    // 胜利
                    NavController controller = Navigation.findNavController(v);
                    if(myViewModel.win_flag){
                        controller.navigate(R.id.action_questionFragment_to_winFragment1);
                        // 防止以后一直胜利
                        myViewModel.win_flag = false;
                        // 创造新纪录,保存
                        myViewModel.save();

                    }else{ // 失败
                        controller.navigate(R.id.action_questionFragment_to_loseFragment1);
                    }
                }
            }
        });

        return binding.getRoot();
        // Inflate the layout for this fragment
        //return inflater.inflate(R.layout.fragment_question, container, false);
    }

}

    QuestionFragment.xml

  

<?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.calculationtest.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/guideline16"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.75" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@ id/guideline9"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.85" />

        <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.65" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@ id/guideline7"
            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/guideline8"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            app:layout_constraintGuide_percent="0.9" />

        <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.08" />

        <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.2" />

        <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.35" />

        <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.45" />

        <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.55" />

        <TextView
            android:id="@ id/textView3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{@string/Grade(data.currentScore)}"
            android:textSize="18sp"
            app:layout_constraintBottom_toTopOf="@ id/guideline10"
            app:layout_constraintEnd_toStartOf="@ id/guideline8"
            app:layout_constraintStart_toStartOf="@ id/guideline7"
            app:layout_constraintTop_toTopOf="@ id/guideline10"
            tools:text="Score:5" />

        <TextView
            android:id="@ id/textView4"
            android:layout_width="38dp"
            android:layout_height="53dp"
            android:text="@{String.valueOf(data.leftNumber)}"
            android:textSize="30sp"
            app:layout_constraintBottom_toBottomOf="@ id/textView5"
            app:layout_constraintEnd_toStartOf="@ id/textView5"
            app:layout_constraintStart_toStartOf="@ id/guideline7"
            app:layout_constraintTop_toTopOf="@ id/textView5"
            app:layout_constraintVertical_bias="0.0"
            tools:text="85" />

        <TextView
            android:id="@ id/textView7"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/euqal"
            android:textSize="@dimen/big_font"
            app:layout_constraintBottom_toBottomOf="@ id/textView9"
            app:layout_constraintEnd_toStartOf="@ id/textView9"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@ id/textView6"
            app:layout_constraintTop_toTopOf="@ id/textView9"
            app:layout_constraintVertical_bias="0.0" />

        <TextView
            android:id="@ id/textView5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{data.operator}"
            android:textSize="@dimen/big_font"
            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"
            app:layout_constraintVertical_bias="0.0"
            tools:text=" " />

        <TextView
            android:id="@ id/textView6"
            android:layout_width="37dp"
            android:layout_height="52dp"
            android:text="@{String.valueOf(data.rightNumber)}"
            android:textSize="30sp"
            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"
            app:layout_constraintVertical_bias="0.0"
            tools:text="75" />

        <TextView
            android:id="@ id/textView9"
            android:layout_width="16dp"
            android:layout_height="53dp"
            android:text="@string/question_mark"
            android:textSize="@dimen/big_font"
            app:layout_constraintBottom_toTopOf="@ id/guideline11"
            app:layout_constraintEnd_toStartOf="@ id/guideline8"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@ id/textView7"
            app:layout_constraintTop_toTopOf="@ id/guideline11" />

        <TextView
            android:id="@ id/textView10"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/Answer"
            android:textSize="@dimen/big_font"
            app:layout_constraintBottom_toTopOf="@ id/guideline12"
            app:layout_constraintEnd_toStartOf="@ id/guideline8"
            app:layout_constraintStart_toStartOf="@ id/guideline7"
            app:layout_constraintTop_toTopOf="@ id/guideline12"
            tools:text="Your Answer:" />

        <Button
            android:id="@ id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/button_1"
            android:textSize="24sp"
            app:layout_constraintBottom_toTopOf="@ id/guideline14"
            app:layout_constraintEnd_toStartOf="@ id/button2"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="@ id/guideline7"
            app:layout_constraintTop_toTopOf="@ id/guideline13" />

        <Button
            android:id="@ id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/button_2"
            android:textSize="24sp"
            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="@string/button_3"
            android:textSize="24sp"
            app:layout_constraintBottom_toBottomOf="@ id/button2"
            app:layout_constraintEnd_toStartOf="@ id/guideline8"
            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="@string/button_4"
            android:textSize="24sp"
            app:layout_constraintBottom_toTopOf="@ id/guideline15"
            app:layout_constraintEnd_toStartOf="@ id/button5"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="@ id/guideline7"
            app:layout_constraintTop_toTopOf="@ id/guideline14" />

        <Button
            android:id="@ id/button5"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/button_5"
            android:textSize="24sp"
            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="@string/button_6"
            android:textSize="24sp"
            app:layout_constraintBottom_toBottomOf="@ id/button5"
            app:layout_constraintEnd_toStartOf="@ id/guideline8"
            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="@string/button_7"
            android:textSize="24sp"
            app:layout_constraintBottom_toTopOf="@ id/guideline16"
            app:layout_constraintEnd_toStartOf="@ id/button8"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="@ id/guideline7"
            app:layout_constraintTop_toTopOf="@ id/guideline15" />

        <Button
            android:id="@ id/button8"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/button_8"
            android:textSize="24sp"
            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="@string/button_9"
            android:textSize="24sp"
            app:layout_constraintBottom_toBottomOf="@ id/button8"
            app:layout_constraintEnd_toStartOf="@ id/guideline8"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@ id/button8"
            app:layout_constraintTop_toTopOf="@ id/button8" />

        <Button
            android:id="@ id/buttonc"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/button_clear"
            android:textSize="24sp"
            app:layout_constraintBottom_toTopOf="@ id/guideline9"
            app:layout_constraintEnd_toStartOf="@ id/button0"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="@ id/guideline7"
            app:layout_constraintTop_toTopOf="@ id/guideline16" />

        <Button
            android:id="@ id/buttonOk"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/button_OK"
            android:textSize="24sp"
            app:layout_constraintBottom_toBottomOf="@ id/button0"
            app:layout_constraintEnd_toStartOf="@ id/guideline8"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@ id/button0"
            app:layout_constraintTop_toTopOf="@ id/button0"
            app:layout_constraintVertical_bias="0.0" />

        <Button
            android:id="@ id/button0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/button_0"
            android:textSize="24sp"
            app:layout_constraintBottom_toBottomOf="@ id/buttonc"
            app:layout_constraintEnd_toStartOf="@ id/buttonOk"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toEndOf="@ id/buttonc"
            app:layout_constraintTop_toTopOf="@ id/buttonc"
            app:layout_constraintVertical_bias="0.0" />

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

 

     WinFragment.java

package com.example.calculationtest;


import android.os.Bundle;

import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.SavedStateViewModelFactory;
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.calculationtest.databinding.FragmentTitleFragment2Binding;
import com.example.calculationtest.databinding.FragmentWinFragment1Binding;


/**
 * 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(getActivity().getApplication(), this)).get(MyViewModel.class);
        FragmentWinFragment1Binding binding;
        binding = DataBindingUtil.inflate(inflater,R.layout.fragment_win_fragment1, container, false);
        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_winFragment1_to_titleFragment2);
            }
        });
        return binding.getRoot();
        // Inflate the layout for this fragment
        //return inflater.inflate(R.layout.fragment_win_fragment1, container, false);
    }

}

    WinFragment.xml

  

<?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.calculationtest.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/guideline"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.15" />

        <androidx.constraintlayout.widget.Guideline
            android:id="@ id/guideline2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            app:layout_constraintGuide_percent="0.5" />

        <ImageView
            android:id="@ id/imageView"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:contentDescription="@string/image_win_message"
            android:src="@drawable/ic_sentiment_satisfied_black_24dp"
            app:layout_constraintBottom_toTopOf="@ id/guideline2"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@ id/guideline" />

        <TextView
            android:id="@ id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/image_win_message"
            android:textSize="30sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@ id/guideline2"
            app:layout_constraintVertical_bias="0.1" />

        <TextView
            android:id="@ id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@{@string/win_message(data.highScore)}"
            android:textSize="30sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@ id/guideline2"
            app:layout_constraintVertical_bias="0.30"
            tools:text="New Score:" />

        <Button
            android:id="@ id/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/button_back_to_Title"
            android:textSize="24sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.5"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@ id/guideline2"
            app:layout_constraintVertical_bias="0.60" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

 

      LoseFragment.java

package com.example.calculationtest;


import android.os.Bundle;

import androidx.databinding.DataBindingUtil;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.SavedStateViewModelFactory;
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.calculationtest.databinding.FragmentLoseFragment1Binding;
import com.example.calculationtest.databinding.FragmentTitleFragment2Binding;


/**
 * A simple {@link Fragment} subclass.
 */
public class LoseFragmen extends Fragment {


    public LoseFragmen() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        MyViewModel myViewModel;
        myViewModel= ViewModelProviders.of(requireActivity(),new SavedStateViewModelFactory(getActivity().getApplication(), this)).get(MyViewModel.class);
        FragmentLoseFragment1Binding binding;
        binding = DataBindingUtil.inflate(inflater,R.layout.fragment_lose_fragment1,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_loseFragment1_to_titleFragment2);
            }
        });
        return binding.getRoot();
        // Inflate the layout for this fragment
       // return inflater.inflate(R.layout.fragment_lose_fragment1, container, false);
    }

}

    LoseFragment.xml

    

<?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.calculationtest.MyViewModel" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".LoseFragmen">

        <Button
            android:id="@ id/button10"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="16dp"
            android:text="@string/button_back_to_Title"
            android:textSize="24sp"
            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/guideline4"
            app:layout_constraintVertical_bias="0.6" />

        <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.13" />

        <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.48" />

        <ImageView
            android:id="@ id/imageView3"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:contentDescription="@string/image_lose_message"
            android:src="@drawable/ic_sentiment_dissatisfied_black_24dp"
            app:layout_constraintBottom_toTopOf="@ id/guideline4"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@ id/guideline3" />

        <TextView
            android:id="@ id/textView12"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="16dp"
            android:text="@string/image_lose_message"
            android:textSize="30sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.496"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@ id/guideline4"
            app:layout_constraintVertical_bias="0.1" />

        <TextView
            android:id="@ id/textView13"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="28dp"
            android:layout_marginBottom="16dp"
            android:text="@{@string/lose_message(data.currentScore)}"
            android:textSize="30sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.45"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@ id/guideline4"
            app:layout_constraintVertical_bias="0.3"
            tools:text="Your Score:" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

 

 

     Strings.xml

<resources>
    <string name="app_name">Calculation Test</string>
    <string name="hello_blank_fragment">Hello blank fragment</string>
    <string name="Image_view">Image_view</string>
    <string name="button_name">Enter</string>
    <string name="best_grade">best grade:%d</string>
    <string name="Grade">Grade:%d</string>
    <string name="Answer">Your Answer</string>
    <string name="button_0">0</string>
    <string name="button_1">1</string>
    <string name="button_2">2</string>
    <string name="button_3">3</string>
    <string name="button_4">4</string>
    <string name="button_5">5</string>
    <string name="button_6">6</string>
    <string name="button_7">7</string>
    <string name="button_8">8</string>
    <string name="button_9">9</string>
    <string name="button_clear">C</string>
    <string name="button_OK">OK</string>
    <string name="euqal">=</string>
    <string name="question_mark">?</string>
    <string name="image_lose_message">You Lose!</string>
    <string name="image_win_message">You Win!</string>
    <string name="lose_message">Your Score:%d</string>
    <string name="win_message">New Score:%d</string>
    <string name="button_back_to_Title">Back</string>
    <string name="plus"> </string>
    <string name="answer_correct_message">Correct!Go</string>

</resources>

 

    其实这个小app关键在于图像的搭建和java内容的编写,各个fragment的xml只是起辅助作用,很多都是不用写。明白了实质其实很简单的!

  运行结果:这是我完成app后自己答得题

  头顶会显示最高记录,然后是出题界面,胜利失败界面。

  android------口算测试APP   android------口算测试APP   android------口算测试APP

 

 

  android------口算测试APP