Wednesday, February 11, 2009

X Y motion

Android's onTouchEvent was giving me some difficulties. I want to increment and decrement my countdown timer based on touch screen input. The user should be able to touch the screen anywhere and move their finger left, right, up or down, and the values should change in a logical way. I discovered I had to introduce a certain scaling factor in order to prevent the tiny increments and decrements from canceling each other out effectively. The code I came up with computes the delta in X and Y coordinates and only increments or decrements the countdown timer values if the delta is more than a certain amount, in the example the value is 5. You could change this to make the system more or less sensitive. This effectively "understands" the intent of the user's gesture.

Here is my onTouchEvent, it should be fairly self explanatory.

@Override
public boolean onTouchEvent(MotionEvent event) {
float mvX;
float mvY;
boolean chg;
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
startY = event.getY();
startX = event.getX();
break;
case MotionEvent.ACTION_MOVE:
endY = event.getY();
endX = event.getX();
break;
case MotionEvent.ACTION_UP:
endY = event.getY();
endX = event.getX();
break;
default:
return false;
}
chg = false;
mvY = endY - startY;
if(mvY > 5) {
mySecondsTotal += 1;
chg = true;
}
if(mvY < -5) {
mySecondsTotal -= 1;
chg = true;
}
mvX = endX - startX;
if(mvX > 5) {
mySecondsTotal += 1;
chg = true;
}
if(mvX < -5) {
mySecondsTotal -= 1;
chg = true;
}
if (chg == false)
return true;
startY = event.getY();
startX = event.getX();
if (mySecondsTotal < 0)
mySecondsTotal = 0;
Message m = new Message();
m.what = timer.GUIUPDATEIDENTIFIER;
this.myYogaViewUpdateHandler.sendMessage(m);
return true;
}

Monday, February 9, 2009

Using a RadioGroup

Set up your RadioGroup and RadioButtons in your xml layout:


<radiogroup id="@+id/group1" layout_width="fill_parent" layout_height="wrap_content" orientation="horizontal">
<radiobutton id="@+id/radio1" text="Bell" layout_width="wrap_content" layout_height="wrap_content">
</radiobutton>
<radiobutton id="@+id/radio2" text="Crystal" layout_width="wrap_content" layout_height="wrap_content">
</radiobutton>
<radiobutton id="@+id/radio3" text="Gong" layout_width="wrap_content" layout_height="wrap_content">
</radiobutton>
</radiogroup>


Save your preferences


int chime = chimes.getCheckedRadioButtonId();


At first nothing is selected and getCheckedRadioButtonId will return a value of -1, so you might want to test for this condition when getting your saved preferences. Otherwise you'll get the Unique ID of the checked Radio Button which you need to test using R.id.


int chime = prefs.getInt(PREF_CHIME, R.id.radio1);
if (chime < 1)
chime = R.id.radio1;
chimes.check(chime);


Handle the options:


int chime = prefs.getInt(preferences.PREF_CHIME, R.raw.bell);
switch(chime){
case R.id.radio1: {
mp = MediaPlayer.create(timer.this, R.raw.bell);
break;
}
case R.id.radio2: {
mp = MediaPlayer.create(timer.this, R.raw.crystal);
break;
}
case R.id.radio3: {
mp = MediaPlayer.create(timer.this, R.raw.gong);
break;
}
default:
mp = MediaPlayer.create(timer.this, R.raw.bell);
break;
}
try {
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}