Android学习进度四

时间:2020-11-24 18:10:14

经过一段时间观看视频进行Android的学习,将现今所学知识进行阶段性总结编写了一款口算测试App,并成功将其打包成apk在手机上运行。主要使用了LiveData,DataBinding,ViewModel以及Fragment等,话不多说,上代码。

一、界面的搭建

创建四个界面,分别为TitleFragment,QuestionFragment,WinFragment以及LoseFragment

Android学习进度四

因为使用了DataBinding和LiveData,要在build.gradle中添加依赖

 dataBinding.enabled true 

 implementation androidx.lifecycle:lifecycle-viewmodel-savedstate:1.0.0-alpha02‘//最新的依赖可以在官网中找到 

 

同时创建MyViewModel.java,继承自AndroidViewModel

  1 package com.example.calculationtest;
  2 
  3 import android.app.Application;
  4 import android.content.Context;
  5 import android.content.SharedPreferences;
  6 
  7 import androidx.annotation.NonNull;
  8 import androidx.lifecycle.AndroidViewModel;
  9 import androidx.lifecycle.MutableLiveData;
 10 import androidx.lifecycle.SavedStateHandle;
 11 
 12 import java.util.Random;
 13 
 14 public class MyViewModel extends AndroidViewModel {
 15     private SavedStateHandle handle;
 16     private static String KEY_HIGH_SCORE = "key_high_score";
 17     private static String KEY_LEFT_NUMBER = "key_left_number";
 18     private static String KEY_RIGHT_NUMBER = "key_right_number";
 19     private static String KEY_OPERATOR = "key_operator";
 20     private static String KEY_ANSWER = "key_answer";
 21     private static String SAVE_SHP_DATA_NAME = "save_shp_data_name";
 22     private static String KEY_CURRENT_SCORE = "key_current_score";
 23     boolean win_flag = false;
 24 
 25     public MyViewModel(@NonNull Application application, SavedStateHandle handle) {
 26         super(application);
 27         if (!handle.contains(KEY_HIGH_SCORE)) {
 28             SharedPreferences shp = getApplication().getSharedPreferences(SAVE_SHP_DATA_NAME, Context.MODE_PRIVATE);
 29             handle.set(KEY_HIGH_SCORE, shp.getInt(KEY_HIGH_SCORE, 0));
 30             handle.set(KEY_LEFT_NUMBER, 0);
 31             handle.set(KEY_RIGHT_NUMBER, 0);
 32             handle.set(KEY_OPERATOR, " ");
 33             handle.set(KEY_ANSWER, 0);
 34             handle.set(KEY_CURRENT_SCORE, 0);
 35         }
 36         this.handle = handle;
 37     }
 38 
 39     public MutableLiveData<Integer> getLeftNumber() {
 40         return handle.getLiveData(KEY_LEFT_NUMBER);
 41     }
 42 
 43     public MutableLiveData<Integer> getRightNumber() {
 44         return handle.getLiveData(KEY_RIGHT_NUMBER);
 45     }
 46 
 47     public MutableLiveData<String> getOpreator() {
 48         return handle.getLiveData(KEY_OPERATOR);
 49     }
 50 
 51     public MutableLiveData<Integer> getHighScore() {
 52         return handle.getLiveData(KEY_HIGH_SCORE);
 53     }
 54 
 55     public MutableLiveData<Integer> getCurrentScore() {
 56         return handle.getLiveData(KEY_CURRENT_SCORE);
 57     }
 58 
 59     public MutableLiveData<Integer> getAnswer() {
 60         return handle.getLiveData(KEY_ANSWER);
 61     }
 62 
 63     void generator() {
 64         int LEVEL = 20;
 65         Random random = new Random();
 66         int x, y;
 67         x = random.nextInt(LEVEL)   1;
 68         y = random.nextInt(LEVEL)   1;
 69         if (x % 2 == 0) {
 70             getOpreator().setValue(" ");
 71             if (x > y) {
 72                 getAnswer().setValue(x);
 73                 getLeftNumber().setValue(y);
 74                 getRightNumber().setValue(x - y);
 75             } else {
 76                 getAnswer().setValue(y);
 77                 getLeftNumber().setValue(x);
 78                 getRightNumber().setValue(y - x);
 79             }
 80         } else {
 81             getOpreator().setValue("-");
 82             if (x > y) {
 83                 getAnswer().setValue(x - y);
 84                 getLeftNumber().setValue(x);
 85                 getRightNumber().setValue(y);
 86             } else {
 87                 getAnswer().setValue(y - x);
 88                 getLeftNumber().setValue(y);
 89                 getRightNumber().setValue(x);
 90             }
 91         }
 92     }
 93 
 94 
 95     void save() {
 96         SharedPreferences shp = getApplication().getSharedPreferences(SAVE_SHP_DATA_NAME, Context.MODE_PRIVATE);
 97         SharedPreferences.Editor editor = shp.edit();
 98         editor.putInt(KEY_HIGH_SCORE, getHighScore().getValue());
 99         editor.apply();
100     }
101 
102 
103     void answerCorrect() {
104         getCurrentScore().setValue(getCurrentScore().getValue()   1);
105         if (getCurrentScore().getValue() > getHighScore().getValue()) {
106             getHighScore().setValue(getCurrentScore().getValue());
107             win_flag = true;
108         }
109         generator();
110     }
111 
112 }

fragment_title.xml

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <layout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:app="http://schemas.android.com/apk/res-auto"
 4     xmlns:tools="http://schemas.android.com/tools">
 5 
 6     <data>
 7         <variable
 8             name="data"
 9             type="com.example.calculationtest.MyViewModel" />
10     </data>
11 
12     <androidx.constraintlayout.widget.ConstraintLayout
13         android:layout_width="match_parent"
14         android:layout_height="match_parent"
15         tools:context=".TitleFragment">
16 
17         <androidx.constraintlayout.widget.Guideline
18             android:id="@ id/guideline"
19             android:layout_width="wrap_content"
20             android:layout_height="wrap_content"
21             android:orientation="vertical"
22             app:layout_constraintGuide_percent="0.1" />
23 
24         <androidx.constraintlayout.widget.Guideline
25             android:id="@ id/guideline2"
26             android:layout_width="wrap_content"
27             android:layout_height="wrap_content"
28             android:orientation="vertical"
29             app:layout_constraintGuide_percent="0.9" />
30 
31         <TextView
32             android:id="@ id/textView"
33             android:layout_width="wrap_content"
34             android:layout_height="wrap_content"
35             android:layout_marginStart="8dp"
36             android:layout_marginTop="8dp"
37             android:layout_marginEnd="8dp"
38             android:layout_marginBottom="8dp"
39             android:text="@string/title_message"
40             android:textAlignment="center"
41             android:textSize="@dimen/big_font"
42             app:layout_constraintBottom_toBottomOf="parent"
43             app:layout_constraintEnd_toStartOf="@ id/guideline2"
44             app:layout_constraintHorizontal_bias="0.652"
45             app:layout_constraintStart_toStartOf="@ id/guideline"
46             app:layout_constraintTop_toTopOf="parent"
47             app:layout_constraintVertical_bias="0.201" />
48 
49         <ImageView
50             android:id="@ id/imageView"
51             android:layout_width="0dp"
52             android:layout_height="0dp"
53             android:layout_marginStart="8dp"
54             android:layout_marginTop="8dp"
55             android:layout_marginEnd="8dp"
56             android:layout_marginBottom="8dp"
57             android:contentDescription="@string/title_image_info"
58             android:src="@drawable/titleimage"
59             app:layout_constraintBottom_toBottomOf="parent"
60             app:layout_constraintDimensionRatio="w,1:1"
61             app:layout_constraintEnd_toStartOf="@ id/guideline2"
62             app:layout_constraintStart_toStartOf="@ id/guideline"
63             app:layout_constraintTop_toTopOf="parent" />
64 
65         <Button
66             android:id="@ id/button"
67             android:layout_width="0dp"
68             android:layout_height="wrap_content"
69             android:layout_marginStart="8dp"
70             android:layout_marginTop="8dp"
71             android:layout_marginEnd="8dp"
72             android:layout_marginBottom="8dp"
73             android:text="@string/title_button_message"
74             app:layout_constraintBottom_toBottomOf="parent"
75             app:layout_constraintEnd_toEndOf="@ id/imageView"
76             app:layout_constraintHorizontal_bias="0.5"
77             app:layout_constraintStart_toStartOf="@ id/imageView"
78             app:layout_constraintTop_toTopOf="parent"
79             app:layout_constraintVertical_bias="0.85" />
80 
81         <TextView
82             android:id="@ id/textView2"
83             android:layout_width="wrap_content"
84             android:layout_height="wrap_content"
85             android:text="@{@string/high_score_message(data.highScore)}"
86             app:layout_constraintBottom_toBottomOf="parent"
87             app:layout_constraintEnd_toEndOf="parent"
88             app:layout_constraintHorizontal_bias="0.875"
89             app:layout_constraintStart_toStartOf="parent"
90             app:layout_constraintTop_toTopOf="parent"
91             app:layout_constraintVertical_bias="0.116"
92             tools:text="High Score:%d" />
93     </androidx.constraintlayout.widget.ConstraintLayout>
94 </layout>
  1. imageview所用图片是网上下载的
  2. 右上角的"high score :%d",需要与viewmodel中的数据绑定
  3. 点击Enter,即可进入答题界面

TitleFragment.java

 1 @Override
 2     public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
 3                              Bundle savedInstanceState) {
 4         MyViewModel myViewModel;
 5         myViewModel = ViewModelProviders.of(requireActivity(), new SavedStateViewModelFactory(requireActivity())).get(MyViewModel.class);
 6         FragmentTitleBinding binding;
 7         binding = DataBindingUtil.inflate(inflater,R.layout.fragment_title,container,false);
 8         binding.setData(myViewModel);
 9         binding.setLifecycleOwner(requireActivity());
10         binding.button.setOnClickListener(new View.OnClickListener() {
11             @Override
12             public void onClick(View v) {
13                 NavController controller = Navigation.findNavController(v);
14                 controller.navigate(R.id.action_titleFragment_to_questionFragment);
15             }
16         });
17         return binding.getRoot();
18         // Inflate the layout for this fragment
19         //return inflater.inflate(R.layout.fragment_title, container, false);
20     }

 

 fragment_question.xml

  1 <?xml version="1.0" encoding="utf-8"?>
  2 <layout xmlns:android="http://schemas.android.com/apk/res/android"
  3     xmlns:app="http://schemas.android.com/apk/res-auto"
  4     xmlns:tools="http://schemas.android.com/tools">
  5 
  6     <data>
  7         <variable
  8             name="data"
  9             type="com.example.calculationtest.MyViewModel" />
 10     </data>
 11 
 12     <androidx.constraintlayout.widget.ConstraintLayout
 13         android:layout_width="match_parent"
 14         android:layout_height="match_parent"
 15         tools:context=".QuestionFragment">
 16 
 17         <androidx.constraintlayout.widget.Guideline
 18             android:id="@ id/guideline9"
 19             android:layout_width="wrap_content"
 20             android:layout_height="wrap_content"
 21             android:orientation="horizontal"
 22             app:layout_constraintGuide_percent="0.85" />
 23 
 24         <androidx.constraintlayout.widget.Guideline
 25             android:id="@ id/guideline8"
 26             android:layout_width="wrap_content"
 27             android:layout_height="wrap_content"
 28             android:orientation="horizontal"
 29             app:layout_constraintGuide_percent="0.45" />
 30 
 31         <androidx.constraintlayout.widget.Guideline
 32             android:id="@ id/guideline7"
 33             android:layout_width="wrap_content"
 34             android:layout_height="wrap_content"
 35             android:orientation="horizontal"
 36             app:layout_constraintGuide_percent="0.37" />
 37 
 38         <androidx.constraintlayout.widget.Guideline
 39             android:id="@ id/guideline3"
 40             android:layout_width="wrap_content"
 41             android:layout_height="wrap_content"
 42             android:orientation="vertical"
 43             app:layout_constraintGuide_percent="0.1" />
 44 
 45         <androidx.constraintlayout.widget.Guideline
 46             android:id="@ id/guideline4"
 47             android:layout_width="wrap_content"
 48             android:layout_height="wrap_content"
 49             android:orientation="vertical"
 50             app:layout_constraintGuide_percent="0.9" />
 51 
 52         <androidx.constraintlayout.widget.Guideline
 53             android:id="@ id/guideline5"
 54             android:layout_width="wrap_content"
 55             android:layout_height="wrap_content"
 56             android:orientation="horizontal"
 57             app:layout_constraintGuide_percent="0.15" />
 58 
 59         <androidx.constraintlayout.widget.Guideline
 60             android:id="@ id/guideline6"
 61             android:layout_width="wrap_content"
 62             android:layout_height="wrap_content"
 63             android:orientation="horizontal"
 64             app:layout_constraintGuide_percent="0.25" />
 65 
 66         <TextView
 67             android:id="@ id/textView3"
 68             android:layout_width="wrap_content"
 69             android:layout_height="wrap_content"
 70             android:layout_marginStart="8dp"
 71             android:layout_marginTop="8dp"
 72             android:layout_marginEnd="8dp"
 73             android:layout_marginBottom="8dp"
 74             android:text="@{@string/current_score(data.currentScore)}"
 75             app:layout_constraintBottom_toTopOf="@ id/guideline5"
 76             app:layout_constraintEnd_toEndOf="parent"
 77             app:layout_constraintStart_toStartOf="parent"
 78             app:layout_constraintTop_toTopOf="@ id/guideline5"
 79             tools:text="Score:5" />
 80 
 81         <TextView
 82             android:id="@ id/textView4"
 83             android:layout_width="wrap_content"
 84             android:layout_height="wrap_content"
 85             android:text="@{String.valueOf(safeUnbox(data.leftNumber))}"
 86             android:textSize="@dimen/huge_font"
 87             app:layout_constraintBottom_toBottomOf="@ id/textView5"
 88             app:layout_constraintEnd_toStartOf="@ id/textView5"
 89             app:layout_constraintHorizontal_bias="0.5"
 90             app:layout_constraintStart_toStartOf="@ id/guideline3"
 91             app:layout_constraintTop_toTopOf="@ id/textView5"
 92             tools:text="8" />
 93 
 94         <TextView
 95             android:id="@ id/textView5"
 96             android:layout_width="wrap_content"
 97             android:layout_height="wrap_content"
 98             android:text="@{data.opreator}"
 99             android:textSize="@dimen/huge_font"
100             app:layout_constraintBottom_toBottomOf="@ id/textView6"
101             app:layout_constraintEnd_toStartOf="@ id/textView6"
102             app:layout_constraintHorizontal_bias="0.5"
103             app:layout_constraintStart_toEndOf="@ id/textView4"
104             app:layout_constraintTop_toTopOf="@ id/textView6"
105             tools:text=" " />
106 
107         <TextView
108             android:id="@ id/textView6"
109             android:layout_width="wrap_content"
110             android:layout_height="wrap_content"
111             android:text="@{String.valueOf(safeUnbox(data.rightNumber))}"
112             android:textSize="@dimen/huge_font"
113             app:layout_constraintBottom_toBottomOf="@ id/textView7"
114             app:layout_constraintEnd_toStartOf="@ id/textView7"
115             app:layout_constraintHorizontal_bias="0.5"
116             app:layout_constraintStart_toEndOf="@ id/textView5"
117             app:layout_constraintTop_toTopOf="@ id/textView7"
118             tools:text="9" />
119 
120         <TextView
121             android:id="@ id/textView7"
122             android:layout_width="wrap_content"
123             android:layout_height="wrap_content"
124             android:text="@string/equal_symbol"
125             android:textSize="@dimen/huge_font"
126             app:layout_constraintBottom_toBottomOf="@ id/textView8"
127             app:layout_constraintEnd_toStartOf="@ id/textView8"
128             app:layout_constraintHorizontal_bias="0.5"
129             app:layout_constraintStart_toEndOf="@ id/textView6"
130             app:layout_constraintTop_toTopOf="@ id/textView8"
131             tools:text="=" />
132 
133         <TextView
134             android:id="@ id/textView8"
135             android:layout_width="wrap_content"
136             android:layout_height="wrap_content"
137             android:text="@string/question_mark"
138             android:textSize="@dimen/huge_font"
139             app:layout_constraintBottom_toTopOf="@ id/guideline6"
140             app:layout_constraintEnd_toStartOf="@ id/guideline4"
141             app:layout_constraintHorizontal_bias="0.5"
142             app:layout_constraintStart_toEndOf="@ id/textView7"
143             app:layout_constraintTop_toTopOf="@ id/guideline6"
144             tools:text="?" />
145 
146         <TextView
147             android:id="@ id/textView9"
148             android:layout_width="wrap_content"
149             android:layout_height="wrap_content"
150             android:layout_marginStart="8dp"
151             android:layout_marginTop="8dp"
152             android:layout_marginEnd="8dp"
153             android:layout_marginBottom="8dp"
154             android:text="@string/input_indicator"
155             android:textSize="@dimen/mid_font"
156             app:layout_constraintBottom_toTopOf="@ id/guideline7"
157             app:layout_constraintEnd_toStartOf="@ id/guideline4"
158             app:layout_constraintStart_toStartOf="@ id/guideline3"
159             app:layout_constraintTop_toTopOf="@ id/guideline7" />
160 
161         <androidx.constraintlayout.widget.Guideline
162             android:id="@ id/guideline10"
163             android:layout_width="wrap_content"
164             android:layout_height="wrap_content"
165             android:orientation="horizontal"
166             app:layout_constraintGuide_percent="0.55" />
167 
168         <androidx.constraintlayout.widget.Guideline
169             android:id="@ id/guideline11"
170             android:layout_width="wrap_content"
171             android:layout_height="wrap_content"
172             android:orientation="horizontal"
173             app:layout_constraintGuide_percent="0.65" />
174 
175         <androidx.constraintlayout.widget.Guideline
176             android:id="@ id/guideline12"
177             android:layout_width="wrap_content"
178             android:layout_height="wrap_content"
179             android:orientation="horizontal"
180             app:layout_constraintGuide_percent="0.75" />
181 
182         <Button
183             android:id="@ id/button1"
184             android:layout_width="wrap_content"
185             android:layout_height="wrap_content"
186             android:text="@string/button1"
187             android:textSize="@dimen/button_font"
188             app:layout_constraintBottom_toTopOf="@ id/guideline10"
189             app:layout_constraintEnd_toStartOf="@ id/button2"
190             app:layout_constraintHorizontal_bias="0.5"
191             app:layout_constraintStart_toStartOf="@ id/guideline3"
192             app:layout_constraintTop_toTopOf="@ id/guideline8" />
193 
194         <Button
195             android:id="@ id/button2"
196             android:layout_width="wrap_content"
197             android:layout_height="wrap_content"
198             android:text="@string/button2"
199             android:textSize="@dimen/button_font"
200             app:layout_constraintBottom_toBottomOf="@ id/button1"
201             app:layout_constraintEnd_toStartOf="@ id/button3"
202             app:layout_constraintHorizontal_bias="0.5"
203             app:layout_constraintStart_toEndOf="@ id/button1"
204             app:layout_constraintTop_toTopOf="@ id/button1" />
205 
206         <Button
207             android:id="@ id/button3"
208             android:layout_width="wrap_content"
209             android:layout_height="wrap_content"
210             android:text="@string/button3"
211             android:textSize="@dimen/button_font"
212             app:layout_constraintBottom_toBottomOf="@ id/button2"
213             app:layout_constraintEnd_toStartOf="@ id/guideline4"
214             app:layout_constraintHorizontal_bias="0.5"
215             app:layout_constraintStart_toEndOf="@ id/button2"
216             app:layout_constraintTop_toTopOf="@ id/button2" />
217 
218         <Button
219             android:id="@ id/button4"
220             android:layout_width="wrap_content"
221             android:layout_height="wrap_content"
222             android:text="@string/button4"
223             android:textSize="@dimen/button_font"
224             app:layout_constraintBottom_toTopOf="@ id/guideline11"
225             app:layout_constraintEnd_toStartOf="@ id/button5"
226             app:layout_constraintHorizontal_bias="0.5"
227             app:layout_constraintStart_toStartOf="@ id/guideline3"
228             app:layout_constraintTop_toTopOf="@ id/guideline10" />
229 
230         <Button
231             android:id="@ id/button6"
232             android:layout_width="wrap_content"
233             android:layout_height="wrap_content"
234             android:text="@string/button6"
235             android:textSize="@dimen/button_font"
236             app:layout_constraintBottom_toBottomOf="@ id/button5"
237             app:layout_constraintEnd_toStartOf="@ id/guideline4"
238             app:layout_constraintHorizontal_bias="0.5"
239             app:layout_constraintStart_toEndOf="@ id/button5"
240             app:layout_constraintTop_toTopOf="@ id/button5"
241             app:layout_constraintVertical_bias="0.0" />
242 
243         <Button
244             android:id="@ id/button5"
245             android:layout_width="wrap_content"
246             android:layout_height="wrap_content"
247             android:text="@string/button5"
248             android:textSize="@dimen/button_font"
249             app:layout_constraintBottom_toBottomOf="@ id/button4"
250             app:layout_constraintEnd_toStartOf="@ id/button6"
251             app:layout_constraintHorizontal_bias="0.5"
252             app:layout_constraintStart_toEndOf="@ id/button4"
253             app:layout_constraintTop_toTopOf="@ id/button4"
254             app:layout_constraintVertical_bias="0.0" />
255 
256         <Button
257             android:id="@ id/button7"
258             android:layout_width="wrap_content"
259             android:layout_height="wrap_content"
260             android:text="@string/button7"
261             android:textSize="@dimen/button_font"
262             app:layout_constraintBottom_toTopOf="@ id/guideline12"
263             app:layout_constraintEnd_toStartOf="@ id/button8"
264             app:layout_constraintHorizontal_bias="0.5"
265             app:layout_constraintStart_toStartOf="@ id/guideline3"
266             app:layout_constraintTop_toTopOf="@ id/guideline11" />
267 
268         <Button
269             android:id="@ id/button8"
270             android:layout_width="wrap_content"
271             android:layout_height="wrap_content"
272             android:text="@string/button8"
273             android:textSize="@dimen/button_font"
274             app:layout_constraintBottom_toBottomOf="@ id/button7"
275             app:layout_constraintEnd_toStartOf="@ id/button9"
276             app:layout_constraintHorizontal_bias="0.5"
277             app:layout_constraintStart_toEndOf="@ id/button7"
278             app:layout_constraintTop_toTopOf="@ id/button7" />
279 
280         <Button
281             android:id="@ id/button9"
282             android:layout_width="wrap_content"
283             android:layout_height="wrap_content"
284             android:text="@string/button9"
285             android:textSize="@dimen/button_font"
286             app:layout_constraintBottom_toBottomOf="@ id/button8"
287             app:layout_constraintEnd_toStartOf="@ id/guideline4"
288             app:layout_constraintHorizontal_bias="0.5"
289             app:layout_constraintStart_toEndOf="@ id/button8"
290             app:layout_constraintTop_toTopOf="@ id/button8" />
291 
292         <Button
293             android:id="@ id/buttonClear"
294             android:layout_width="wrap_content"
295             android:layout_height="wrap_content"
296             android:text="@string/buttonClear"
297             android:textSize="@dimen/button_font"
298             app:layout_constraintBottom_toTopOf="@ id/guideline9"
299             app:layout_constraintEnd_toStartOf="@ id/button0"
300             app:layout_constraintHorizontal_bias="0.5"
301             app:layout_constraintStart_toStartOf="@ id/guideline3"
302             app:layout_constraintTop_toTopOf="@ id/guideline12" />
303 
304         <Button
305             android:id="@ id/button0"
306             android:layout_width="wrap_content"
307             android:layout_height="wrap_content"
308             android:text="@string/button0"
309             android:textSize="@dimen/button_font"
310             app:layout_constraintBottom_toBottomOf="@ id/buttonClear"
311             app:layout_constraintEnd_toStartOf="@ id/buttonSubmit"
312             app:layout_constraintHorizontal_bias="0.5"
313             app:layout_constraintStart_toEndOf="@ id/buttonClear"
314             app:layout_constraintTop_toTopOf="@ id/buttonClear" />
315 
316         <Button
317             android:id="@ id/buttonSubmit"
318             android:layout_width="wrap_content"
319             android:layout_height="wrap_content"
320             android:text="@string/buttonSubmit"
321             android:textSize="@dimen/button_font"
322             app:layout_constraintBottom_toBottomOf="@ id/button0"
323             app:layout_constraintEnd_toStartOf="@ id/guideline4"
324             app:layout_constraintHorizontal_bias="0.5"
325             app:layout_constraintStart_toEndOf="@ id/button0"
326             app:layout_constraintTop_toTopOf="@ id/button0" />
327 
328     </androidx.constraintlayout.widget.ConstraintLayout>
329 </layout>

QuestionFragment.java

设置按键监听

 1 @Override
 2     public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
 3                              Bundle savedInstanceState) {
 4         final MyViewModel myViewModel;
 5         myViewModel = ViewModelProviders.of(requireActivity(), new SavedStateViewModelFactory(requireActivity())).get(MyViewModel.class);
 6         myViewModel.generator();
 7         myViewModel.getCurrentScore().setValue(0);
 8         final FragmentQuestionBinding binding;
 9         binding = DataBindingUtil.inflate(inflater, R.layout.fragment_question, container, false);
10         binding.setData(myViewModel);
11         binding.setLifecycleOwner(requireActivity());
12         final StringBuilder builder = new StringBuilder();
13         View.OnClickListener listener = new View.OnClickListener() {
14             @Override
15             public void onClick(View v) {
16                 switch (v.getId()) {
17                     case R.id.button0:
18                         builder.append("0");
19                         break;
20                     case R.id.button1:
21                         builder.append("1");
22                         break;
23                     case R.id.button2:
24                         builder.append("2");
25                         break;
26                     case R.id.button3:
27                         builder.append("3");
28                         break;
29                     case R.id.button4:
30                         builder.append("4");
31                         break;
32                     case R.id.button5:
33                         builder.append("5");
34                         break;
35                     case R.id.button6:
36                         builder.append("6");
37                         break;
38                     case R.id.button7:
39                         builder.append("7");
40                         break;
41                     case R.id.button8:
42                         builder.append("8");
43                         break;
44                     case R.id.button9:
45                         builder.append("9");
46                         break;
47                     case R.id.buttonClear:
48                         builder.setLength(0);
49                         break;
50                 }
51                 if (builder.length() == 0) {
52                     binding.textView9.setText(getString(R.string.input_indicator));
53                 } else {
54                     binding.textView9.setText(builder.toString());
55                 }
56             }
57         };
58 
59         binding.button0.setOnClickListener(listener);
60         binding.button1.setOnClickListener(listener);
61         binding.button2.setOnClickListener(listener);
62         binding.button3.setOnClickListener(listener);
63         binding.button4.setOnClickListener(listener);
64         binding.button5.setOnClickListener(listener);
65         binding.button6.setOnClickListener(listener);
66         binding.button7.setOnClickListener(listener);
67         binding.button8.setOnClickListener(listener);
68         binding.button9.setOnClickListener(listener);
69         binding.buttonClear.setOnClickListener(listener);
70 
71         binding.buttonSubmit.setOnClickListener(new View.OnClickListener() {
72             @Override
73             public void onClick(View v) {
74                 if (builder.length() == 0) {
75                     builder.append("-1");
76                 }
77                 if (Integer.valueOf(builder.toString()).intValue() == myViewModel.getAnswer().getValue()) {
78                     myViewModel.answerCorrect();
79                     builder.setLength(0);
80                     binding.textView9.setText(R.string.answer_correct_message);
81                 } else {
82                     NavController controller = Navigation.findNavController(v);
83                     if (myViewModel.win_flag) {
84                         controller.navigate(R.id.action_questionFragment_to_winFragment);
85                         myViewModel.win_flag = false;
86                         myViewModel.save();
87                     } else {
88                         controller.navigate(R.id.action_questionFragment_to_loseFragment);
89                     }
90                 }
91             }
92         });
93         return binding.getRoot();
94         // Inflate the layout for this fragment
95         //return inflater.inflate(R.layout.fragment_question, container, false);
96     }

 

fragment_win.xml

在创建drawable中创建矢量图

Android学习进度四

 

 

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <layout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:app="http://schemas.android.com/apk/res-auto"
 4     xmlns:tools="http://schemas.android.com/tools">
 5 
 6     <data>
 7         <variable
 8             name="data"
 9             type="com.example.calculationtest.MyViewModel" />
10     </data>
11 
12     <androidx.constraintlayout.widget.ConstraintLayout
13         android:layout_width="match_parent"
14         android:layout_height="match_parent"
15         tools:context=".WinFragment">
16 
17         <androidx.constraintlayout.widget.Guideline
18             android:id="@ id/guideline15"
19             android:layout_width="wrap_content"
20             android:layout_height="wrap_content"
21             android:orientation="horizontal"
22             app:layout_constraintGuide_percent="0.1" />
23 
24         <androidx.constraintlayout.widget.Guideline
25             android:id="@ id/guideline16"
26             android:layout_width="wrap_content"
27             android:layout_height="wrap_content"
28             android:orientation="horizontal"
29             app:layout_constraintGuide_percent="0.45" />
30 
31         <ImageView
32             android:id="@ id/imageView3"
33             android:layout_width="0dp"
34             android:layout_height="0dp"
35             android:layout_marginStart="8dp"
36             android:layout_marginTop="8dp"
37             android:layout_marginEnd="8dp"
38             android:layout_marginBottom="8dp"
39             android:contentDescription="@string/win_image_message"
40             android:src="@drawable/ic_sentiment_satisfied_black_24dp"
41             app:layout_constraintBottom_toTopOf="@ id/guideline16"
42             app:layout_constraintEnd_toEndOf="parent"
43             app:layout_constraintStart_toStartOf="parent"
44             app:layout_constraintTop_toTopOf="@ id/guideline15" />
45 
46         <TextView
47             android:id="@ id/textView12"
48             android:layout_width="wrap_content"
49             android:layout_height="wrap_content"
50             android:layout_marginStart="8dp"
51             android:layout_marginTop="8dp"
52             android:layout_marginEnd="8dp"
53             android:layout_marginBottom="8dp"
54             android:text="@string/win_message"
55             android:textSize="@dimen/big_font"
56             app:layout_constraintBottom_toBottomOf="parent"
57             app:layout_constraintEnd_toEndOf="parent"
58             app:layout_constraintStart_toStartOf="parent"
59             app:layout_constraintTop_toTopOf="@ id/guideline16"
60             app:layout_constraintVertical_bias="0.1" />
61 
62         <TextView
63             android:id="@ id/textView13"
64             android:layout_width="wrap_content"
65             android:layout_height="wrap_content"
66             android:layout_marginStart="8dp"
67             android:layout_marginTop="8dp"
68             android:layout_marginEnd="8dp"
69             android:layout_marginBottom="8dp"
70             android:text="@{@string/win_score_message(data.highScore)}"
71             android:textSize="@dimen/big_font"
72             app:layout_constraintBottom_toBottomOf="parent"
73             app:layout_constraintEnd_toEndOf="parent"
74             app:layout_constraintStart_toStartOf="parent"
75             app:layout_constraintTop_toBottomOf="@ id/imageView3"
76             app:layout_constraintVertical_bias="0.30"
77             tools:text="New Record:"/>
78 
79         <Button
80             android:id="@ id/button11"
81             android:layout_width="wrap_content"
82             android:layout_height="wrap_content"
83             android:layout_marginStart="8dp"
84             android:layout_marginTop="8dp"
85             android:layout_marginEnd="8dp"
86             android:layout_marginBottom="8dp"
87             android:text="@string/button_back_to_title"
88             android:textSize="@dimen/button_font"
89             app:layout_constraintBottom_toBottomOf="parent"
90             app:layout_constraintEnd_toEndOf="parent"
91             app:layout_constraintStart_toStartOf="parent"
92             app:layout_constraintTop_toBottomOf="@ id/imageView3"
93             app:layout_constraintVertical_bias="0.55" />
94     </androidx.constraintlayout.widget.ConstraintLayout>
95 </layout>

WinFragment.java

创建Back键返回初始界面监听

 1 @Override
 2     public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
 3                              Bundle savedInstanceState) {
 4         // Inflate the layout for this fragment
 5         MyViewModel myViewModel = ViewModelProviders.of(requireActivity(),new SavedStateViewModelFactory(requireActivity())).get(MyViewModel.class);
 6         FragmentWinBinding binding;
 7         binding = DataBindingUtil.inflate(inflater,R.layout.fragment_win,container,false);
 8         binding.setData(myViewModel);
 9         binding.setLifecycleOwner(requireActivity());
10         binding.button11.setOnClickListener(new View.OnClickListener() {
11             @Override
12             public void onClick(View v) {
13                 Navigation.findNavController(v).navigate(R.id.action_winFragment_to_titleFragment);
14             }
15         });
16         return binding.getRoot();
17         //return inflater.inflate(R.layout.fragment_win, container, false);
18     }

 

fragment_lose.xml

同理先创建矢量图

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <layout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:app="http://schemas.android.com/apk/res-auto"
 4     xmlns:tools="http://schemas.android.com/tools">
 5 
 6     <data>
 7         <variable
 8             name="data"
 9             type="com.example.calculationtest.MyViewModel" />
10     </data>
11 
12     <androidx.constraintlayout.widget.ConstraintLayout
13         android:layout_width="match_parent"
14         android:layout_height="match_parent"
15         tools:context=".LoseFragment">
16 
17         <androidx.constraintlayout.widget.Guideline
18             android:id="@ id/guideline13"
19             android:layout_width="wrap_content"
20             android:layout_height="wrap_content"
21             android:orientation="horizontal"
22             app:layout_constraintGuide_percent="0.1" />
23 
24         <androidx.constraintlayout.widget.Guideline
25             android:id="@ id/guideline14"
26             android:layout_width="wrap_content"
27             android:layout_height="wrap_content"
28             android:orientation="horizontal"
29             app:layout_constraintGuide_percent="0.45" />
30 
31         <ImageView
32             android:id="@ id/imageView2"
33             android:layout_width="0dp"
34             android:layout_height="0dp"
35             android:layout_marginStart="8dp"
36             android:layout_marginTop="8dp"
37             android:layout_marginEnd="8dp"
38             android:layout_marginBottom="8dp"
39             android:contentDescription="@string/lose_image_message"
40             android:src="@drawable/ic_sentiment_dissatisfied_black_24dp"
41             app:layout_constraintBottom_toTopOf="@ id/guideline14"
42             app:layout_constraintEnd_toEndOf="parent"
43             app:layout_constraintStart_toStartOf="parent"
44             app:layout_constraintTop_toTopOf="@ id/guideline13" />
45 
46         <TextView
47             android:id="@ id/textView10"
48             android:layout_width="wrap_content"
49             android:layout_height="wrap_content"
50             android:layout_marginStart="8dp"
51             android:layout_marginTop="8dp"
52             android:layout_marginEnd="8dp"
53             android:layout_marginBottom="8dp"
54             android:text="@string/lose_message"
55             android:textSize="@dimen/big_font"
56             app:layout_constraintBottom_toBottomOf="parent"
57             app:layout_constraintEnd_toEndOf="parent"
58             app:layout_constraintHorizontal_bias="0.5"
59             app:layout_constraintStart_toStartOf="parent"
60             app:layout_constraintTop_toTopOf="@ id/guideline14"
61             app:layout_constraintVertical_bias="0.1" />
62 
63         <TextView
64             android:id="@ id/textView11"
65             android:layout_width="wrap_content"
66             android:layout_height="wrap_content"
67             android:layout_marginStart="8dp"
68             android:layout_marginTop="8dp"
69             android:layout_marginEnd="8dp"
70             android:layout_marginBottom="8dp"
71             android:text="@{@string/lose_score_message(data.currentScore)}"
72             android:textSize="@dimen/big_font"
73             app:layout_constraintBottom_toBottomOf="parent"
74             app:layout_constraintEnd_toEndOf="parent"
75             app:layout_constraintStart_toStartOf="parent"
76             app:layout_constraintTop_toTopOf="@ id/guideline14"
77             app:layout_constraintVertical_bias="0.30"
78             tools:text="Your Score:"/>
79 
80         <Button
81             android:id="@ id/button10"
82             android:layout_width="wrap_content"
83             android:layout_height="wrap_content"
84             android:text="@string/button_back_to_title"
85             android:textSize="@dimen/button_font"
86             app:layout_constraintBottom_toBottomOf="parent"
87             app:layout_constraintEnd_toEndOf="parent"
88             app:layout_constraintHorizontal_bias="0.50"
89             app:layout_constraintStart_toStartOf="parent"
90             app:layout_constraintTop_toTopOf="@ id/guideline14"
91             app:layout_constraintVertical_bias="0.55" />
92     </androidx.constraintlayout.widget.ConstraintLayout>
93 </layout>

LoseFragment.java

创建Back键返回初始界面监听

 1 @Override
 2     public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
 3                              Bundle savedInstanceState) {
 4         MyViewModel myViewModel = ViewModelProviders.of(requireActivity(),new SavedStateViewModelFactory(requireActivity())).get(MyViewModel.class);
 5         FragmentLoseBinding binding;
 6         binding = DataBindingUtil.inflate(inflater,R.layout.fragment_lose,container,false);
 7         binding.setData(myViewModel);
 8         binding.setLifecycleOwner(requireActivity());
 9         binding.button10.setOnClickListener(new View.OnClickListener() {
10             @Override
11             public void onClick(View v) {
12                 Navigation.findNavController(v).navigate(R.id.action_loseFragment_to_titleFragment);
13             }
14         });
15         return binding.getRoot();
16         // Inflate the layout for this fragment
17         //return inflater.inflate(R.layout.fragment_lose, container, false);
18     }

 

二、确定页面之间跳转关系

1)创建navigation

Android学习进度四

 

Android学习进度四

 

2)导入fargment

Android学习进度四

 

三、导航栏返回键建立以及返回键的拦截

MainActivity.java

 1 package com.example.calculationtest;
 2 
 3 import androidx.appcompat.app.AlertDialog;
 4 import androidx.appcompat.app.AppCompatActivity;
 5 import androidx.navigation.NavController;
 6 import androidx.navigation.Navigation;
 7 import androidx.navigation.ui.NavigationUI;
 8 
 9 import android.content.DialogInterface;
10 import android.os.Bundle;
11 
12 public class MainActivity extends AppCompatActivity {
13     NavController controller;
14 
15     @Override
16     protected void onCreate(Bundle savedInstanceState) {
17         super.onCreate(savedInstanceState);
18         setContentView(R.layout.activity_main);
19         controller = Navigation.findNavController(this, R.id.fragment);
20         NavigationUI.setupActionBarWithNavController(this, controller);
21     }
22 
23     @Override
24     public boolean onSupportNavigateUp() {
25         if (controller.getCurrentDestination().getId() == R.id.questionFragment) {
26             AlertDialog.Builder builder = new AlertDialog.Builder(this);
27             builder.setTitle(getString(R.string.quit_dialog_title));
28             builder.setPositiveButton(R.string.dialog_positive_message, new DialogInterface.OnClickListener() {
29                 @Override
30                 public void onClick(DialogInterface dialog, int which) {
31                     controller.navigateUp();
32                 }
33             });
34             builder.setNegativeButton(R.string.dialog_negative_message, new DialogInterface.OnClickListener() {
35                 @Override
36                 public void onClick(DialogInterface dialog, int which) {
37 
38                 }
39             });
40             AlertDialog dialog = builder.create();
41             dialog.show();
42         } else if (controller.getCurrentDestination().getId() == R.id.titleFragment) {
43             finish();
44         } else {
45             controller.navigate(R.id.titleFragment);
46         }
47         return super.onSupportNavigateUp();
48     }
49 
50     @Override
51     public void onBackPressed() {
52         onSupportNavigateUp();
53     }
54 }

当点击返回键时会弹出提示框确认是否离开。

 

四、本地化

完整的App可以适应手机语言来改变自己所显示的语言

strings.xml

 1 <resources>
 2     <string name="app_name">CalculationTest</string>
 3 
 4     <!-- TODO: Remove or change this placeholder text -->
 5     <string name="hello_blank_fragment" translatable="false">Hello blank fragment</string>
 6     <string name="title_message">Calculation Test</string>
 7     <string name="title_image_info" translatable="false">title image</string>
 8     <string name="title_button_message">Enter</string>
 9     <string name="high_score_message">High Score:%d</string>
10     <string name="button0" translatable="false">0</string>
11     <string name="button1" translatable="false">1</string>
12     <string name="button2" translatable="false">2</string>
13     <string name="button3" translatable="false">3</string>
14     <string name="button4" translatable="false">4</string>
15     <string name="button5" translatable="false">5</string>
16     <string name="button6" translatable="false">6</string>
17     <string name="button7" translatable="false">7</string>
18     <string name="button8" translatable="false">8</string>
19     <string name="button9" translatable="false">9</string>
20     <string name="buttonClear" translatable="false">C</string>
21     <string name="buttonSubmit">OK</string>
22     <string name="equal_symbol" translatable="false">=</string>
23     <string name="question_mark" translatable="false">?</string>
24     <string name="current_score">Score:%d</string>
25     <string name="input_indicator">Your Answer:</string>
26     <string name="win_image_message" translatable="false">win image</string>
27     <string name="lose_image_message" translatable="false">lose image</string>
28     <string name="lose_message">You Lose!</string>
29     <string name="win_message">You Win!</string>
30     <string name="lose_score_message">Your Score:%d</string>
31     <string name="win_score_message">New Record:%d</string>
32     <string name="button_back_to_title">Back</string>
33     <string name="answer_correct_message">Correct!Go On!</string>
34     <string name="quit_dialog_title">Are you sure to quit?</string>
35     <string name="dialog_positive_message">OK</string>
36     <string name="dialog_negative_message">Cancel</string>
37     <string name="title_nav_message">Welcome</string>
38     <string name="question_nav_message">Testing</string>
39     <string name="win_nav_message">Win</string>
40     <string name="lose_nav_message">Lose</string>
41 </resources>

 

strings.xml(zh-rCN)

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <resources>
 3     <string name="app_name">口算测试</string>
 4     <string name="answer_correct_message">回答正确! 请继续!</string>
 5     <string name="buttonSubmit">确定</string>
 6     <string name="button_back_to_title">返回</string>
 7     <string name="current_score">得分:%d</string>
 8     <string name="dialog_negative_message">取消</string>
 9     <string name="dialog_positive_message">确定</string>
10     <string name="high_score_message">最高纪录:%d</string>
11     <string name="title_button_message">进入</string>
12     <string name="win_score_message">创造新纪录:%d</string>
13     <string name="win_message">挑战成功!</string>
14     <string name="title_message">口算测试</string>
15     <string name="quit_dialog_title">确定离开?</string>
16     <string name="lose_score_message">你的得分:%d</string>
17     <string name="lose_message">挑战失败!</string>
18     <string name="input_indicator">请开始答题:</string>
19     <string name="question_nav_message">测试</string>
20     <string name="title_nav_message">欢迎</string>
21     <string name="win_nav_message">胜利</string>
22     <string name="lose_nav_message">失败</string>
23 </resources>