当前位置:网站首页>Bishi blog (13) -- oral arithmetic test app
Bishi blog (13) -- oral arithmetic test app
2022-07-04 08:32:00 【Zhou Keren】
1、 Create four Fragment:Title,Question,Win,Lose
2、 stay res Next create a navigation chart nav, Use a line to show the logical relationship between the four pages :
3、 to title Add an icon to the page , And in gradle Add dataBinding And dependence :
buildFeatures{
dataBinding = true;
}
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:2.3.1' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
4、 Get started Title page :
<string name="title_message">Calculation Test</string>
<string name="title_image_info">title image</string>
<string name="title_button_message">Enter</string>
<string name="high_score_message">High Score:%d</string>
5、 do Question page :
<string name="button0">0</string>
<string name="button1">1</string>
<string name="button2">2</string>
<string name="button3">3</string>
<string name="button4">4</string>
<string name="button5">5</string>
<string name="button6">6</string>
<string name="button7">7</string>
<string name="button8">8</string>
<string name="button9">9</string>
<string name="button_clear">C</string>
<string name="button_submit">OK</string>
<string name="equal_symbol">=</string>
<string name="question_mark">\?</string>
<string name="current_score">Score:%d</string>
<string name="input_indicator">Your Answer:</string>
6、 do win and lose page :
<string name="lose_image_message">lose image</string>
<string name="win_image_message">win image</string>
<string name="lose_message">You Lose!</string>
<string name="win_message">You Win!</string>
<string name="lose_score_message">Your Score:%d</string>
<string name="win_score_message">New Record:%d</string>
<string name="button_back_to_title">Back</string>
7、 You need to create a 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;
}
MutableLiveData<Integer>getLeftNumber(){
return handle.getLiveData(KEY_LEFT_NUMBER);
}
MutableLiveData<Integer>getRightNumber(){
return handle.getLiveData(KEY_RIGHT_NUMBER);
}
MutableLiveData<Integer>getOperator(){
return handle.getLiveData(KEY_OPERATOR);
}
MutableLiveData<Integer>getHighScore(){
return handle.getLiveData(KEY_HIGH_SCORE);
}
MutableLiveData<Integer>getCurrentScore(){
return handle.getLiveData(KEY_CURRENT_SCORE);
}
MutableLiveData<Integer>getAnswer(){
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、 Data binding :
fragment_title:
<?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>
...
<TextView
...
android:text="@{@string/high_score_message(data.highScore)}"
...
</layout>
fragment_question:
<?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>
...
<TextView
...
android:text="@{@string/current_score(data.currentScore)}"
... />
...
<TextView
...
android:text="@{String.valueOf(data.leftNumber)}"
.../>
<TextView
...
android:text="@{data.operator}"
... />
<TextView
...
android:text="@{String.valueOf(data.rightNumber)}"
... />
...
</layout>
fragment_win:
<?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>
...
<TextView
...
android:text="@{@string/win_score_message(data.highScore)}"
... />
...
</layout>
fragment_lose:
<?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>
...
<TextView
...
android:text="@{@string/lose_score_message(data.currentScore)}"
... />
...
</layout>
9、 Write fragment Code inside :
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();// Create a variable string
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){// Without input
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 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>getHighScore(){
return handle.getLiveData(KEY_HIGH_SCORE);
}
public MutableLiveData<Integer>getCurrentScore(){
return handle.getLiveData(CURRENT_SCORE);
}
public MutableLiveData<Integer>getAnswer(){
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、 Some resources that need to be sinicized are sinicized :
The final run result :
Simple oral arithmetic test APP
边栏推荐
- How to choose solid state hard disk and mechanical hard disk in computer
- 力扣今日题-1200. 最小绝对差
- L1 regularization and L2 regularization
- 2022 gas examination registration and free gas examination questions
- DM8 uses different databases to archive and recover after multiple failures
- Sort by item from the list within the list - C #
- Snipaste convenient screenshot software, which can be copied on the screen
- Example analysis of C # read / write lock
- Flutter 集成 amap_flutter_location
- ZABBIX 5.0 monitoring client
猜你喜欢
1. Kalman filter - the best linear filter
Moher College phpmailer remote command execution vulnerability tracing
snipaste 方便的截图软件,可以复制在屏幕上
Comprendre la méthode de détection des valeurs aberrantes des données
SSRF vulnerability exploitation - attack redis
Display Chinese characters according to numbers
How does Xiaobai buy a suitable notebook
根据数字显示中文汉字
DM8 tablespace backup and recovery
OpenFeign 服务接口调用
随机推荐
C # implements a queue in which everything can be sorted
R language ggplot2 visualization: ggplot2 visualization grouping box diagram, place the legend and title of the visualization image on the top left of the image and align them to the left, in which th
zabbix监控系统邮件报警配置
PHP session variable passed from form - PHP
团体程序设计天梯赛-练习集 L1-006 连续因子
【Go基础】2 - Go基本语句
yolov5 xml数据集转换为VOC数据集
Need help resetting PHP counters - PHP
团体程序设计天梯赛-练习集 L2-002 链表去重
Mouse over to change the transparency of web page image
Private collection project practice sharing [Yugong series] February 2022 U3D full stack class 007 - production and setting skybox resources
Laravel page load problem connection reset - PHP
Add log file to slim frame - PHP
Wechat has new functions, and the test is started again
ZABBIX monitoring system custom monitoring content
2022 tower crane driver examination and tower crane driver examination questions and analysis
PHP converts seconds to timestamps - PHP
一文了解數據异常值檢測方法
Sort by item from the list within the list - C #
Unity write word