Updating a chart from an ArrayList over time?

2019-03-06 04:47发布

问题:

I have an ArrayList of values, and I would like to iterate through the ArrayList. For every new value, I would like to update the chart with that value, and then wait a set amount of time before doing the same thing to the next value.

At the moment, my log says that all of the values are being iterated over. However, on my testing device, the chart does not update until the very end; at that point, all of the values are loaded at once, so there is no desired "slideshow" effect.

When I want to start playing back the values in my ArrayList, this method is called:

public void playback(){
    if(ret != null) {
        for (int x = 0; x < ret.size(); x++) {
            addEntry(ret.get(x));
            try {
                Thread.sleep(100);
            } catch (Exception e){
                //Do nothing
            }
        }
    } else {
        Log.d(LOG_TAG, "ret was null.");
    }
}

What can I do so that the values are displayed on my chart, one after another, with a certain amount of time between each value?


Edit: Here was the solution I ended up implementing with help from Shadab Ansari:

public void playback(){
    if(ret != null) {
        addEntry(0);
    } else {
        Log.d(LOG_TAG, "ret was null.");
    }
}



private void addEntry(int index) {
    final int in = index;

    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            yVals1.get(0).setVal(ret.get(in).intValue());
            RadarDataSet set1 = new RadarDataSet(yVals1, "Set 1");
            // And other UI stuff

            // Recursive call!
            if(in < ret.size() - 1){
                addEntry(in + 1);
            }
        }
    }, 100);

}

In case it was not clear, ret was a global variable that contained the arrays that I was going to be inserting. yVals1 was an ArrayList of Entries to populate the radar chart.

The end result is that, in this example code, the chart is updated with the next value in my ArrayList every 100 milliseconds. During this time I can still zoom in/out of the chart and rotate it with no problems.

回答1:

If your addEntry() performs a UI operation then let me explain your problem -

Explanation -

Android is an event based system. Something happens on the device (the screen is touched, a key is pressed, etc.) and Android raises an event. An App is notified of an event and when one occurs that it needs to respond to it does so, often running the code that you have written. Your App runs its code in a loop under the control of the Android Operating Systems (OS). This code loop is referred to as the App's thread of execution. There is only one thread and it is responsible for both running the App code and updating the display.

So the UI update does not happen immediately and your making the UI thread sleep for 100 ms every time the loop runs. And when Android tries to update the UI, you make the thread sleep which means during this time period UI thread will not do anything. And this happens till your loop finishes. After your loop ends, the final event gets executed and you will see your UI updated by the call of addEntry() with the latest value passed.

Solution -

You can use postDelayed()-

new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                           //Perform your task and it will be executed after 100 ms
                        }
                    },100);