Mobile App Dev 2021W: Tutorial 6: Difference between revisions

From Soma-notes
No edit summary
Line 1: Line 1:
'''This tutorial is still in development.'''
'''This tutorial is still in development.'''
==Tasks==
# Compare the Kotlin and Swift versions of Conversions.  How does the Converter class differ?  How does the conversions dictionary/map differ?  And, how are they the same?  What does this tell you about the similarity and differences between the languages?
# What is the flow of control of MainActivity?  How does this flow of control compare to that of ContentView in Converter2 from Tutorial 2?


==Code==
==Code==

Revision as of 16:34, 10 March 2021

This tutorial is still in development.

Tasks

  1. Compare the Kotlin and Swift versions of Conversions. How does the Converter class differ? How does the conversions dictionary/map differ? And, how are they the same? What does this tell you about the similarity and differences between the languages?
  2. What is the flow of control of MainActivity? How does this flow of control compare to that of ContentView in Converter2 from Tutorial 2?


Code

Converter2A.zip

Conversions.kt

package carleton.comp1601.converter_2a

//  Conversions.kt

class Converter {
    var convFrom = "From Type"
    var convTo = "To Type"
    var convert: (from: Double) -> Double?

    fun formatConversion(from: Double): String {
        val to = this.convert(from)
        if (to != null) {
            return "${from} ${this.convFrom} is ${to} ${this.convTo}."
        } else {
            return "Converting ${from} ${convFrom} to ${this.convTo} failed."
        }
    }

    constructor(from: String, to: String, f: (from: Double) -> Double?) {
        this.convFrom = from
        this.convTo = to
        this.convert = f
    }
}

fun InToCM(inch: Double): Double? {
    val cm = 2.54 * inch
    return cm
}

val conversions = mapOf(
        "F to C" to Converter("Farenheit", "Celsius",
            {F ->  ((F - 32.0)*(5/9))}),
        "C to F" to Converter("Celsius","Farenheit",
            {((9/5)*it + 32.0)}),
        "km to mi" to Converter("kilometers", "miles",
            fun (k: Double): Double? {
                val m = k * 0.6213712
                return m
            }),
        "inch to cm" to Converter("inches", "centimeters", ::InToCM))

MainActivity.kt

package carleton.comp1601.converter_2a

import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.view.MenuItem
import android.view.View
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.PopupMenu

class MainActivity : AppCompatActivity() {
    private lateinit var result: TextView
    private lateinit var menuButton: Button
    private lateinit var fromStringW: EditText
    private var conv: Converter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        menuButton = findViewById(R.id.convMenu)
        fromStringW = findViewById(R.id.fromString)
        result = findViewById(R.id.result)

        fromStringW.addTextChangedListener(watcher)
        fromStringW.setVisibility(View.INVISIBLE);
    }

    fun onMenuItemClick(choice: MenuItem): Boolean {
        val convName = choice.getTitle()
        val c = conversions[convName]

        if (c != null) {
            conv = c
            result.setText("You picked ${convName}")
            fromStringW.setText("")
        } else {
            result.setText("Invalid Menu Selection")
        }

        fromStringW.setVisibility(View.VISIBLE);
        return true
    }

    // https://stackoverflow.com/questions/15580111/
    fun showMenu(v: View) {
        val menu = PopupMenu(this, v)

        for (s in conversions.keys) {
            menu.menu.add(s)
        }

        menu.setOnMenuItemClickListener(::onMenuItemClick)
        menu.show()
    }

    private val watcher = object : TextWatcher {

        override fun afterTextChanged(s: Editable) {
            val fromS = fromStringW.getText().toString()
            var from = fromS.toDoubleOrNull()

            if (from == null) {
                result.setText("Please enter a number to convert.")
            } else {
                val c = conv

                if (c != null) {
                    result.setText(c.formatConversion(from))
                } else {
                    result.setText("No conversion selected.")
                }
            }
        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
        }
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/convMenu"
        style="@style/Widget.MaterialComponents.Button.TextButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="showMenu"
        android:text="Conversions Menu"
        android:textAppearance="@style/TextAppearance.AppCompat.Display1"
        android:textColor="@color/black"
        app:backgroundTint="@color/white"
        app:layout_constraintBottom_toTopOf="@+id/fromString"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/fromString"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ems="10"
        android:inputType="textPersonName"
        app:layout_constraintBottom_toTopOf="@+id/result"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/convMenu" />

    <TextView
        android:id="@+id/result"
        android:layout_width="418dp"
        android:layout_height="341dp"
        android:padding="10dp"
        android:text="Please select a conversion type from the menu above."
        android:textAlignment="center"
        android:textAppearance="@style/TextAppearance.AppCompat.Medium"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/fromString" />

</androidx.constraintlayout.widget.ConstraintLayout>