Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android

alex gwartney
alex gwartney
8,849 Points

How to iterate through a array on button click?

So Im having a bit of trouble coming up with how to do this. I need to iterate through a array each time i click a button. So if i have a string array that holds elements a through z. I want to be able to click the button go to a then click again and go to b ect.

2 Answers

Hi Alex,

I read Harry's reply and agree that a for loop is prefect for iterating through an array. I then got to thinking about your problem - you want to step through an array every time a button is clicked so there's a GUI requiremenet and an event call too.

The button click detection mechanism in Android is set up as a listener. That listener waits for the click event to occur then calls some code to respond to the click. That code then stops but it doesn't hold up execution so I don't know how to halt the for loop whilst waiting for a click event to occur. The for loop above will just iterate on its own, not stopping for a mouse click.

That got me thinking about alternative methods. I set up a very simple screen with a button and a label. The idea is that clicking the button changes the label to the next array element. When the last element is reached (I got bored typing the array at "H"!) it restarts from the beginning. We can make it stop, if that's the requirement.

public class MainActivity extends ActionBarActivity {
    // array example - this can contain anything
    public String [] mAlphaArray = {"A", "B", "C", "D", "E", "F", "G", "H"};
    // a counter to track the position - might not be required
    public int mIfCounter = 0;
    // the label to show the array element
    public TextView mViewLabel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // init the label
        mViewLabel = (TextView) findViewById(R.id.ifTestLabel);
        // connect up the button
        Button setIfTestButton = (Button) findViewById(R.id.btnIfTest);
        // listen for a click ... shhhhh!
        setIfTestButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                /** In here we test to see if we've hit the last
                 *  element in the array and reset if we have, 
                 *  else just carry on to the next
                 */
                mViewLabel.setText(mAlphaArray[mIfCounter]);
                if (mIfCounter < mAlphaArray.length - 1){
                    mIfCounter++;
                } else {
                    mIfCounter = 0;
                }
            }
        });
    }

I'll keep thinking about the for loop - there must be a way of doing it - but I thought I'd share that as a possible solution in the meantime. This code is in a Github repo here - feel free to tinker with it, or bin it completely!!

Steve.

alex gwartney
alex gwartney
8,849 Points

Ok Steve this worked perfectly for what i need i implemented into my project and it is good to go. Now the only question i have is what is the -1 for i get how every thing else works but that. So if you could explain that it would be awesome. Ether wise thank you so much for solving that for me.

Hi Alex,

The - 1 is needed for two reasons. First, the order the bounds-check is done in relation to the increment is the main one.

You know an array starts counting its elements at zero so that:

String [] arr = {"A", "B", "C"};

has three elements [0] is A, [1] is B and [2] is C. But arr.length is 3.

So, if I've got code (like in the main app) like:

if (count < arr.length) {
  count++;
} else {
  count = 0;
}

Then on the first pass, count is zero; cool. During that pass it is incremented to 1. Next pass, it clears the test in the if allowing count to be incremented again; count is now 2. The third pass (which should be the last) count is 2. That is less than arr.length so it is incremented once again, making it equal to 3.

So we now have the scenario where we are going to try access arr[3] which will throw a bounds exception. So, I stopped the if test at arr.length - 1 so that the largest value the count could reach is equal to the index number to access the last element of the array, i.e. arr[2].

The same applies to the code in the mini-app. Although I cleaned that up a little in my first post above to avoid some nonsense that was happening. I suggest you amend your code appropriately; move the mViewLabel.settext() to before the if and delete the silly method I created for no reason!

Shout if you need more!

Steve.

Harry James
Harry James
14,780 Points

This is a great solution for this context! My answer was just to print out all of the different values in the array which wouldn't be suitable for what Alex is using this for.

Using the for loop would indeed congest that thread as it loops through all of the values, rendering the app unusable during this time.

If you really did want to use the for loop (Which in this case I wouldn't recommend as the method Steve has provided is what I believe to be the most efficient method of going about this) then perhaps it could run on a background thread where you would call runOnUiThread() to update the label but again, that would be inefficient for this context.

Harry James
Harry James
14,780 Points

Hey Alex!

For that, we can use a for loop. Here's an example:

// mArray has already been declared.
for (int i = 0; i < 11; i++) {
Log.d("TAG", "The value of mArray[" + i + "]" + " is: " + mArray[i]);
}

So if at mArray[0] the value was "Test", this would read out: "The value of mArray[0] is Test".

Now, let's explain what goes in the parentheses:

int i = 0; is where we declare a variable (I created one called i for integer within the parentheses) and then we set it to a value (0 in this case as the first time this runs through, I want to use index 0).

i < 11 is the condition. The for loop will only run if this condition is met. So, we're actually going to run this through 11 times up to index 10 (Remember, arrays start at index 0).

i++ is ran each time the for loop runs. i++ is simply a shorthand for i + 1, both do the same thing and this would actually work.


Hopefully this should work for you but if there's anything you don't understand fully, give me a shout and I'll try my best to explain it further :)

alex gwartney
alex gwartney
8,849 Points

Really good explanation and thanks for helping me out you are close to what im wanting to do but as Steve had said the problem with the for loop is that it iterates all by it self rather then when the button clicks, Check out what Steve had wrote i think this is what i need im going to try it out and see if this gets what i want. And again thanks for the help though.

If you let us know exactly what you want, I'm sure we can come up with something that fits better - I just chucked a little app together trying to get a for loop to work!

I still can't think how to get a for loop to fit - without halting all execution pending a button click, I don't think it fits what you need, That's not good practice, so let's stick with an event-driven model and manage the number of iterations based on the length of the array.

Just my view! And I'm wrong more often than not.

Steve.

alex gwartney
alex gwartney
8,849 Points

Well what you had did was exactly what i was wanting to do i wanted a button event that looped through a array. im re doing a version of the fun facts app to do something different with it for practice.

And im setting it up different because they use a random array and i did not want that for what iam doing so i wanted to go a different route. so that is why i was asking how to get the button to click through the array because the random array does this for you with the random generation.