0

I am creating a spinner in my current layout file, and the contents of this spinner range from 1.0 mA, all the way to 100.0mA. Each increment increases by 0.1 mA. Is there a way to have some sort of loop to populate this string-array, other than manually entering each entry in my string-array file?

JuiCe
  • 4,132
  • 16
  • 68
  • 119

6 Answers6

2

You can use BigDecimal to do this. Here's an example that prints them to the screen from 1.0 to 3.0. You can adapt as necessary.

By using BigDecimal, you will not have rounding errors internally or externally, meaning if you extend it to a bigger number down the road, you won't run into those issues. Big Decimal was designed for this kind of thing.

import java.util.*;
import java.math.*;
class Amps {
    public static void main(String[] args) {
        List<String> strs = new ArrayList<String>();
        BigDecimal max = new BigDecimal("3.0");
        BigDecimal inc = new BigDecimal("0.1");
        for(BigDecimal cur = new BigDecimal("1.0"); cur.compareTo(max) <= 0; cur = cur.add(inc)) {
            strs.add(cur.toString() + "mA");
        }
        System.out.println(strs);
    }

}

If you're wondering about the speed, using the BigDecimal is actually faster than using the formatter. Here's a small test that runs them back and forth for a sample size of about 1,000,000 strings:

import java.math.*;
import java.text.*;
import java.util.*;
class Amps {
    public static void main(String[] args) {
        usingBig();
        usingPrim();
        usingBig();
        usingPrim();
        usingBig();
        usingPrim();
        usingBig();
        usingPrim();
        usingBig();
        usingPrim();
    }

    static void usingBig() {
        long then = System.currentTimeMillis();
        List<String> strs = new ArrayList<String>(1000000);
        BigDecimal max = new BigDecimal("100000.0");
        BigDecimal inc = new BigDecimal("0.1");
        for(BigDecimal cur = new BigDecimal("1.0"); cur.compareTo(max) <= 0; cur = cur.add(inc)) {
            strs.add(cur.toString() + "mA");
        }
        long now = System.currentTimeMillis();
        System.out.println("Big: " + (now - then));
    }

    static void usingPrim() {
        long then = System.currentTimeMillis();
        DecimalFormat formatter = new DecimalFormat("0.0");
        List<String> strs = new ArrayList<String>(1000000);
        float max = 100000.0f;
        float inc = 0.1f;
        for(float cur = 1.0f; cur <= max; cur += inc) {
            strs.add(formatter.format(cur) + "mA");
        }
        long now = System.currentTimeMillis();
        System.out.println("Prim: " + (now - then));
    }

}

With a result of:

C:\files\j>java Amps
Big: 1344
Prim: 5172
Big: 1047
Prim: 4656
Big: 1172
Prim: 4531
Big: 1125
Prim: 4453
Big: 1141
Prim: 4547

Even without the DecimalFormatter, primitives are still slower than BigDecimal. See below the results of if I comment out the DecimalFormatter and it's format call (using instead cur + "mA" to add to the list).

C:\files\j>java Amps
Big: 1328
Prim: 1469
Big: 1093
Prim: 1438
Big: 1375
Prim: 1562
Big: 1204
Prim: 1500
Big: 1109
Prim: 1469
corsiKa
  • 81,495
  • 25
  • 153
  • 204
  • Interesting method, wondering about the speed as this is most likely an implementation of a big-num library. Generally these tend to be fairly slow. I like it though, thinking out of the box :-) – trumpetlicks Jun 22 '12 at 17:21
  • @trumpetlicks As illustrated by the example in my edit, the BigDecimal class is actually faster for this purpose than the DecimalFormatter (which you would need to make your numbers show up right, since many numbers you'd encounter can't be represented exactly in floating point.) – corsiKa Jun 22 '12 at 20:59
  • @trumpetlicks Update: even without the DecimalFormatter, `BigDecimal` is still faster than `float` – corsiKa Jun 22 '12 at 21:01
  • @ GREAT INFORMATION - thanks for the update and the data. I have implemented most of my own big-num library in C / C++. I thought this could be possible with the low character count number, but it is great to see your data, thank your :-) +1 – trumpetlicks Jun 22 '12 at 21:02
1

Create a SpinnerAdapter and hook it up to your spinner. Then you can loop through calling adapter.add(item1), adapter.add(item2), etc...

Check this out also: How can I add items to a spinner in Android?

For example,

Spinner spinner = (Spinner) findViewById(R.id.spinner);

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, YOUR_STRING_ARRAY);

adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

spinner.setAdapter(adapter);
Community
  • 1
  • 1
barbiepylon
  • 891
  • 7
  • 23
  • Can you show me the code you are telling me to use? I thought this answer worked but I cannot initialize a SpinnerAdapter correctly – JuiCe Jun 22 '12 at 18:19
  • Thank you, does the YOUR_STRING_ARRAY need to be an actual string array, or can i use another container such as an ArrayList of Strings? – JuiCe Jun 22 '12 at 18:36
  • Also, the android.r.layout.LAYOUT, I have about 8 spinners in this one layout. Does that not matter? – JuiCe Jun 22 '12 at 18:40
  • You should be able to use an ArrayList. Check out http://developer.android.com/reference/android/widget/ArrayAdapter.html for documentation. It looks like you can pass any sort of list into it. It doesn't matter that your layout has more than one spinner...just choose the one you want using adapter.setDropDownViewResource(). – barbiepylon Jun 22 '12 at 19:23
  • Is there any chance you can clarify the 'android.R.layout.LAYOUT' and 'android.R.layout.SPINNER' calls? – JuiCe Jun 26 '12 at 13:29
  • So, I think my answer was a tad off. I've corrected it now. Basically, android.R.layout.simple_spinner_item is a Android layout that you can use. If you want you can create your own layout to style the spinner items and use that instead by calling R.Layout.YOURLAYOUT. Likewise, android.R.layout.simple_spinner_dropdown_item is built in for your use. By setting the adapter to your spinner you are using these built in layouts which style your spinner items. Remember, you can create your own layouts and use these insteads. – barbiepylon Jun 26 '12 at 13:59
  • Let me know if this works...I was going off of some old code and mistakenly thought that I was using custom layouts which is why my first answer was a little confusing! – barbiepylon Jun 26 '12 at 14:07
1

Of course you can:

String[] data = new String[991];

int i = 0;
for(float f=1.0f; f<=100.0f; f+=0.1f) {
    data[i++] = "" + f + "A";
}

EDIT: If you want to put this array in your XML file, you can use any programming language you want to generate this array as a one-off. For example, this java code will do the grunt work for you:

import java.text.*;
public class T {
  public static void main(String[] args) {
  DecimalFormat formatter = new DecimalFormat("0.0");

    for(float f=1.0f; f<=100.0f; f+=0.1f) {
      System.out.println("\"" + formatter.format(f) + "A\",");
    }
  }
}

Compile/run it: javac T.java followed by java T > output.txt. Now open the output.txt file in a text editor and copy/paste your array.

Aleks G
  • 56,435
  • 29
  • 168
  • 265
  • 1
    How will this populate the spinner? – barbiepylon Jun 22 '12 at 17:12
  • I'm not doing it in my .java file, I would be doing it in my .xml file. – JuiCe Jun 22 '12 at 17:17
  • @user1454749 Please read the question carefully: the OP is not asking to populate the spinner, but to populate the array in a loop so that he wouldn't have to type all values by hand – Aleks G Jun 22 '12 at 17:17
  • @JuiCe Are you trying to do this as a one-off? – Aleks G Jun 22 '12 at 17:18
  • Yeah, I read it as a one-off too. For that matter, he could put similar generative code in his app, run it once, and copy it out of LogCat :) – Josh Jun 22 '12 at 19:50
1
List<String> list = new ArrayList<String>();

now using for loop you can add data in list and set list to spinner..

for(float value=1.0f;value<100.0f;){
        String str = String.valueOf(value);
        list.add(value+"mA");
          value+=0.1f;       
}
Samir Mangroliya
  • 39,918
  • 16
  • 117
  • 134
1

Try a loop that generates strings

List<String> list = new ArrayList<String>();
int endCount = (100. - 1.0) / .1
For(int i = 0; i < endCount; i++){

    String stringToAdd = String.format("%.1f mA", 1.0 + ((float)i * 0.1));

    // Add stringToAdd to your array
    list.add(stringToAdd);
}
trumpetlicks
  • 7,033
  • 2
  • 19
  • 33
  • Thank you, what is the method call to set this List as the contents of my spinner? – JuiCe Jun 22 '12 at 17:39
  • Look here for an example! http://developer.android.com/guide/topics/ui/controls/spinner.html You will most likely have to implement a SpinnerAdapter. – trumpetlicks Jun 22 '12 at 17:41
1

You will have to implement a SpinnerAdapter class, similar to this one:

public class MySpinnerAdapter implements SpinnerAdapter {
   private List<String> steps = new ArrayList<String>();
   public MySpinnerAdapter(double min,double max,double increment) {
      for(double f=min;f < max;f+=increment) steps.add(String.valueOf(f)+" mA");
   }
   public int getCount() {
      return steps.size();
   }
   public View getView(int position, View convertView, ViewGroup parent) {
      TextView t = new TextView(YourActivity.this);
      t.setText(steps.get(position));
      return t;
   }
   public boolean isEmpty() {
      return (steps.size() == 0);
   }
   public View getDropDownView(int position, View convertView,ViewGroup paret) {
      if(convertView != null) return(convertView);
      return(getView(position,convertView,parent));
   }
   public Object getItem(int position) {
      return(steps.get(position));
   }
   public long getItemId(int position) {
      return position;
   }
   public int getItemViewType(int position) {
      return 0;
   }
   public int getViewTypeCount() {
      return 1;
   }
   public boolean hasStableIds() {
      return true;
   }
   public void registerDataSetObserver(DataSetObserver observer) {
   }
   public void unregisterDataSetObserver(DataSetObserver observer) {
   }
}

Then you have to set a new instance of this class into your Spinner:

Spinner s = (Spinner) findViewById(R.id.YourSpinnerId);
s.setAdapter(new MySpinnerAdapter(1.0,100.0,0.1));
Carlos Barcellos
  • 544
  • 1
  • 4
  • 10
  • The implementation for this isn't already included in the SDK? – JuiCe Jun 22 '12 at 18:23
  • Actually you have to implement your own, as the views may change according to your app. This [link](http://app-solut.com/blog/2011/03/using-custom-layouts-for-spinner-or-listview-entries-in-android/) shows some more examples for custom layouts. – Carlos Barcellos Jun 22 '12 at 18:36