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?

2
  • Is this a one-off thing? Commented Jun 22, 2012 at 17:23
  • Sorry, I don't know what that means Commented Jun 22, 2012 at 18:20

6 Answers 6

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
Sign up to request clarification or add additional context in comments.

4 Comments

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 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.)
@trumpetlicks Update: even without the DecimalFormatter, BigDecimal is still faster than float
@ 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
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);

7 Comments

Can you show me the code you are telling me to use? I thought this answer worked but I cannot initialize a SpinnerAdapter correctly
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?
Also, the android.r.layout.LAYOUT, I have about 8 spinners in this one layout. Does that not matter?
You should be able to use an ArrayList. Check out developer.android.com/reference/android/widget/… 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().
Is there any chance you can clarify the 'android.R.layout.LAYOUT' and 'android.R.layout.SPINNER' calls?
|
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;       
}

Comments

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);
}

2 Comments

Thank you, what is the method call to set this List as the contents of my spinner?
Look here for an example! developer.android.com/guide/topics/ui/controls/spinner.html You will most likely have to implement a SpinnerAdapter.
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.

5 Comments

How will this populate the spinner?
I'm not doing it in my .java file, I would be doing it in my .xml file.
@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
@JuiCe Are you trying to do this as a one-off?
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 :)
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));

2 Comments

The implementation for this isn't already included in the SDK?
Actually you have to implement your own, as the views may change according to your app. This link shows some more examples for custom layouts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.