Search code examples
androidarraysequationsunit-conversion

Android unit converter... too many equations


I am creating a unit converter for Android that uses buttons (to select the type of unit) and spinners (to select the unit) but I have ran into a problem. There are too many possible equations. If you have ten units in each spinner for all the unit types you end having hundreds of different equation possibilities. Does anyone have any idea on how to make a shorter code?

Here are my string arrays for the spinners:

<string-array name="speed">

    <item>Centimeters/Second</item>
    <item>Meters/Second</item>
    <item>Feet/Second</item>
    <item>Feet/Minute</item>
    <item>Miles/Hour</item>
    <item>Kilometers/Hour</item>
    <item>Furlongs/Minute</item>
    <item>Knots</item>
    <item>Leagues/Day</item>
    <item>Mach</item>

</string-array>

<string-array name="distance">

    <item>Meter</item>
    <item>Foot</item>
    <item>Centimeter</item>
    <item>Millimeter</item>
    <item>Micrometer</item>
    <item>Nanometer</item>
    <item>Mile</item>
    <item>Yard</item>
    <item>Inch</item>
    <item>Light Year</item>

</string-array>

<string-array name="temperature">

    <item>Celsius</item>
    <item>Kelvin</item>
    <item>Fahrenheit</item>

</string-array>

<string-array name="area">

    <item>Square Meter</item>
    <item>Square Kilometer</item>
    <item>Square Centimeter</item>
    <item>Square Millimeter</item>
    <item>Square Micrometer</item>
    <item>Hectare</item>
    <item>Square Mile</item>
    <item>Square Yard</item>
    <item>Square Foot</item>
    <item>Square Inch</item>
    <item>Acre</item>

</string-array>

<string-array name="volume">

    <item>Cubic Meter</item>
    <item>Cubic Kilometer</item>
    <item>Cubic Centimeter</item>
    <item>Cubic Millimeter</item>
    <item>Liter</item>
    <item>Milliliter</item>
    <item>US Gallon</item>
    <item>US Quart</item>
    <item>US Pint</item>
    <item>US Cup</item>
    <item>US Fluid Ounce</item>
    <item>US Table Spoon</item>
    <item>US Tea Spoon</item>
    <item>Imperial Gallon</item>
    <item>Imperial Quart</item>
    <item>Imperial Pint</item>
    <item>Imperial Fluid Ounce</item>
    <item>Imperial Table Spoon</item>
    <item>Imperial Tea Spoon</item>
    <item>Cubic Mile</item>
    <item>Cubic Foot</item>
    <item>Cubic Inch</item>
    <item>Cubic Yard</item>

</string-array>

<string-array name="mass">

    <item>Kilogram</item>
    <item>Gram</item>
    <item>Milligram</item>
    <item>Metric Ton</item>
    <item>Long Ton</item>
    <item>Short Ton</item>
    <item>Pound</item>
    <item>Ounce</item>
    <item>Carat</item>
    <item>Atomic Mass Unit</item>
    <item>Stone</item>

</string-array>

<string-array name="time">

    <item>Second</item>
    <item>Millisecond</item>
    <item>Microsecond</item>
    <item>Nanosecond</item>
    <item>Picoseconds</item>
    <item>Minute</item>
    <item>Hour</item>
    <item>Day</item>
    <item>Week</item>
    <item>Month</item>
    <item>Year</item>

</string-array>

<string-array name="energy">

    <item>Joule</item>
    <item>Gram Calorie</item>
    <item>KiloJoule</item>
    <item>Foot-Pound</item>
    <item>Kilocalorie</item>
    <item>Watt Hour</item>
    <item>Electronvolt</item>
    <item>BTU</item>
    <item>US Therm</item>

</string-array>

And here's my converters xml:

RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="ca.software.appart.calcu_everything.Converter">

<Spinner
    android:layout_width="200dp"
    android:layout_height="wrap_content"
    android:id="@+id/spinner"
    android:layout_alignTop="@+id/spinner2"
    android:layout_alignParentStart="true"
    android:layout_toStartOf="@+id/what"
    android:backgroundTint="#2125ff"/>
<Spinner
    android:layout_width="200dp"
    android:layout_height="wrap_content"
    android:id="@+id/spinner2"
    android:layout_above="@+id/calculate"
    android:layout_alignEnd="@+id/linearLayout"
    android:layout_toEndOf="@+id/what"
    android:backgroundTint="#2125ff"/>

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/linear1">

    <Button
        android:background="@drawable/calculator_buttons"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="@string/speed"
        android:textAllCaps="false"
        android:id="@+id/speed" />
    <Button
    android:background="@drawable/calculator_buttons"
    android:layout_width="0dp"
    android:layout_height="match_parent"
    android:layout_weight="1"
    android:text="@string/mass"
    android:textAllCaps="false"
        android:id="@+id/mass" />
    <Button
        android:background="@drawable/calculator_buttons"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="@string/area"
        android:textAllCaps="false"
        android:id="@+id/area" />
    <Button
        android:background="@drawable/calculator_buttons"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="@string/temp"
        android:textAllCaps="false"
        android:id="@+id/temp" />
</LinearLayout>


<LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
    android:layout_below="@id/linear1"
    android:id="@+id/linearLayout">

    <Button
        android:background="@drawable/calculator_buttons"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="@string/energy"
        android:textAllCaps="false"
        android:id="@+id/energy" />
    <Button
        android:background="@drawable/calculator_buttons"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="@string/volume"
        android:textAllCaps="false"
        android:id="@+id/volume" />

    <Button
        android:background="@drawable/calculator_buttons"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="@string/distance"
        android:textAllCaps="false"
        android:id="@+id/distance" />
    <Button
        android:background="@drawable/calculator_buttons"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:text="@string/time"
        android:textAllCaps="false"
        android:id="@+id/time" />
    </LinearLayout>

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/calculate"
    android:id="@+id/calculate"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true"
    android:background="@drawable/science_buttons"/>

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:text="1"
    android:id="@+id/what"
    android:layout_below="@+id/linearLayout"
    android:layout_centerHorizontal="true"
    />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:text="1"
    android:id="@+id/answer"
    android:layout_below="@+id/calculate"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="87dp" />

<EditText
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:inputType="numberSigned"
    android:ems="10"
    android:id="@+id/editText"
    android:layout_below="@+id/calculate"
    android:layout_alignParentEnd="true"
    android:layout_alignParentStart="true" />


Solution

  • Use one as the base unit. Lets say meters for distance. Then rather than ever converting feet to light years, you would convert feet to meters and meters to light years. That reduces the number of conversions you need to 2 per new option (Foo to meters and meters to Foo). When the user hits the convert button, you'd run both conversions.

    Do the same with all the other categories- one base unit per measurement type. Probably best to pick the metric ones.

    In fact for almost all of these, you only need 1 function.

    HashMap<Integer, Double> toMeters;
    toMeters.add(TYPE_CM, .01);
    toMeters.add(TYPE_KM, 1000);
    toMeters.add(TYPE_METERS, 1);
    
    double convert(double amount, int type1, int type2) {
      return amount * toMeters.get(type1) * 1/(toMeters.get(type2));
    }
    

    The only one that doesn't really work with is Farenheit to Celsius, due to the +32 factor.