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

Posted littemelon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了android------口算测试APP相关的知识,希望对你有一定的参考价值。

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

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

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

   

 

 

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

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

  TitleFragment:                              QuestionFragment:

                

 

 

 

 

  WinFragment:                              LoseFragment:

 

               

 

 

    

 

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

 

    然后在activity_main.xml,将NavHostFragment拖入到ConstraintLayout里

 

 

    要保存数据,所以要新建一个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/guideline

以上是关于android------口算测试APP的主要内容,如果未能解决你的问题,请参考以下文章

小学四则运算口算练习app---No.6

小学四则运算口算练习app---No.3

小学四则运算口算练习app---No.4

小学四则运算口算练习app---No.5

我的片段无法转换为 android.support.v4.app.Fragment

Android学习进度四