文章目录
- 一、案例演示
- 二、页面布局
- 1、activity_question.xml
- 2、fragment_radio_button.xml
- 3、fragment_chex_box.xml
- 三、功能实现
- 构思
- 1、Question.java
- 2、RadioButtonFragment.java
- 3、ChexBoxFragment.java
- 4、QuestionActivity.java
- 四、部分样式
- 1、select_button_text.xml
- 2、shape_radiobutton.xml
- 3、shape_radiobutton2.xml
- 4、shape_success_answer.xml
- 5、shape_error_answer.xml
fragment的切换,实体类的整体分析,单选多选的实现,
一、案例演示
- 单选题,多选题随机分布,单选题当点击选项提交错误时,选择的错误选项变红,正确选项变蓝。多选题当点击选项提交错误时所有选择的选项变红,正确时正确答案变蓝,
- 倒计时仅仅用来提示时间,并无其他功能,没有完善
- 当答题结束时显示最终答题分数
二、页面布局
1、activity_question.xml
1、不需要动的布局
2、代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/hui"
tools:context=".QuestionActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white">
<ImageView
android:layout_width="50dp"
android:layout_height="50dp"
android:background="@drawable/left"></ImageView>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="每日答题"
android:textColor="@color/black"
android:textSize="25dp"
android:layout_gravity="center"
android:layout_marginLeft="110dp"></TextView>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="10dp"
android:text="剩余时间:1:47"
android:textColor="@color/black"
android:textSize="25dp"></TextView>
<Button
android:id="@+id/submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="10dp"
android:background="@color/red2"
android:text="提交"></Button>
</RelativeLayout>
</LinearLayout>
<FrameLayout
android:id="@+id/fragment1"
android:layout_width="match_parent"
android:layout_height="match_parent"
></FrameLayout>
</LinearLayout>
2、fragment_radio_button.xml
1、单选按钮fragment布局
2、代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".RadioButtonFragment">
<LinearLayout
android:layout_margin="10dp"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30dp"
android:textColor="@color/black"
android:text="单选题"></TextView>
<TextView
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/black"></TextView>
<LinearLayout
android:layout_marginTop="5dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:id="@+id/question_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25dp"
android:text="题干"></TextView>
<TextView
android:id="@+id/textview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25dp"></TextView>
</LinearLayout>
<RadioGroup
android:id="@+id/radiogroup"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<RadioButton
android:id="@+id/radio1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/select_button_text"
android:textSize="20dp"
android:gravity="center"
android:button="@null"
android:text="选项1"></RadioButton>
<RadioButton
android:id="@+id/radio2"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/select_button_text"
android:gravity="center"
android:textSize="20dp"
android:button="@null"
android:text="选项2"></RadioButton>
<RadioButton
android:id="@+id/radio3"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/select_button_text"
android:gravity="center"
android:textSize="20dp"
android:button="@null"
android:text="选项3"></RadioButton>
<RadioButton
android:id="@+id/radio4"
android:layout_marginTop="10dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/select_button_text"
android:button="@null"
android:gravity="center"
android:textSize="20dp"
android:text="选项4"></RadioButton>
</RadioGroup>
</LinearLayout>
</LinearLayout>
3、fragment_chex_box.xml
1、多选按钮fragment布局
2、代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ChexBoxFragment">
<LinearLayout
android:layout_margin="10dp"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="30dp"
android:textColor="@color/black"
android:text="多选题"></TextView>
<TextView
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@color/black"></TextView>
<LinearLayout
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@color/white">
<TextView
android:id="@+id/question_item2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25dp"
android:text="题干"></TextView>
<TextView
android:id="@+id/b1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10dp"></TextView>
<TextView
android:id="@+id/b2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10dp"></TextView>
<TextView
android:id="@+id/b3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10dp"></TextView>
<TextView
android:id="@+id/b4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25dp"></TextView>
<TextView
android:id="@+id/b5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="10dp"></TextView>
</LinearLayout>
<CheckBox
android:id="@+id/boxs1"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:button="@null"
android:background="@drawable/select_button_text"
android:textSize="20dp"
android:text="选项1"></CheckBox>
<CheckBox
android:id="@+id/boxs2"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:button="@null"
android:background="@drawable/select_button_text"
android:textSize="20dp"
android:text="选项2"></CheckBox>
<CheckBox
android:id="@+id/boxs3"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:button="@null"
android:background="@drawable/select_button_text"
android:textSize="20dp"
android:text="选项3"></CheckBox>
<CheckBox
android:id="@+id/boxs4"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:button="@null"
android:background="@drawable/select_button_text"
android:textSize="20dp"
android:text="选项4"></CheckBox>
<CheckBox
android:id="@+id/boxs5"
android:layout_marginTop="5dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:button="@null"
android:background="@drawable/select_button_text"
android:textSize="20dp"
android:text="选项5"></CheckBox>
</LinearLayout>
</LinearLayout>
三、功能实现
构思
Fragment:
1.自己判断答案对不对: getResult()
2.更换题目内容: nextQuestion()
3.获取题目: setQuestion (Question q)
1、Question.java
实体类
public class Question {
private String questionStem;//题干
private String[] options;//选项
private String correctOptions;//正确选项的下标从0开始
private int questionTypes;//1 为单选题, 2为多选题
public Question(String questionStem, String[] options, String correctOptions, int questionTypes) {
this.questionStem = questionStem;
this.options = options;
this.correctOptions = correctOptions;
this.questionTypes = questionTypes;
}
public Question() {
}
public String getQuestionStem() {
return questionStem;
}
public void setQuestionStem(String questionStem) {
this.questionStem = questionStem;
}
public String[] getOptions() {
return options;
}
public void setOptions(String[] options) {
this.options = options;
}
public String getCorrectOptions() {
return correctOptions;
}
public void setCorrectOptions(String correctOptions) {
this.correctOptions = correctOptions;
}
public int getQuestionTypes() {
return questionTypes;
}
public void setQuestionTypes(int questionTypes) {
this.questionTypes = questionTypes;
}
}
2、RadioButtonFragment.java
public class RadioButtonFragment extends Fragment {
//成员变量
private TextView question_stem;//题干文本框控件,就是选中的控件显示
private RadioGroup radioGroup;
private RadioButton [] rb =new RadioButton[4];
private Question question;//题目对象就是标题,单选多选,正确下标
private int result;//正确为1 错误为0 未答题为-1
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.e("单选onCreateView","单选onCreateView执行了");
View view=inflater.inflate(R.layout.fragment_radio_button, container, false);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.e("单选onViewCreated","单选onViewCreated执行了");
//初始化控件
initView(view);
//更新题目
nextQuestion(question);
}
//获取题目
public void setQuestion(Question question){
this.question=question;
}
//初始化控件
public void initView(final View view){
Log.e("单选initView","单选initView执行了");
//获取题干
question_stem=view.findViewById(R.id.question_item);
radioGroup=view.findViewById(R.id.radiogroup);
//单选控件
rb[0]=view.findViewById(R.id.radio1);
rb[1]=view.findViewById(R.id.radio2);
rb[2]=view.findViewById(R.id.radio3);
rb[3]=view.findViewById(R.id.radio4);
}
//清空原来选项
public void clear(){
radioGroup.clearCheck();
}
//更新题目
public void nextQuestion(Question question){
Log.e("单选nextQuestion","单选nextQuestion执行了");
clear();
//设置题干
question_stem.setText(question.getQuestionStem());
//设置选项
for (int i=0;i<rb.length;i++){
//所有选项初始都未选中
rb[i].setChecked(false);
//设置选项内容
rb[i].setText(question.getOptions()[i]);
//设置背景颜色
rb[i].setBackgroundResource(R.drawable.select_button_text);
//设置字体颜色
rb[i].setTextColor(getResources().getColor(R.color.black));
}
}
//判断选择结果
public int getResult(Question question){
//正确的id下标
int correctIndex=Integer.parseInt(question.getCorrectOptions());
int correctId=rb[correctIndex].getId();
//当前选中的id
int radioId=radioGroup.getCheckedRadioButtonId();
if(radioId==-1){
Toast.makeText(getContext(), "请选择你的选项", Toast.LENGTH_SHORT).show();
result=-1;
}else {
for(int i=0;i< rb.length;i++){
rb[i].setBackgroundResource(R.drawable.shape_radiobutton2);
}
if (radioId==correctId){
Toast.makeText(getContext(), "回答正确", Toast.LENGTH_SHORT).show();
result=1;
}else {
//答案错误背景和字体变对应的颜色
RadioButton radioButton=getView().findViewById(radioId);
radioButton.setBackgroundResource(R.drawable.shape_error_answer);
radioButton.setTextColor(getResources().getColor(R.color.error));
result=0;
}
//无论正确还是错误,正确的答案都显示出来
rb[correctIndex].setBackgroundResource(R.drawable.shape_success_answer);
rb[correctIndex].setTextColor(getResources().getColor(R.color.success));
}
return result;
}
}
3、ChexBoxFragment.java
public class ChexBoxFragment extends Fragment {
//成员变量
private TextView question_stem;//题干文本框控件,就是选中的控件显示
private CheckBox[] cb =new CheckBox[5];
private Question question;//题目对象就是标题,单选多选,正确下标
private int result;//正确为1 错误为0 未答题为-1
private View view;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
Log.e("复选onCreateView","复选onCreateView执行了");
view=inflater.inflate(R.layout.fragment_chex_box, container, false);
return view;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Log.e("复选onViewCreated","复选onViewCreated执行了");
//初始化控件
initView(view);
//更新题目
nextQuestion(question);
}
//获取题目
public void setQuestion(Question question){
this.question=question;
}
public void clearChoice(){
//清除选择
for (int i = 0; i < cb.length; i++) {
cb[i].setChecked(false);
}
}
//初始化控件
public void initView(final View view){
Log.e("复选initView","复选initView执行了");
//获取题干
question_stem=view.findViewById(R.id.question_item2);
//单选控件
cb[0]=view.findViewById(R.id.boxs1);
cb[1]=view.findViewById(R.id.boxs2);
cb[2]=view.findViewById(R.id.boxs3);
cb[3]=view.findViewById(R.id.boxs4);
cb[4]=view.findViewById(R.id.boxs5);
}
//更新题目
public void nextQuestion(Question question){
Log.e("复选nextQuestion","nextQuestion执行了");
//设置题干
Log.e("a",question.getQuestionStem());
question_stem.setText(question.getQuestionStem());
//设置选项
for (int i=0;i<cb.length;i++){
//所有选项初始都未选中
cb[i].setChecked(false);
//设置选项内容
cb[i].setText(question.getOptions()[i]);
//设置背景颜色
cb[i].setBackgroundResource(R.drawable.select_button_text);
//设置字体颜色
cb[i].setTextColor(getResources().getColor(R.color.black));
}
}
//判断选择结果
public int getResult(Question question){
//得到正确的选项的下标数组
String[] correctOptions = question.getCorrectOptions().split(",");
boolean answer = true; //记录正确答案是否选择
int checkednum = 0; //选择的选项个数
for(int i = 0; i < cb.length; i++){
if(cb[i].isChecked()){
checkednum++; //选项个数增加
}
}
if(checkednum == 0){
Toast.makeText(getContext(),"请选择答案!",Toast.LENGTH_SHORT).show();
result = -1;
}else{
for(int i=0;i< cb.length;i++){
cb[i].setBackgroundResource(R.drawable.shape_radiobutton2);
}
if(checkednum==correctOptions.length){
for (String correctOption : correctOptions) {
//判断对应的选项是否被选择
boolean now = cb[Integer.parseInt(correctOption)].isChecked();
answer = answer && now;
}
}else {
answer=false;
}
if(answer){
for (String correctOption : correctOptions) {
//判断对应的选项是否被选择
CheckBox c = cb[Integer.parseInt(correctOption)];
c.setBackgroundResource(R.drawable.shape_success_answer);
c.setTextColor(getResources().getColor(R.color.success));
}
result = 1;
}else{
for (CheckBox checkBox : cb) {
if (checkBox.isChecked()) {
checkBox.setBackgroundResource(R.drawable.shape_error_answer);
checkBox.setTextColor(getResources().getColor(R.color.error));
}
}
showCorrectAnswer(correctOptions);
result = 0;
}
}
return result;
}
//显示正确答案的dialog
private void showCorrectAnswer(String[] correctOptions) {
//得到正确答案
String answer = "";
for (String correctOption : correctOptions) {
answer += cb[Integer.parseInt(correctOption)].getText().toString() + "\n";
}
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setTitle("正确答案")
.setMessage(answer)
.setNegativeButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
builder.create().show();
}
}
4、QuestionActivity.java
public class QuestionActivity extends AppCompatActivity {
private int score=0;//答题分数
private final List<Question>questions=new ArrayList<>();//题目集合
private int i=0;//当前题号
private int previousType;//上一题题目类型,单选为1,多选为2
private int result;//答题结果,正确为1,错误为0,未答题为2
private Button button;//提交按钮
private RadioButtonFragment radioButtonFragment;//单选按钮对象
private ChexBoxFragment chexBoxFragment;
private TextView time;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_question);
//初始化题目
initQuestions();
//初始化控件
initView();
//根据题形加载第一题
Question question=questions.get(0);
Log.e("question", "可以获取题目");
if (question.getQuestionTypes()==1){
//给出题目的类型
radioButtonFragment.setQuestion(question);
replaceFragment(radioButtonFragment);
previousType=1;//当前题型为1,为单选题
}else {
chexBoxFragment.setQuestion(question);
replaceFragment(chexBoxFragment);
previousType=2;//当前题型为2,为多选题
}
}
CountDownTimer countDownTimer=new CountDownTimer(120000, 1000) {
public void onTick(long millisUntilFinished) {
time.setText("剩余时间 " + millisUntilFinished / 1000+"s");
}
public void onFinish() {
time.setText("时间到!");
}
}.start();
//替换fragment方法
private void replaceFragment(Fragment Fragment) {
FragmentManager manager=getSupportFragmentManager();
FragmentTransaction transaction=manager.beginTransaction();
transaction.replace(R.id.fragment1,Fragment);
transaction.commit();
}
public void initQuestions(){
Log.e("信息更新", "执行了");
Question question=new Question();
//题干
question.setQuestionStem("1、哪个季节天气最热?");
//选项
question.setOptions(new String[]{"春","夏","秋","冬"});
//正确的答案
question.setCorrectOptions("1");
//题目类型
question.setQuestionTypes(1);
//把题目添加到集合中
questions.add(question);
Question question2=new Question();
//题干
question2.setQuestionStem("2、坤坤喜欢的运动是什么?");
//选项
question2.setOptions(new String[]{"唱","跳","rap","篮球","music"});
//正确的答案
question2.setCorrectOptions("1,2");
//题目类型
question2.setQuestionTypes(2);
//把题目添加到集合中
questions.add(question2);
Question question3=new Question();
//题干
question3.setQuestionStem("3、属于前端的是?");
//选项
question3.setOptions(new String[]{"html","css","java","orcale","mysql"});
//正确的答案
question3.setCorrectOptions("0,1");
//题目类型
question3.setQuestionTypes(2);
//把题目添加到集合中
questions.add(question3);
Question question4=new Question();
//题干
question4.setQuestionStem("4、属于后端的是?");
//选项
question4.setOptions(new String[]{"java","c","ppt","world","excel"});
//正确的答案
question4.setCorrectOptions("0,1");
//题目类型
question4.setQuestionTypes(2);
//把题目添加到集合中
questions.add(question4);
Question question5=new Question();
//题干
question5.setQuestionStem("5、我使用的手机品牌是?");
//选项
question5.setOptions(new String[]{"苹果","化为","OPPO","VIVO"});
//正确的答案
question5.setCorrectOptions("3");
//题目类型
question5.setQuestionTypes(1);
//把题目添加到集合中
questions.add(question5);
}
public void initView(){
//找到对应控件
button=findViewById(R.id.submit);
radioButtonFragment=new RadioButtonFragment();
chexBoxFragment=new ChexBoxFragment();
time=findViewById(R.id.time);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//如果是提交按钮,根据当前题目类型,调用getResult()
if(button.getText().equals("提交")){
if(questions.get(i).getQuestionTypes()==1){
result=radioButtonFragment.getResult(questions.get(i));
}else {
result=chexBoxFragment.getResult(questions.get(i));
}
//如果答对了就+1分
if(result==1){
score++;
}
//如果不是第五题,就改文本为下一题,如果是第五题,就修改文本为结束
if(i==4){
button.setText("结束");
}else if(result!=-1){
button.setText("下一题");
}
}else {
//如果是下一题按钮,题号增加,判断你是否已经答题完成
i++;
if(i<questions.size()){
//根据上一题类型,选择是否替换fragment
if(questions.get(i).getQuestionTypes()==1){
if (previousType!=1){
chexBoxFragment.clearChoice();
radioButtonFragment.setQuestion(questions.get(i));
replaceFragment(radioButtonFragment);
previousType=1;
}else {
radioButtonFragment.nextQuestion(questions.get(i));
}
}else {
if(previousType!=2){
radioButtonFragment.clear();
chexBoxFragment.setQuestion(questions.get(i));
replaceFragment(chexBoxFragment);
previousType=2;
}else {
chexBoxFragment.nextQuestion(questions.get(i));
}
}
button.setText("提交");
}else {
showDialog();
button.setVisibility(View.INVISIBLE);
}
}
}
});
}
//显示答题结束的页面
private void showDialog(){
AlertDialog.Builder builder=new AlertDialog.Builder(QuestionActivity.this);
builder.setTitle("提示");
builder.setMessage("答题结束得分"+score);
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent=new Intent(QuestionActivity.this,QuestionActivity.class);
startActivity(intent);
}
});
builder.create().show();
}
}
四、部分样式
1、select_button_text.xml
按压样式
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 按钮选中状态-->
<item android:state_checked="true" android:drawable="@drawable/shape_radiobutton"></item>
<!-- 按钮未选中状态-->
<item android:state_checked="false" android:drawable="@drawable/shape_radiobutton2"></item>
</selector>
2、shape_radiobutton.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 大小-->
<size android:height="50dp" android:width="50dp"></size>
<!-- 颜色-->
<solid android:color="@color/teal_200"></solid>
<!-- 描边-->
<stroke android:color="@color/black" android:width="1dp"
android:dashWidth="3dp" android:dashGap="1dp"></stroke>
<!-- 角半径-->
<corners android:radius="5dp"></corners>
</shape>
3、shape_radiobutton2.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size android:width="50dp" android:height="50dp"></size>
<solid android:color="@color/white"></solid>
<stroke android:color="@color/black" android:width="1dp"></stroke>
<corners android:radius="5dp"></corners>
</shape>
4、shape_success_answer.xml
回答正确选项颜色
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size android:width="50dp" android:height="50dp"></size>
<solid android:color="#D00CA5EA"></solid>
<corners android:radius="5dp"></corners>
</shape>
5、shape_error_answer.xml
回答错误选项颜色
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<size android:width="50dp" android:height="50dp"></size>
<solid android:color="#A3F44336"></solid>
<corners android:radius="5dp"></corners>
</shape>