[Android Q&A, Help & Troubleshooting] Ap0C552:
I am having a problem with my first Android app. I am posting here looking for guidance to find a solution, or to decide if maybe what I am attempting is to bothersome for someone just learning the android platform. My Java and OO are very strong though.

I am writing a calculator app as my first android app.

I have a mode button on the calculator that changes the buttons to make new functions available.

When mode switches, certain buttons get changed to a different drawable with different colors, and all the text gets updated on all the buttons.

Each mode has a new string array corresponding to the text for that mode.

What I am currently trying to achieve is having a delay between the time that each button is updated, a sort of cascade effect. I have not successfully implemented this.

In the following code I have a toggleLabels method which attempts to do this. It has three if blocks corresponding to the three modes, which each gets a new set of text and buttons. There are two nested for loops in each running i=width and j=height.

To create the cascade effect I grabbed system time, and then subtracted from current time to see that 100ms had passed.

No cascade effect takes place, and when I hit the mode button, there is a long delay then all of the buttons switch at once. The delay seems to be exactly 2 seconds, which corresponds to the cumulative delay of 100ms per button X 20 buttons.

I also tried an alternate method of Thread.Sleep() which yielded the same result, and which I read was bad practice to implement in your UI thread.

Basically I am doing..

loop through each button

{

Change button drawable

Change button text

delay X time

}

But what is showing in the app is

loop through each button

{

Change button drawable

Change button text

}

delay (X * N buttons) amount of time

draw all the buttons at once

I

After doing a lot of investigating, and not finding to much relevant info out there, I am thinking I need to implement a new thread to do this in.

I also came up with the idea of extending a new class of button and overriding the ondraw method with a delay in it. Not sure this is a horribly improper way of doing it.

My code is as follows....

package com.example.calculator;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;

public class MainActivity extends Activity {

EditText displayUpper;
EditText displayLower;
//View root;
LinearLayout keyPanel;
Button[][] buttons;
int width;
int height;
String[] labels1;
String[] labels2;
String[] labels3;
int mode;
long time;
boolean click;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

width=4;
height=5;
mode=3;
click=false;

// root = (LinearLayout)findViewById(R.id.root);
keyPanel = (LinearLayout)findViewById(R.id.keyPanel);
displayUpper = (EditText)findViewById(R.id.editText1);
displayLower = (EditText)findViewById(R.id.editText1);

labels1=getResources().getStringArray(R.array.first_panel);
labels2=getResources().getStringArray(R.array.second_panel);
labels3=getResources().getStringArray(R.array.third_panel);

assignButtons(); //<-must come before toggleLabel
toggleLabel(); //<-must come after assignButtons

final Runnable r = new Runnable()
{
public void run()
{
toggleLabel();
}
};

buttons[3][0].setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Perform action on click

r.run();

}

});

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

//---This method stores all the buttons in a multi-dimensional array
//--- Assigns buttons starting at left column from top to bottom
private void assignButtons()
{
buttons=new Button[width][height];

LinearLayout temp;

for(int i=0;i<width;i++)
{
temp = (LinearLayout)keyPanel.getChildAt(i);

for(int j=0;j<height;j++)
{
buttons[i][j] = (Button)temp.getChildAt(j);
}

}

}

//--This method set and toggles all the button labels
private void toggleLabel()
{

int pos=0;
boolean notchange=true;

if(mode==0)//<--If mode=0 change to second set of buttons
{

mode=1;

time=System.currentTimeMillis();

for(int i=0;i<width;i++)
{

for(int j=0;j<height;j++)
{
notchange=true;

while(notchange)
{
if(System.currentTimeMillis()-time>100)
{
notchange=false;
buttons[i][j].setText(labels2[pos]);
pos++;

if(i==3||j==0)
{
buttons[i][j].setBackgroundResource(R.drawable.sec_button);

}

time=System.currentTimeMillis();
}
}
}

}

}
else if(mode==1)//<--If mode=1 change to third set of buttons
{

mode=2;

time=System.currentTimeMillis();

for(int i=0;i<width;i++)
{
for(int j=0;j<height;j++)
{
notchange=true;
while(notchange)
{
if(System.currentTimeMillis()-time>100)
{
notchange=false;
buttons[i][j].setText(labels3[pos]);
pos++;

if(i==3||j==0)
{
buttons[i][j].setBackgroundResource(R.drawable.third_button);
}

time=System.currentTimeMillis();

}
}
}

}

}
else//<--else change back to first set of buttons
{
mode=0;
time=System.currentTimeMillis();

for(int i=0;i<width;i++)
{
for(int j=0;j<height;j++)
{
notchange=true;
while(notchange)
{
if(System.currentTimeMillis()-time>100)
{

notchange=false;
buttons[i][j].setText(labels1[pos]);
pos++;

if(i==3||j==0)
{
buttons[i][j].setBackgroundResource(R.drawable.calcbutton);
}

time=System.currentTimeMillis();

}
}
}

}
}

}

}