我对编程和Android开发都很陌生,所以请原谅我,如果我的基础知识还不是很精通的话。我在底部提供了我的代码。
如标题中所述,如何在我的自定义arrayadapter创建的视图中引用每个视图?这样我就可以访问arrayadapter中每个视图对象的变量。
实际上,我有两个问题需要实现。所以现在我正在尝试创建一个由科学测试组成的简单应用程序。我已设法将所有与CheckBox视图配对的问题(TextViews)显示到ListView布局中。我的想法是,当用户检查CheckBox时,它会存储一个真正的'某处的布尔值(可能在ArrayList中)。之后在分数汇总活动中,我将用户的答案与原始布尔值(问题的正确答案)进行比较,以检查是否为每个问题给出了正确的答案并返回分数。这样做是否明智?
TestActivity.java
package com.example.android.scienceknowledgetest;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.ListView;
import java.util.ArrayList;
public class TestActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
// ArrayList of all the questions and their boolean (answer) values
ArrayList<Question> questions = new ArrayList<Question>();
questions.add(new Question("Plants derive most of their dry mass from the air", true, ""));
questions.add(new Question("Aluminium is the most common metal in the Earth's crust", true, ""));
questions.add(new Question("Vitamin C has be shown to prevent colds", false, ""));
questions.add(new Question("We lose most of our heat through our heads", false, ""));
questions.add(new Question("Dogs are unable to digest chocolate", false, ""));
questions.add(new Question("Apple pips contain cyanide", true, ""));
questions.add(new Question("Cholesterol is a naturally-occurring toxic substance", false, ""));
questions.add(new Question("When you're on a diet, you lose weight by oxidising fat to a gas and exhaling it", true, ""));
questions.add(new Question("Human beings are unable to sense when the oxygen level of the air is low", true, ""));
questions.add(new Question("Most of the Y chromosome is passed unchanged from father to son", true, ""));
// Constructing a new TestAdapter instance
TestAdapter adapter = new TestAdapter(this, questions);
// Find the ListView to display the questions and check boxes
ListView questions_checkbox_list = (ListView) findViewById(R.id.question_checkbox_list);
// Display the questions and check boxes to the ListView questions_checkbox_list
questions_checkbox_list.setAdapter(adapter);
// Configuring the Button Submit
Button submitAnswers = (Button) findViewById(R.id.submit_answers);
submitAnswers.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent endTest = new Intent(TestActivity.this, TestSummary.class);
startActivity(endTest);
}
});
}
}
TestAdapter
package com.example.android.scienceknowledgetest;
import android.app.Activity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.TextView;
import java.util.ArrayList;
public class TestAdapter extends ArrayAdapter<Question> {
// TestAdapter constructor
public TestAdapter(Activity context, ArrayList<Question> questions) {
super(context, 0, questions);
}
private View listItemsView;
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Check if the current view is recycled, otherwise inflate new view
listItemsView = convertView;
if (listItemsView == null) {
listItemsView = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
}
// Find the current Question object and store in the variable currentQuestion
Question currentQuestion = getItem(position);
// Find the TextView texts of the Question and set the question
TextView questionText = (TextView) listItemsView.findViewById(R.id.question_text);
questionText.setText(currentQuestion.getmQuestion());
// Find the CheckBox of the Question and set the boolean value
CheckBox answerBool = (CheckBox) listItemsView.findViewById(R.id.answer_boolean);
// Return the item as a view
return listItemsView;
}
}
Question.java
package com.example.android.scienceknowledgetest;
public class Question {
// Declaring the question variable
private String mQuestion;
// Declaring the answer variable
private boolean mAnswer;
// Declaring the attempt variable
private String mAttempt;
// Getter method to request for the question
public String getmQuestion() {
return mQuestion;
}
// Getter method to request for the boolean value of the answer
public boolean getmAnswer() {
return mAnswer;
}
// Question Constructor
public Question(String question, boolean answer, String attempt) {
mQuestion = question;
mAnswer = answer;
mAttempt = attempt;
}
}
activity_test.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical">
<ListView
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp"
android:id="@+id/question_checkbox_list" />
<Button
android:layout_weight="0"
android:id="@+id/submit_answers"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/submit_answers"
android:textSize="16sp"
android:layout_margin="16dp"
android:layout_marginLeft="48dp"/>
</LinearLayout>
list_item.xml
<?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:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<CheckBox
android:id="@+id/answer_boolean"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/question_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="8dp"
tools:text="When you're on a diet, you lose weight by oxidising fat to a gas and exhaling it"/>
</LinearLayout>
答案 0 :(得分:0)
这里有你想要的东西。它都在适配器中。这是TestAdpater的代码: -
public class TestAdapter extends ArrayAdapter<Question> {
Context passedcontext;
// TestAdapter constructor
public TestAdapter(Activity context, ArrayList<Question> questions) {
super(context, 0, questions);
passedcontext = context;
}
private View listItemsView;
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// Check if the current view is recycled, otherwise inflate new view
listItemsView = convertView;
if (listItemsView == null) {
listItemsView = LayoutInflater.from(getContext()).inflate(R.layout.list_item, parent, false);
}
// Find the current Question object and store in the variable currentQuestion
Question currentQuestion = getItem(position);
// Find the TextView texts of the Question and set the question
TextView questionText = (TextView) listItemsView.findViewById(R.id.question_text);
questionText.setText(currentQuestion.getmQuestion());
// Find the CheckBox of the Question and set the boolean value
CheckBox answerBool = (CheckBox) listItemsView.findViewById(R.id.answer_boolean);
answerBool.setTag(position);
answerBool.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
detectCheckBoxChanged(buttonView, isChecked);
}
});
// Return the item as a view
return listItemsView;
}
public void detectCheckBoxChanged(CompoundButton buttonview, boolean ischecked) {
Toast.makeText(passedcontext,
"CheckBox " +
buttonview.getTag().toString() +
" Changed to " + Boolean.toString(ischecked),
Toast.LENGTH_SHORT).show();
}
}
第一个变化是增加了一行: -
Context passedcontext;
这将保存调用活动的上下文(下一个新的代码行)。
第二个更改是添加了一行来设置带有调用活动的上下文的passcontext,这在TestAdapter的构造函数中完成: -
passedcontext = context;
下一个更改是使用位置设置CheckBoxes的标记,以便您可以确定哪个CheckBox已触发监听器。在您getView
方法中确定了CheckBox的ID后,会立即(或不久之后)出现这种情况,该方法可以方便地传递位置。: -
answerBool.setTag(position);
为了按顺序执行操作并且可能简化代码,将一个新的类方法添加到类中以处理CheckBox Changed事件(在这种情况下发出一个Toast,详细说明单击了哪个CheckBox及其状态)。注意它是使用这个Toast为什么我们得到了调用活动的上下文,因为Toast需要一个上下文来显示: -
public void detectCheckBoxChanged(CompoundButton buttonview, boolean ischecked) {
Toast.makeText(passedcontext,
"CheckBox " +
buttonview.getTag().toString() +
" Changed to " + Boolean.toString(ischecked),
Toast.LENGTH_SHORT).show();
}
最后一段代码设置并包含要更改的CheckBox的侦听器。您可以将上面的代码合并到侦听器中,而不是调用新的detectCheckBoxChanged
方法。此代码添加在getView
方法中,并且在确定了CheckBox的ID之后需要(至少是设置): -
answerBool.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
detectCheckBoxChanged(buttonView, isChecked);
}
});
您可以更改 detectCheckBoxChanged
方法,以包含以下内容: -
int position = Integer.parseInt(buttonview.getTag().toString());
TestActivity.handleCheckBoxChanged(position, isChecked);
在这种情况下,将调用TestActivity活动(调用活动)中的handleCheckBoxChanged方法,例如,
public static void handleCheckBoxChanged(int position, boolean ischecked) {
// handle the change here using the position
Log.d("CHKBOXHIT",
"Checkbox " +
Integer.toString(position) +
" was hit it is now "
+ Boolean.toString(ischecked)
);
}
以下更改可能是绕过&#34;未回答&#34;问题我评论过。
1)将一个int数组作为类变量添加到TestActivity中(即在公共类TestAdapter扩展ArrayAdapter {&#39;之后),例如。
static int[] answers;
2)设置answers数组并将元素初始化为无法回答的值,此代码遵循问题ArrayList的设置。 e.g。
answers = new int[questions.size()];
for (int i = 0; i < answers.length; i++ ) {
answers[i] = -1;
}
3)添加一个新方法,当单击一个传递索引和状态的答案时将调用该方法。
public static void setAnswer(int index, boolean answer) {
answers[index] = 0;
if (answer) {
answers[index] = 1;
}
}
4)将以下行添加到TestAdapter类中的detectCheckBoxChanged方法: -
TestActivity.setAnswer(position, ischecked);
5)要测试它,请将TestActivity中的submitAnswers onClick侦听器更改为: -
submitAnswers.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
//Intent endTest = new Intent(ScienceKnowledgeTest.this, ScienceKnowledgeTest.class);
//startActivity(endTest);
for (int i =0; i < answers.length; i++) {
switch (answers[i]) {
case -1:
Log.d("RESULTS", "Question "
+ Integer.toString(i + 1) +
" was not answered."
);
break;
case 0:
Log.d("RESULTS", "Question " +
Integer.toString(i + 1) +
" was answered as False"
);
break;
case 1:
Log.d("RESULTS", "Question " +
Integer.toString(i + 1) +
" was answered as True"
);
break;
default:
Log.d("RESULTS", "Well that's unusual something appears to be wrong!!!");
break;
}
}
}
});
但是,这有一个问题,即选择一个错误的答案需要2次点击才能将复选框设置为true,然后再设置为false。两个复选框一个用于true,一个用于false将更清晰。