user3287264
user3287264

Reputation:

Android listview: Different colours in Items and SubItems?

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

Answers (2)

rogcg
rogcg

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.

list_row.xml

<?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.

MyArrayAdapter.java

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:

Your onCreate() method

@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. enter image description here


Let me know if you have more doubts.

Hope this helps you!

Upvotes: 0

Mouad EL Fakir
Mouad EL Fakir

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:

row.xml

<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:

MyAdapter.java

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:

TestResults.java

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 :) enter image description here

Upvotes: 1

Related Questions