Friday, May 20, 2011

Dumping the Answer display


One of the main structural issues with my quiz app is that answers are shown on a separate display than the questions. This has the effect of swinging the customer back and forth between the two displays. Since I first coded the app, I've realized that it would be a more pleasant experience to just keep the customer on the same display, and simple highlight the good answer in green, and the wrong answer in red, if they chose incorrectly.

The thing about Japanese is that you have the kanji, which is a symbol, then you have the phonetic spelling, which is best displayed in the Japanese alphabet. But then there is also the English translation, which is a little curveball on a standard quiz. Since the phonetic spelling is already displayed, on a standard quiz it is simply a question of highlighting the correct answer. But also displaying the english translation on the same display is more problematic. Plus, I'll need to add the "next question" button.

It seems like it might get crowded. And if I put ads in, it will be that much more crowded. But, it might be worth it, simply to keep from bouncing the customer from back and forth from the question to the answer display and back all the time.

One thing I can certainly do is make the fonts smaller. I went a little big on them.

Ok, I've made some progress. I now have a button that keeps me on the same page, it just gets the next question and possible quiz answers and displays them. And when you select an answer, it will display the english.

Now, I need to highlight the correct answer. I've already done some highlighting on the selection. How did that work, before?

Ah, here we go - it's in "custom_list.xml".


xmlns:android="http://schemas.android.com/apk/res/android">



android:startColor="@color/state_pressed_end"
android:endColor="@color/state_pressed_start"
android:angle="90" />
android:width="3dp"
android:color="@color/grey05" />
android:radius="3dp" />
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />





android:endColor="@color/state_focused_end"
android:startColor="@color/state_focused_start"
android:angle="90" />
android:width="3dp"
android:color="@color/grey05" />
android:radius="3dp" />
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />






That's all well and good. But those highlights are encoded in XML, and triggered based on touch events. I need to programmatically set a color; one for the correct answer, and another for the selected, incorrect answer if they're different.

This might be a good place to start:

http://tinyurl.com/3e5ya32

rowView.setBackgroundColor(R.drawable.view_odd_row_bg);

But where did row view come from? Some additional hunting around reveals this url:

http://ykyuen.wordpress.com/2010/03/15/android-%E2%80%93-applying-alternate-row-color-in-listview-with-simpleadapter/

Which has this code:

public void onItemClick(AdapterView parent, View view, int position,

long id) {

// TODO Auto-generated method stub

Log.d("debug", "postion: " + position);

Log.d("debug", "id: " + id);

}

};

It's not clear if view is the whole list view, or that one row.

List's try this:

view.setBackgroundColor(Color.BLUE);

Good. That worked.

But, that's not enough. I need to also highlight the *correct* answer. Obviously, position will play a role here. All I need to do is apply it to something.

There is a parent, the ListView, with a getChild method. So, I need to get the view that's at the correct position.

Let's try this:

View correctRow = l.getChildAt(1);

correctRow.setBackgroundColor(Color.GREEN);

Oddly, it always seem to choose row 3 for the highlighted color. The blue highlight is unpredictable.

Let's change the number:

View correctRow = l.getChildAt(0);

Zero highlights row 4.

I'd best check the API. It just says, it returns the view at the specified postion in the group.

What if I put a 2 in? Well, that one highlights the second row.

Let's try a 3. Yup, it highlights the first row.

So it like a reverse relationship between what you'd expect and child index.

expected actual
0 4
1 3
2 2
3 1


Maybe it's a stack kind of a thing?

Let's see what postion it is...

Toast.makeText(getApplicationContext(), "postion is: " + position,
Toast.LENGTH_SHORT).show();

That's exactly as expected. It's probably the fact that the view is a node, and the node is retrieved list-in, first out. So I'll just twiddle the code to handle it.

Ultimately end up with code like this:

@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);

int childCount = l.getChildCount();
int lastViewPos = childCount - 1;
View selView = l.getChildAt(lastViewPos - position);

// http://www.ceveni.com/2009/08/set-rgb-color-codes-for-android-and-rgb.html
// Light Coral 240-128-128 f08080

selView.setBackgroundColor(Color.rgb(240, 128, 128)); // light red

int i = findCorrectViewPosition(l, childCount);

View correctRow = l.getChildAt(lastViewPos - i);

// Pale Green 152-251-152 98fb98
correctRow.setBackgroundColor(Color.rgb(152, 251, 152));
}

private int findCorrectViewPosition(ListView l, int childCount) {
// find correct answer
int i = 0;
for (i = 0; i < childCount; i++) {
View view = l.getChildAt(i);
String str = (String) ((TextView) view).getText();
if (str.equals(mQuestion.hiragana)) {
break;
}
}
return i;
}


And no more answer display! Of course, there is a lot of cleanup work to do. I'll get to that later.

No comments:

Post a Comment