Reputation:
Is it possible to an item in a list view as one colour and its sub items as a different colour?
I am creating a game (times tables quiz game) in which the question and the answers the user gives as well as the correct answer are transfered through to a list view. e.g.:
Item- "7 x 5= (user answer)" subitem- "(correct answer)"
I want the question i.e. "7x5" to be in black, the user answer to be green if correct and red if not correct. And also the correct answer to always be green
Activity in which I wish to change the colours:
public class TestResults extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.testresults);
ListView itemList = (ListView) findViewById(R.id.lvRandomTestresults);
//gets all necessary data from the previous activity
int[] results = getIntent().getIntArrayExtra("results");
String[] questions= getIntent().getStringArrayExtra("Questions");
int[] correctAnswer= getIntent().getIntArrayExtra("CorrectAnswer");
ArrayList < HashMap <String, String> > list = new ArrayList < HashMap <String, String> > ();
// loop to give list view
for (int i = 1; i <= 10; ++i) {
int userAnswer = results[i - 1];
int expectedAnswer = correctAnswer[i-1];
String userString = questions[i-1] + userAnswer;
String expectedString = " " + expectedAnswer;
HashMap<String, String> map = new HashMap<String, String>();
map.put("user", userString);
map.put("expected", expectedString);
list.add(map);
}
String[] keys = {"user", "expected"};
int[] ids = {android.R.id.text1, android.R.id.text2};
SimpleAdapter adapter = new SimpleAdapter(this, list, android.R.layout.simple_list_item_2, keys, ids);
itemList.setAdapter(adapter);
}//onCreate end
}//class end
XML corresponding to this activity:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="@+id/lvRandomTestresults"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
Upvotes: 1
Views: 1049
Reputation: 10471
Create a new layout file called list_row.xml
to be the layout of the row of your list. Each row will have this layout, each one with two TextViews.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:id="@+id/list_row.xml"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:id="@+id/questionLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/question"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:paddingLeft="10dp"
android:paddingTop="2dp"
android:paddingBottom="2dp"/>
<TextView
android:id="@+id/answer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#000000"
android:paddingLeft="10dp"
android:paddingTop="2dp"
android:paddingBottom="2dp"/>
</LinearLayout>
<TextView
android:id="@+id/correct"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#00FF00"
android:paddingLeft="10dp"
android:paddingTop="2dp"
android:paddingBottom="2dp"/>
</LinearLayout>
And create a custom ArrayAdapter to manage your view's colors. Create this class as inner class or you can create in a separated file if you want.
public class MyArrayAdapter extends ArrayAdapter<ArrayList<HashMap<String, String>>>
{
Context mContext;
ArrayList<HashMap<String, String>> mQuestionArrayList;
int mLayoutResourceId;
String[] mQuestionsArray;
int[] mUsersAnswers;
public MyArrayAdapter(Context context, int layoutResourceId, ArrayList<HashMap<String, String>> questionsArrayList, String[] questionsArray, int[] usersAnswers)
{
super(context, layoutResourceId);
mContext = context;
this.mQuestionArrayList = questionsArrayList;
this.mLayoutResourceId = layoutResourceId;
this.mQuestionsArray = questionsArray;
this.mUsersAnswers = usersAnswers;
}
@Override
public int getCount()
{
return mQuestionArrayList.size();
}
@Override
public View getView(int position, View row, ViewGroup parent)
{
HashMap<String, String> question = mQuestionArrayList.get(position);
LayoutInflater inflater = LayoutInflater.from(mContext);
// Here you will initialize the row layout, by inflating the xml file list_row.
row = inflater.inflate(this.mLayoutResourceId, parent, false);
// Here we initialize those two TextViews defined in the list_row layout.
TextView questionTxtView = (TextView) row.findViewById(R.id.question);
TextView answerTxtView = (TextView) row.findViewById(R.id.answer);
TextView correctAnswerTxtView = (TextView) row.findViewById(R.id.correct);
questionTxtView.setText(mQuestionsArray[position]);
answerTxtView.setText(String.valueOf(mUsersAnswers[position]));
correctAnswerTxtView.setText(question.get("expected").toString());
// This is just a pseudo code to show you when and how to set the colors of
// the TextView programatically.
if(mUsersAnswers[position] != Integer.parseInt(question.get("expected").toString()))
answerTxtView.setTextColor(Color.RED);
else
answerTxtView.setTextColor(Color.GREEN);
return row;
}
}
And in your Activity's onCreate()
method, you should have a ListView
object and set the your custom array adapter (defined above as example) to your ListView
this way:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView itemList = (ListView) findViewById(R.id.lvRandomTestresults);
//gets all necessary data from the previous activity
int[] results = getIntent().getIntArrayExtra("results");
String[] questions= getIntent().getStringArrayExtra("Questions");
int[] correctAnswer= getIntent().getIntArrayExtra("CorrectAnswer");
ArrayList< HashMap <String, String> > list = new ArrayList < HashMap <String, String> > ();
// loop to give list view
for (int i = 0; i < 10; i++) {
int userAnswer = results[i];
int expectedAnswer = correctAnswer[i];
String userString = questions[i] + " " + userAnswer;
String expectedString = "" + expectedAnswer;
HashMap<String, String> map = new HashMap<String, String>();
map.put("user", userString);
map.put("expected", expectedString);
list.add(map);
}
// Instantiate your custom array adapter
MyArrayAdapter adapter = new MyArrayAdapter(this.getApplicationContext(), R.layout.list_row, list, questions, results);
// Here you set the custom adapter to your ListView.
itemList.setAdapter(adapter);
}
I tested the code with fictional values, and the result below was retrieved from the code written in this answer.
Let me know if you have more doubts.
Hope this helps you!
Upvotes: 0
Reputation: 3749
In the code you give, you used a default adapter it's really not costumisable at all, you have to create you own adpater, so let's do it:
First of all you have to add an xml file to your layout folder represent one row in the listView:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/questionTV"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/answerTV"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
then you have to create you costum Adapter, so create new class and name it MyAdapter , put this code in it:
public class MyAdapter extends ArrayAdapter<String> {
private final Activity context;
private final String[] questions;
private final int[] answers;
private final int[] rightAnswers;
static class ViewHolder {
public TextView text1;
public TextView text2;
}
public MyAdapter(Activity context, String[] questions, int[] answers, int[] rightAnswers){
super(context, R.layout.row, questions);
this.context = context;
this.questions= questions;
this.answers= answers;
this.rightAnswers= rightAnswers;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
if (rowView == null) {
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.row, null);
// configure view holder
ViewHolder viewHolder = new ViewHolder();
viewHolder.text1 = (TextView) rowView.findViewById(R.id.questionTV);
viewHolder.text2 = (TextView) rowView.findViewById(R.id.answerTV);
rowView.setTag(viewHolder);
}
// fill data
ViewHolder holder = (ViewHolder) rowView.getTag();
String question = questions[position];
int answer = answers[position];
int rightAnswer = rightAnswers[position];
//set Question in the text View with a BLACK backgroud color
holder.text1.setText(question);
//holder.text1.setBackgroundColor(Color.BLACK);
//set User Answer with GREEN backgroun if it's correct or RED if it s not
holder.text2.setText(String.valueOf(answer));
if(answer == rightAnswer){
holder.text2.setBackgroundColor(Color.GREEN);
}else {
holder.text2.setBackgroundColor(Color.RED);
}
return rowView;
}
}
finally you need to customise your activity with that:
public class TestResults extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.testresults);
ListView itemList = (ListView) findViewById(R.id.lvRandomTestresults);
//gets all necessary data from the previous activity
int[] results = getIntent().getIntArrayExtra("results");
String[] questions= getIntent().getStringArrayExtra("Questions");
int[] correctAnswer= getIntent().getIntArrayExtra("CorrectAnswer");
itemList.setAdapter(new MyAdapter(this, questions, results, correctAnswer));
}//onCreate end
}//class end
And this is a simple test if it's needed :)
Upvotes: 1