Android学习进度四 一.界面的搭建 二.确定页面之间跳转关系 三.导航栏返回键建立以及返回键的拦截 四.本地化
经过一段时间观看视频进行Android的学习,将现今所学知识进行阶段性总结编写了一款口算测试App,并成功将其打包成apk在手机上运行。主要使用了LiveData,DataBinding,ViewModel以及Fragment等,话不多说,上代码。
创建四个界面,分别为TitleFragment,QuestionFragment,WinFragment以及LoseFragment
因为使用了DataBinding和LiveData,要在build.gradle中添加依赖
dataBinding.enabled true
implementation 'androidx.lifecycle:lifecycle-viewmodel-savedstate:1.0.0-alpha02'//最新的依赖可以在官网中找到
创建MyViewModel.java,继承自AndroidViewModel
package com.example.calculationtest; import android.app.Application; import android.content.Context; import android.content.SharedPreferences; import androidx.annotation.NonNull; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.SavedStateHandle; import java.util.Random; public class MyViewModel extends AndroidViewModel { private SavedStateHandle handle; private static String KEY_HIGH_SCORE = "key_high_score"; private static String KEY_LEFT_NUMBER = "key_left_number"; private static String KEY_RIGHT_NUMBER = "key_right_number"; private static String KEY_OPERATOR = "key_operator"; private static String KEY_ANSWER = "key_answer"; private static String SAVE_SHP_DATA_NAME = "save_shp_data_name"; 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; } public MutableLiveData<Integer> getLeftNumber() { return handle.getLiveData(KEY_LEFT_NUMBER); } public MutableLiveData<Integer> getRightNumber() { return handle.getLiveData(KEY_RIGHT_NUMBER); } public MutableLiveData<String> getOpreator() { return handle.getLiveData(KEY_OPERATOR); } public MutableLiveData<Integer> getHighScore() { return handle.getLiveData(KEY_HIGH_SCORE); } public MutableLiveData<Integer> getCurrentScore() { return handle.getLiveData(KEY_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) { getOpreator().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 { getOpreator().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(); } }
fragment_title.xml
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> <data> <variable name="data" type="com.example.calculationtest.MyViewModel" /> </data> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".TitleFragment"> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_percent="0.1" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_percent="0.9" /> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" android:text="@string/title_message" android:textAlignment="center" android:textSize="@dimen/big_font" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/guideline2" app:layout_constraintHorizontal_bias="0.652" app:layout_constraintStart_toStartOf="@+id/guideline" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.201" /> <ImageView android:id="@+id/imageView" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" android:contentDescription="@string/title_image_info" android:src="@drawable/titleimage" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintDimensionRatio="w,1:1" app:layout_constraintEnd_toStartOf="@+id/guideline2" app:layout_constraintStart_toStartOf="@+id/guideline" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/button" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" android:text="@string/title_button_message" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="@+id/imageView" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="@+id/imageView" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.85" /> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{@string/high_score_message(data.highScore)}" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.875" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.116" tools:text="High Score:%d" /> </androidx.constraintlayout.widget.ConstraintLayout> </layout>
- imageview所用图片是网上下载的
- 右上角的"high score :%d",需要与viewmodel中的数据绑定
- 点击Enter,即可进入答题界面
TitleFragment.java
@Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { MyViewModel myViewModel; myViewModel = ViewModelProviders.of(requireActivity(), new SavedStateViewModelFactory(requireActivity())).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 v) { NavController controller = Navigation.findNavController(v); 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); }
fragment_question.xml
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> <data> <variable name="data" type="com.example.calculationtest.MyViewModel" /> </data> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".QuestionFragment"> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline9" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.85" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline8" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.45" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.37" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_percent="0.1" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" app:layout_constraintGuide_percent="0.9" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.15" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.25" /> <TextView android:id="@+id/textView3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" android:text="@{@string/current_score(data.currentScore)}" app:layout_constraintBottom_toTopOf="@+id/guideline5" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline5" tools:text="Score:5" /> <TextView android:id="@+id/textView4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{String.valueOf(safeUnbox(data.leftNumber))}" android:textSize="@dimen/huge_font" app:layout_constraintBottom_toBottomOf="@+id/textView5" app:layout_constraintEnd_toStartOf="@+id/textView5" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="@+id/guideline3" app:layout_constraintTop_toTopOf="@+id/textView5" tools:text="8" /> <TextView android:id="@+id/textView5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{data.opreator}" android:textSize="@dimen/huge_font" app:layout_constraintBottom_toBottomOf="@+id/textView6" app:layout_constraintEnd_toStartOf="@+id/textView6" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/textView4" app:layout_constraintTop_toTopOf="@+id/textView6" tools:text="+" /> <TextView android:id="@+id/textView6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{String.valueOf(safeUnbox(data.rightNumber))}" android:textSize="@dimen/huge_font" app:layout_constraintBottom_toBottomOf="@+id/textView7" app:layout_constraintEnd_toStartOf="@+id/textView7" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/textView5" app:layout_constraintTop_toTopOf="@+id/textView7" tools:text="9" /> <TextView android:id="@+id/textView7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/equal_symbol" android:textSize="@dimen/huge_font" app:layout_constraintBottom_toBottomOf="@+id/textView8" app:layout_constraintEnd_toStartOf="@+id/textView8" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/textView6" app:layout_constraintTop_toTopOf="@+id/textView8" tools:text="=" /> <TextView android:id="@+id/textView8" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/question_mark" android:textSize="@dimen/huge_font" app:layout_constraintBottom_toTopOf="@+id/guideline6" app:layout_constraintEnd_toStartOf="@+id/guideline4" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/textView7" app:layout_constraintTop_toTopOf="@+id/guideline6" tools:text="?" /> <TextView android:id="@+id/textView9" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" android:text="@string/input_indicator" android:textSize="@dimen/mid_font" app:layout_constraintBottom_toTopOf="@+id/guideline7" app:layout_constraintEnd_toStartOf="@+id/guideline4" app:layout_constraintStart_toStartOf="@+id/guideline3" app:layout_constraintTop_toTopOf="@+id/guideline7" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline10" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.55" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline11" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.65" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline12" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.75" /> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button1" android:textSize="@dimen/button_font" app:layout_constraintBottom_toTopOf="@+id/guideline10" app:layout_constraintEnd_toStartOf="@+id/button2" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="@+id/guideline3" app:layout_constraintTop_toTopOf="@+id/guideline8" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button2" android:textSize="@dimen/button_font" app:layout_constraintBottom_toBottomOf="@+id/button1" app:layout_constraintEnd_toStartOf="@+id/button3" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/button1" app:layout_constraintTop_toTopOf="@+id/button1" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button3" android:textSize="@dimen/button_font" app:layout_constraintBottom_toBottomOf="@+id/button2" app:layout_constraintEnd_toStartOf="@+id/guideline4" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/button2" app:layout_constraintTop_toTopOf="@+id/button2" /> <Button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button4" android:textSize="@dimen/button_font" app:layout_constraintBottom_toTopOf="@+id/guideline11" app:layout_constraintEnd_toStartOf="@+id/button5" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="@+id/guideline3" app:layout_constraintTop_toTopOf="@+id/guideline10" /> <Button android:id="@+id/button6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button6" android:textSize="@dimen/button_font" app:layout_constraintBottom_toBottomOf="@+id/button5" app:layout_constraintEnd_toStartOf="@+id/guideline4" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/button5" app:layout_constraintTop_toTopOf="@+id/button5" app:layout_constraintVertical_bias="0.0" /> <Button android:id="@+id/button5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button5" android:textSize="@dimen/button_font" app:layout_constraintBottom_toBottomOf="@+id/button4" app:layout_constraintEnd_toStartOf="@+id/button6" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/button4" app:layout_constraintTop_toTopOf="@+id/button4" app:layout_constraintVertical_bias="0.0" /> <Button android:id="@+id/button7" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button7" android:textSize="@dimen/button_font" app:layout_constraintBottom_toTopOf="@+id/guideline12" app:layout_constraintEnd_toStartOf="@+id/button8" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="@+id/guideline3" app:layout_constraintTop_toTopOf="@+id/guideline11" /> <Button android:id="@+id/button8" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button8" android:textSize="@dimen/button_font" app:layout_constraintBottom_toBottomOf="@+id/button7" app:layout_constraintEnd_toStartOf="@+id/button9" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/button7" app:layout_constraintTop_toTopOf="@+id/button7" /> <Button android:id="@+id/button9" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button9" android:textSize="@dimen/button_font" app:layout_constraintBottom_toBottomOf="@+id/button8" app:layout_constraintEnd_toStartOf="@+id/guideline4" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/button8" app:layout_constraintTop_toTopOf="@+id/button8" /> <Button android:id="@+id/buttonClear" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/buttonClear" android:textSize="@dimen/button_font" app:layout_constraintBottom_toTopOf="@+id/guideline9" app:layout_constraintEnd_toStartOf="@+id/button0" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="@+id/guideline3" app:layout_constraintTop_toTopOf="@+id/guideline12" /> <Button android:id="@+id/button0" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button0" android:textSize="@dimen/button_font" app:layout_constraintBottom_toBottomOf="@+id/buttonClear" app:layout_constraintEnd_toStartOf="@+id/buttonSubmit" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/buttonClear" app:layout_constraintTop_toTopOf="@+id/buttonClear" /> <Button android:id="@+id/buttonSubmit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/buttonSubmit" android:textSize="@dimen/button_font" app:layout_constraintBottom_toBottomOf="@+id/button0" app:layout_constraintEnd_toStartOf="@+id/guideline4" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toEndOf="@+id/button0" app:layout_constraintTop_toTopOf="@+id/button0" /> </androidx.constraintlayout.widget.ConstraintLayout> </layout>
QuestionFragment.java
设置按键监听
@Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final MyViewModel myViewModel; myViewModel = ViewModelProviders.of(requireActivity(), new SavedStateViewModelFactory(requireActivity())).get(MyViewModel.class); myViewModel.generator(); myViewModel.getCurrentScore().setValue(0); final FragmentQuestionBinding binding; binding = DataBindingUtil.inflate(inflater, R.layout.fragment_question, container, false); binding.setData(myViewModel); binding.setLifecycleOwner(requireActivity()); final StringBuilder builder = new StringBuilder(); View.OnClickListener listener = new View.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()) { case R.id.button0: builder.append("0"); break; case R.id.button1: builder.append("1"); break; case R.id.button2: builder.append("2"); break; case R.id.button3: builder.append("3"); break; case R.id.button4: builder.append("4"); break; case R.id.button5: builder.append("5"); break; case R.id.button6: builder.append("6"); break; case R.id.button7: builder.append("7"); break; case R.id.button8: builder.append("8"); break; case R.id.button9: builder.append("9"); break; case R.id.buttonClear: 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() { @Override public void onClick(View v) { if (builder.length() == 0) { builder.append("-1"); } if (Integer.valueOf(builder.toString()).intValue() == myViewModel.getAnswer().getValue()) { myViewModel.answerCorrect(); builder.setLength(0); binding.textView9.setText(R.string.answer_correct_message); } else { NavController controller = Navigation.findNavController(v); 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(); // Inflate the layout for this fragment //return inflater.inflate(R.layout.fragment_question, container, false); } }
fragment_win.xml
在创建drawable中创建矢量图
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> <data> <variable name="data" type="com.example.calculationtest.MyViewModel" /> </data> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".WinFragment"> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline15" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.1" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline16" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.45" /> <ImageView android:id="@+id/imageView3" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" android:contentDescription="@string/win_image_message" android:src="@drawable/ic_sentiment_satisfied_black_24dp" app:layout_constraintBottom_toTopOf="@+id/guideline16" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline15" /> <TextView android:id="@+id/textView12" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" android:text="@string/win_message" android:textSize="@dimen/big_font" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline16" app:layout_constraintVertical_bias="0.1" /> <TextView android:id="@+id/textView13" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" android:text="@{@string/win_score_message(data.highScore)}" android:textSize="@dimen/big_font" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/imageView3" app:layout_constraintVertical_bias="0.30" tools:text="New Record:"/> <Button android:id="@+id/button11" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" android:text="@string/button_back_to_title" android:textSize="@dimen/button_font" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/imageView3" app:layout_constraintVertical_bias="0.55" /> </androidx.constraintlayout.widget.ConstraintLayout> </layout>
WinFragment.java
创建Back键返回初始界面监听
@Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment MyViewModel myViewModel = ViewModelProviders.of(requireActivity(),new SavedStateViewModelFactory(requireActivity())).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 v) { Navigation.findNavController(v).navigate(R.id.action_winFragment_to_titleFragment); } }); return binding.getRoot(); //return inflater.inflate(R.layout.fragment_win, container, false); }
fragment_lose.xml
同理先创建矢量图
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> <data> <variable name="data" type="com.example.calculationtest.MyViewModel" /> </data> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".LoseFragment"> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline13" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.1" /> <androidx.constraintlayout.widget.Guideline android:id="@+id/guideline14" android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" app:layout_constraintGuide_percent="0.45" /> <ImageView android:id="@+id/imageView2" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" android:contentDescription="@string/lose_image_message" android:src="@drawable/ic_sentiment_dissatisfied_black_24dp" app:layout_constraintBottom_toTopOf="@+id/guideline14" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline13" /> <TextView android:id="@+id/textView10" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" android:text="@string/lose_message" android:textSize="@dimen/big_font" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.5" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline14" app:layout_constraintVertical_bias="0.1" /> <TextView android:id="@+id/textView11" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginBottom="8dp" android:text="@{@string/lose_score_message(data.currentScore)}" android:textSize="@dimen/big_font" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline14" app:layout_constraintVertical_bias="0.30" tools:text="Your Score:"/> <Button android:id="@+id/button10" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button_back_to_title" android:textSize="@dimen/button_font" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.50" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="@+id/guideline14" app:layout_constraintVertical_bias="0.55" /> </androidx.constraintlayout.widget.ConstraintLayout> </layout>
LoseFragment.java
创建Back键返回初始界面监听
@Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { MyViewModel myViewModel = ViewModelProviders.of(requireActivity(),new SavedStateViewModelFactory(requireActivity())).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 v) { Navigation.findNavController(v).navigate(R.id.action_loseFragment_to_titleFragment); } }); return binding.getRoot(); // Inflate the layout for this fragment //return inflater.inflate(R.layout.fragment_lose, container, false); }
二.确定页面之间跳转关系
1)创建navigation
2)导入fargment
三.导航栏返回键建立以及返回键的拦截
MainActivity.java
package com.example.calculationtest; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.navigation.NavController; import androidx.navigation.Navigation; import androidx.navigation.ui.NavigationUI; import android.content.DialogInterface; import android.os.Bundle; public class MainActivity extends AppCompatActivity { NavController controller; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); controller = Navigation.findNavController(this, R.id.fragment); NavigationUI.setupActionBarWithNavController(this, controller); } @Override public boolean onSupportNavigateUp() { if (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, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { controller.navigateUp(); } }); builder.setNegativeButton(R.string.dialog_negative_message, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); AlertDialog dialog = builder.create(); dialog.show(); } else if (controller.getCurrentDestination().getId() == R.id.titleFragment) { finish(); } else { controller.navigate(R.id.titleFragment); } return super.onSupportNavigateUp(); } @Override public void onBackPressed() { onSupportNavigateUp(); } }
当点击返回键时会弹出提示框确认是否离开。
四.本地化
完整的App可以适应手机语言来改变自己所显示的语言
strings.xml
<resources> <string name="app_name">CalculationTest</string> <!-- TODO: Remove or change this placeholder text --> <string name="hello_blank_fragment" translatable="false">Hello blank fragment</string> <string name="title_message">Calculation Test</string> <string name="title_image_info" translatable="false">title image</string> <string name="title_button_message">Enter</string> <string name="high_score_message">High Score:%d</string> <string name="button0" translatable="false">0</string> <string name="button1" translatable="false">1</string> <string name="button2" translatable="false">2</string> <string name="button3" translatable="false">3</string> <string name="button4" translatable="false">4</string> <string name="button5" translatable="false">5</string> <string name="button6" translatable="false">6</string> <string name="button7" translatable="false">7</string> <string name="button8" translatable="false">8</string> <string name="button9" translatable="false">9</string> <string name="buttonClear" translatable="false">C</string> <string name="buttonSubmit">OK</string> <string name="equal_symbol" translatable="false">=</string> <string name="question_mark" translatable="false">?</string> <string name="current_score">Score:%d</string> <string name="input_indicator">Your Answer:</string> <string name="win_image_message" translatable="false">win image</string> <string name="lose_image_message" translatable="false">lose 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> <string name="answer_correct_message">Correct!Go On!</string> <string name="quit_dialog_title">Are you sure to quit?</string> <string name="dialog_positive_message">OK</string> <string name="dialog_negative_message">Cancel</string> <string name="title_nav_message">Welcome</string> <string name="question_nav_message">Testing</string> <string name="win_nav_message">Win</string> <string name="lose_nav_message">Lose</string> </resources>
strings.xml(zh-rCN)
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">口算测试</string> <string name="answer_correct_message">回答正确! 请继续!</string> <string name="buttonSubmit">确定</string> <string name="button_back_to_title">返回</string> <string name="current_score">得分:%d</string> <string name="dialog_negative_message">取消</string> <string name="dialog_positive_message">确定</string> <string name="high_score_message">最高纪录:%d</string> <string name="title_button_message">进入</string> <string name="win_score_message">创造新纪录:%d</string> <string name="win_message">挑战成功!</string> <string name="title_message">口算测试</string> <string name="quit_dialog_title">确定离开?</string> <string name="lose_score_message">你的得分:%d</string> <string name="lose_message">挑战失败!</string> <string name="input_indicator">请开始答题:</string> <string name="question_nav_message">测试</string> <string name="title_nav_message">欢迎</string> <string name="win_nav_message">胜利</string> <string name="lose_nav_message">失败</string> </resources>