毕设博客(十三) —— 口算测试APP

1、创建四个Fragment:Title,Question,Win,Lose

毕设博客(十三) —— 口算测试APP_第1张图片

2、在res下创建一个导航图表nav,用连线表示出四个页面之间的逻辑关系:

毕设博客(十三) —— 口算测试APP_第2张图片

3、给title页面添加一个图标,并且在gradle中添加dataBinding 和依赖:

buildFeatures{
    dataBinding = true;
}
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.3.1'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'

4、开始做Title页面:

毕设博客(十三) —— 口算测试APP_第3张图片

Calculation Test
title image
Enter
High Score:%d

5、做Question页面: 

毕设博客(十三) —— 口算测试APP_第4张图片

0
1
2
3
4
5
6
7
8
9
C
OK
=
\?
Score:%d
Your Answer:

6、做win和lose页面:

毕设博客(十三) —— 口算测试APP_第5张图片

毕设博客(十三) —— 口算测试APP_第6张图片

lose image
win image
You Lose!
You Win!
Your Score:%d
New Record:%d
Back

7、需要创建一个ViewModel:

...

    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";
    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;
    }
    MutableLiveDatagetLeftNumber(){
        return handle.getLiveData(KEY_LEFT_NUMBER);
    }
    MutableLiveDatagetRightNumber(){
        return handle.getLiveData(KEY_RIGHT_NUMBER);
    }
    MutableLiveDatagetOperator(){
        return handle.getLiveData(KEY_OPERATOR);
    }
    MutableLiveDatagetHighScore(){
        return  handle.getLiveData(KEY_HIGH_SCORE);
    }
    MutableLiveDatagetCurrentScore(){
        return handle.getLiveData(KEY_CURRENT_SCORE);
    }
    MutableLiveDatagetAnswer(){
        return handle.getLiveData(KEY_ANSWER);
    }
    void generator(){
        int LEVEL = 20;
        Random random = new Random();
        int x,y;
        x = random.nextInt(LEVEL) + 1;
        y = random.nextInt(LEVEL) + 1;
        if (x % 2 == 0){
            getOperator().setValue(Integer.valueOf("+"));
            if (x > y){ 
                getAnswer().setValue(x);
                getLeftNumber().setValue(y);
                getRightNumber().setValue(x - y);
            }
            else {
                getAnswer().setValue(y);
                getLeftNumber().setValue(x);
                getRightNumber().setValue(y - x);
            }
        }
        else {
            getOperator().setValue(Integer.valueOf("-"));
            if (x > y){
                getAnswer().setValue(x - y);
                getLeftNumber().setValue(x);
                getRightNumber().setValue(y);
            }
            else {
                getAnswer().setValue(y - x);
                getLeftNumber().setValue(y);
                getRightNumber().setValue(x);
            }
        }
    }
    @SuppressWarnings("ConstantConditions")
    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();
    }
    @SuppressWarnings("ConstantConditions")
    void answerCorrect(){
        getCurrentScore().setValue(getCurrentScore().getValue() + 1);
        if (getCurrentScore().getValue() > getHighScore().getValue()){
            getHighScore().setValue(getCurrentScore().getValue());
            win_flag = true;
        }
        generator();
    }
}

8、做数据绑定: 

fragment_title:



    
        
    
   ...
        

fragment_question:



    
        
    
    ...
        
        ...
        
        
        
       ...

fragment_win:



    
        
    
    ...
        
    ...

fragment_lose:



    
        
    
    ...
        
    ...

9、写fragment里面的代码:

TitleFragment:

...
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        MyViewModel myViewModel;
        myViewModel = new ViewModelProvider(requireActivity(),new SavedStateViewModelFactory(requireActivity().getApplication(),this)).get(MyViewModel.class);
        FragmentTitleBinding binding;
        binding = DataBindingUtil.inflate(inflater,R.layout.fragment_title,container,false);
        binding.setData(myViewModel);
        binding.setLifecycleOwner(requireActivity());
        binding.button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                NavController controller = Navigation.findNavController(view);
                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:

...
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        final MyViewModel myViewModel;
        myViewModel = new ViewModelProvider(requireActivity(),new SavedStateViewModelFactory(requireActivity().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() {
            @SuppressLint("NonConstantResourceId")
            @Override
            public void onClick(View view) {
                switch (view.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.button_clear:
                        builder.setLength(0);break;
                }
                if (builder.length() == 0){
                    binding.textView9.setText(getString(R.string.input_indicator));
                }else {
                    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.buttonClear.setOnClickListener(listener);

        binding.buttonSubmit.setOnClickListener(new View.OnClickListener() {
            @SuppressWarnings("ConstantConditions")
            @Override
            public void onClick(View view) {
                if(builder.length() == 0){//没有输入的情况下
                    Toast.makeText(getActivity(), getString(R.string.input_null_message), Toast.LENGTH_SHORT).show();
                    return;
                }
                else if (Integer.valueOf(builder.toString()).intValue() == myViewModel.getAnswer().getValue()){
                    myViewModel.answerCorrect();
                    builder.setLength(0);
                    binding.textView9.setText(R.string.answer_correct_message);
                   // builder.append(getString(R.string.answer_correct_message));
                }
                else {
                    NavController controller = Navigation.findNavController(view);
                    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);
                    }
                }
            }
        });
        return binding.getRoot();
    }
}

WinFragment:

...
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        MyViewModel myViewModel = new ViewModelProvider(requireActivity(),new SavedStateViewModelFactory(requireActivity().getApplication(),this)).get(MyViewModel.class);
        FragmentWinBinding binding;
        binding = DataBindingUtil.inflate(inflater,R.layout.fragment_win,container,false);
        binding.setData(myViewModel);
        binding.setLifecycleOwner(requireActivity());
        binding.button11.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                NavController controller = Navigation.findNavController(view);
                controller.navigate(R.id.action_winFragment_to_titleFragment);
            }
        });
        return binding.getRoot();
    }
}

 LoseFragment:

...
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        MyViewModel myViewModel = new ViewModelProvider(requireActivity(),new SavedStateViewModelFactory(requireActivity().getApplication(),this)).get(MyViewModel.class);
        FragmentLoseBinding binding;
        binding = DataBindingUtil.inflate(inflater,R.layout.fragment_lose,container,false);
        binding.setData(myViewModel);
        binding.setLifecycleOwner(requireActivity());
        binding.button10.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                NavController controller = Navigation.findNavController(view);
                controller.navigate(R.id.action_loseFragment_to_titleFragment);
            }
        });
        return binding.getRoot();
    }
}

10、MainActivity:

package com.example.calculationtest;
import ...

public class MainActivity extends AppCompatActivity {
    NavController controller;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //controller = findNavController(this,R.id.fragment);
        NavHostFragment navHostFragment = (NavHostFragment) getSupportFragmentManager().findFragmentById(R.id.fragment);
        controller = navHostFragment.getNavController();
        NavigationUI.setupActionBarWithNavController(this,controller);
    }

    @Override
    public boolean onSupportNavigateUp() {
        if (Objects.requireNonNull(controller.getCurrentDestination()).getId() == R.id.questionFragment){
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle(getString(R.string.quit_dialog_title));
            builder.setPositiveButton(R.string.dialog_positive_message, (dialogInterface, i) -> controller.navigateUp());
            builder.setNegativeButton(R.string.dialog_negative_message, (dialogInterface, i) -> {

            });
            AlertDialog dialog = builder.create();
            dialog.show();
        }else {
            controller.navigate(R.id.titleFragment);
        }
        return super.onNavigateUp();
    }

    @Override
    public void onBackPressed() {
        onSupportNavigateUp();
    }
}

11、MyViewModel:

package com.example.calculationtest;
import ...
public class MyViewModel extends AndroidViewModel {
    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 CURRENT_SCORE = "current_score";
    boolean win_flag = false;
    // private  String current = getApplication().getResources().getString(R.string.KEY_CURRENT_SCORE);
    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(CURRENT_SCORE, 0);
/*
            handle.set(application.getString(R.string.KEY_CURRENT_SCORE),0 );
*/
        }
        this.handle = handle;
    }
    public MutableLiveDatagetLeftNumber(){
        return  handle.getLiveData(KEY_LEFT_NUMBER);
    }
    public MutableLiveDatagetRightNumber(){
        return handle.getLiveData(KEY_RIGHT_NUMBER);
    }
    public MutableLiveDatagetOperator(){
        return handle.getLiveData(KEY_OPERATOR);
    }
    public MutableLiveDatagetHighScore(){
        return handle.getLiveData(KEY_HIGH_SCORE);
    }
    public MutableLiveDatagetCurrentScore(){
        return handle.getLiveData(CURRENT_SCORE);
    }
    public MutableLiveDatagetAnswer(){
        return handle.getLiveData(KEY_ANSWER);
    }
    void generator(){
        int LEVEL = 20;
        Random random = new Random();
        int x,y;
        x = random.nextInt(LEVEL) + 1;
        y = random.nextInt(LEVEL) + 1;
        if(x%2 == 0 ){
            getOperator().setValue("+");
            if(x>y){
                getAnswer().setValue(x);
                getLeftNumber().setValue(y);
                getRightNumber().setValue(x - y);
            }else {
                getAnswer().setValue(y);
                getLeftNumber().setValue(x);
                getRightNumber().setValue(y - x);
            }
        }
        else{
            getOperator().setValue("-");
            if (x > y){
                getAnswer().setValue(x - y);
                getLeftNumber().setValue(x);
                getRightNumber().setValue(y);
            }else{
                getAnswer().setValue(y - x);
                getLeftNumber().setValue(y);
                getRightNumber().setValue(x);
            }
        }

    }
    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 answerCorrect() {
        getCurrentScore().setValue(getCurrentScore().getValue() + 1);
        if (getCurrentScore().getValue() > getHighScore().getValue()) {
            getHighScore().setValue(getCurrentScore().getValue());
            win_flag = true;
        }
        generator();
    }
}

12、对一些需要汉化的资源进行汉化:

毕设博客(十三) —— 口算测试APP_第7张图片

最终运行结果:

简易口算测试APP

你可能感兴趣的:(毕设,android,java,android,studio)