最近综合了一下android学的知识也根据up主的视频开发了一款适合儿童的口算app,下面我来大致介绍一下这款app的功能和开发思路:
首先看一下我的na'vgation(页面导航):开始是欢迎页面,之后点击enter会进入答题页面,之后答对会得一分,每次直到答题错误会再之后的页面生成你的成绩,如果你的成绩大于历史得分对高分,就会跳转到Win页面,否则跳转到Lose页面。
首页面:
答题页面:
Lose界面:
win界面:
下面我给一些源码供大家看一下:
java代码:
loseFragment:
package com.example.canceltext; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.databinding.DataBindingUtil; import androidx.fragment.app.Fragment; import androidx.lifecycle.SavedStateViewModelFactory; import androidx.lifecycle.ViewModelProviders; import androidx.navigation.Navigation; import com.example.canceltext.databinding.FragmentDefeatBinding; /** * A simple {@link Fragment} subclass. */ public class loseFragment extends Fragment { public loseFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { MyViewModel myViewModel; myViewModel = ViewModelProviders.of(requireActivity(), new SavedStateViewModelFactory(requireActivity().getApplication(), requireActivity())).get(MyViewModel.class); final FragmentDefeatBinding binding ; binding = DataBindingUtil.inflate(inflater, R.layout.fragment_defeat,container,false); binding.setData(myViewModel); binding.setLifecycleOwner(getActivity()); binding.button14.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Navigation.findNavController(v).navigate(R.id.action_loseFragment_to_tatelFragment); } }); // Inflate the layout for this fragment return binding.getRoot(); } }
MainActivity:
package com.example.canceltext; import android.content.DialogInterface; import android.os.Bundle; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.navigation.NavController; import androidx.navigation.Navigation; import androidx.navigation.ui.NavigationUI; 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(R.string.quit_dialog_title); builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { controller.navigateUp(); } }); builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); } return super.onSupportNavigateUp(); } @Override public void onBackPressed() { onSupportNavigateUp(); } }
MyViewModel:
package com.example.canceltext; 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 { 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"; private static String KEY_LOSE_SCORE = "key_lose_score"; public static 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_ANSWER,0); handle.set(KEY_OPERATOR,"+"); handle.set(KEY_CURRENT_SCORE,0); } this.handle= handle; } public MutableLiveData<Integer> getLiftnumber(){ return handle.getLiveData(KEY_LEFT_NUMBER); } public MutableLiveData<Integer> getRightnumber(){ return handle.getLiveData(KEY_RIGHT_NUMBER); } public MutableLiveData<Integer> getHighScore(){ return handle.getLiveData(KEY_HIGH_SCORE); } public MutableLiveData<Integer> getCurrentScore(){ return handle.getLiveData(KEY_CURRENT_SCORE); } public MutableLiveData<Integer> getLoseScore(){ return handle.getLiveData(KEY_LOSE_SCORE); } public MutableLiveData<String> getOperator(){ return handle.getLiveData(KEY_OPERATOR); } public MutableLiveData<Integer> getAnswer(){ return handle.getLiveData(KEY_ANSWER); } void generator(){ int LEVEL = 20; Random random = new Random(); int x =random.nextInt(LEVEL)+1; int y =random.nextInt(LEVEL)+1; if(x%2==0){ getOperator().setValue("+"); if(x>y){ getAnswer().setValue(x); getLiftnumber().setValue(y); getRightnumber().setValue(x-y); }else{ getAnswer().setValue(y); getLiftnumber().setValue(x); getRightnumber().setValue(y-x); } }else{ getOperator().setValue("-"); if(x>y){ getAnswer().setValue(x-y); getLiftnumber().setValue(x); getRightnumber().setValue(y); }else{ getAnswer().setValue(y-x); getLiftnumber().setValue(y); getRightnumber().setValue(x); } } } void save(){ SharedPreferences sharedPreferences = getApplication().getSharedPreferences(SAVE_SHP_DATA_NAME,Context.MODE_PRIVATE); SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putInt(KEY_HIGH_SCORE,getHighScore().getValue()); editor.apply(); } @SuppressWarnings("ConstantConditions") void answerCurrent(){ getCurrentScore().setValue(getCurrentScore().getValue() + 1); if(getCurrentScore().getValue()>getHighScore().getValue()){ getHighScore().setValue(getCurrentScore().getValue()); WIN_FLAG =true; } generator(); } }
questionFragment:
package com.example.canceltext; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.databinding.DataBindingUtil; import androidx.fragment.app.Fragment; import androidx.lifecycle.SavedStateViewModelFactory; import androidx.lifecycle.ViewModelProviders; import androidx.navigation.NavController; import androidx.navigation.Navigation; import com.example.canceltext.databinding.FragmentQuestionBinding; /** * A simple {@link Fragment} subclass. */ public class questionFragment extends Fragment { public questionFragment() { // Required empty public constructor } @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final MyViewModel myViewModel; myViewModel = ViewModelProviders.of(requireActivity(), new SavedStateViewModelFactory(requireActivity().getApplication(), requireActivity())).get(MyViewModel.class); myViewModel.generator(); final FragmentQuestionBinding binding; binding = DataBindingUtil.inflate(inflater, R.layout.fragment_question,container,false); binding.setLifecycleOwner(requireActivity()); binding.setData(myViewModel); final StringBuilder builder = new StringBuilder(); View.OnClickListener listener = new View.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()){ 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.button10: builder.setLength(0); break; case R.id.button11: builder.append("0"); break; } if(builder.length()==0){ binding.textView9.setText(getString(R.string.input)); } else{ binding.textView9.setText(getString(R.string.input)+builder.toString()); } } }; 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.button10.setOnClickListener(listener); binding.button11.setOnClickListener(listener); binding.button12.setOnClickListener(new View.OnClickListener() { @SuppressWarnings("ConstantConditions") @Override public void onClick(View v) { if(Integer.valueOf(builder.toString()).intValue()==myViewModel.getAnswer().getValue()){ myViewModel.answerCurrent(); 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); } myViewModel.getLoseScore().setValue(myViewModel.getCurrentScore().getValue()); myViewModel.getCurrentScore().setValue(0); } } }); return binding.getRoot(); // Inflate the layout for this fragment // return inflater.inflate(R.layout.fragment_question, container, false); } }
tatelFragment:
package com.example.canceltext; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.databinding.DataBindingUtil; import androidx.fragment.app.Fragment; import androidx.lifecycle.SavedStateViewModelFactory; import androidx.lifecycle.ViewModelProviders; import androidx.navigation.NavController; import androidx.navigation.Navigation; import com.example.canceltext.databinding.FragmentQuestionBinding; /** * A simple {@link Fragment} subclass. */ public class questionFragment extends Fragment { public questionFragment() { // Required empty public constructor } @Override public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { final MyViewModel myViewModel; myViewModel = ViewModelProviders.of(requireActivity(), new SavedStateViewModelFactory(requireActivity().getApplication(), requireActivity())).get(MyViewModel.class); myViewModel.generator(); final FragmentQuestionBinding binding; binding = DataBindingUtil.inflate(inflater, R.layout.fragment_question,container,false); binding.setLifecycleOwner(requireActivity()); binding.setData(myViewModel); final StringBuilder builder = new StringBuilder(); View.OnClickListener listener = new View.OnClickListener() { @Override public void onClick(View v) { switch (v.getId()){ 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.button10: builder.setLength(0); break; case R.id.button11: builder.append("0"); break; } if(builder.length()==0){ binding.textView9.setText(getString(R.string.input)); } else{ binding.textView9.setText(getString(R.string.input)+builder.toString()); } } }; 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.button10.setOnClickListener(listener); binding.button11.setOnClickListener(listener); binding.button12.setOnClickListener(new View.OnClickListener() { @SuppressWarnings("ConstantConditions") @Override public void onClick(View v) { if(Integer.valueOf(builder.toString()).intValue()==myViewModel.getAnswer().getValue()){ myViewModel.answerCurrent(); 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); } myViewModel.getLoseScore().setValue(myViewModel.getCurrentScore().getValue()); myViewModel.getCurrentScore().setValue(0); } } }); return binding.getRoot(); // Inflate the layout for this fragment // return inflater.inflate(R.layout.fragment_question, container, false); } }
winFragment:
package com.example.canceltext; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import androidx.databinding.DataBindingUtil; import androidx.fragment.app.Fragment; import androidx.lifecycle.SavedStateViewModelFactory; import androidx.lifecycle.ViewModelProviders; import androidx.navigation.NavController; import androidx.navigation.Navigation; import com.example.canceltext.databinding.FragmentWinBinding; /** * A simple {@link Fragment} subclass. */ public class winFragment extends Fragment { public winFragment() { // Required empty public constructor } @Override public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) { MyViewModel myViewModel; myViewModel = ViewModelProviders.of(requireActivity(), new SavedStateViewModelFactory(requireActivity().getApplication(), requireActivity())).get(MyViewModel.class); FragmentWinBinding binding; binding = DataBindingUtil.inflate(inflater, R.layout.fragment_win,container,false); binding.setLifecycleOwner(requireActivity()); binding.setData(myViewModel); binding.button13.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { NavController controller = Navigation.findNavController(v); controller.navigate(R.id.action_winFragment_to_tatelFragment); } }); //nflate the layout for this fragment // return binding.getRoot(); // } //} I