当前位置:网站首页>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
边栏推荐
- zabbix監控系統自定義監控內容
- 小程序容器技术与物联网 IoT 可以碰撞出什么样的火花
- Using the rate package for data mining
- 【Go基础】1 - Go Go Go
- How to set multiple selecteditems on a list box- c#
- Leetcode 23. Merge K ascending linked lists
- go-zero微服务实战系列(九、极致优化秒杀性能)
- How college students choose suitable computers
- Chrome is set to pure black
- 2022 tower crane driver examination and tower crane driver examination questions and analysis
猜你喜欢
How to solve the problem of computer jam and slow down
Conversion of yolov5 XML dataset to VOC dataset
How to re enable local connection when the network of laptop is disabled
Azure ad domain service (II) configure azure file share disk sharing for machines in the domain service
Do you know about autorl in intensive learning? A summary of articles written by more than ten scholars including Oxford University and Google
Chrome is set to pure black
[gurobi] establishment of simple model
C#,数值计算(Numerical Recipes in C#),线性代数方程的求解,Gauss-Jordan消去法,源代码
DM database password policy and login restriction settings
Manjaro install wechat
随机推荐
Set and modify the page address bar icon favicon ico
SQL statement view SQL Server 2005 version number
Display Chinese characters according to numbers
Flutter 集成 amap_flutter_location
Do you know about autorl in intensive learning? A summary of articles written by more than ten scholars including Oxford University and Google
【Go基础】2 - Go基本语句
墨者学院-Webmin未经身份验证的远程代码执行
Snipaste convenient screenshot software, which can be copied on the screen
小程序容器技术与物联网 IoT 可以碰撞出什么样的火花
力扣今日题-1200. 最小绝对差
Cancel ctrl+alt+delete when starting up
@Role of pathvariable annotation
Basic operations of databases and tables ----- view data tables
What does range mean in PHP
【性能测试】一文读懂Jmeter
[gurobi] establishment of simple model
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
Three paradigms of database design
DM8 tablespace backup and recovery
OpenFeign 服务接口调用