Mobile App Dev 2022W: Tutorial 6: Difference between revisions
Line 5: | Line 5: | ||
==Getting Started== | ==Getting Started== | ||
* Install [https://developer.android.com/studio/ Android Studio]. While you can run the version for MacOS, you should probably download and run it on the fastest computer you have access to. | |||
* Create a new Phone & Tablet project, selecting the "Empty Activity" template. Select "Kotlin" as the language and API 21, Android 5.0 as the minimum SDK. | |||
* Replace the contents of [https://homeostasis.scs.carleton.ca/~soma/mad-2022w/code/textanalyzer-5/MainActivity.kt MainActivity.kt] (under app->java) with the version below. Be sure to copy the raw source rather than the syntax highlighted version below. | |||
* Replace the contents of [https://homeostasis.scs.carleton.ca/~soma/mad-2022w/code/textanalyzer-5/activity_main.xml activity_main.xml] (under app->res->layout) with the version below. Select the "Code" view (rather than "Design") so you can see the raw XML. You may have save the file below locally as your browser may try to interpret the XML. | |||
* Add the following lines to themes.xml (in app->res->values->themes), just below the last item: | |||
<item name="windowActionBar">false</item> | <item name="windowActionBar">false</item> | ||
<item name="windowNoTitle">true</item> | <item name="windowNoTitle">true</item> | ||
* Create a new Android simulator using the Device Manager. We suggest a Pixel 3a running API 31, but other devices should work fine. | |||
* Save the project and run it! | |||
<!--- | <!--- |
Revision as of 03:47, 16 February 2022
This tutorial is still in development.
In this tutorial you will be playing with textanalyzer-5, which implements the same text analyzer functionality as Tutorial 5's textanalyzer-3. This version, however, is an Android app.
Getting Started
- Install Android Studio. While you can run the version for MacOS, you should probably download and run it on the fastest computer you have access to.
- Create a new Phone & Tablet project, selecting the "Empty Activity" template. Select "Kotlin" as the language and API 21, Android 5.0 as the minimum SDK.
- Replace the contents of MainActivity.kt (under app->java) with the version below. Be sure to copy the raw source rather than the syntax highlighted version below.
- Replace the contents of activity_main.xml (under app->res->layout) with the version below. Select the "Code" view (rather than "Design") so you can see the raw XML. You may have save the file below locally as your browser may try to interpret the XML.
- Add the following lines to themes.xml (in app->res->values->themes), just below the last item:
<item name="windowActionBar">false</item> <item name="windowNoTitle">true</item>
- Create a new Android simulator using the Device Manager. We suggest a Pixel 3a running API 31, but other devices should work fine.
- Save the project and run it!
textanalyzer-5 Code
MainActivity.kt
package carleton.comp1601.textanalyzer5
import androidx.appcompat.app.AppCompatActivity
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.widget.PopupMenu
import kotlin.reflect.KFunction1
class MainActivity : AppCompatActivity() {
private lateinit var t: EditText
private lateinit var analysisResult: TextView
var analysisMode = "None"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
t = findViewById(R.id.t)
t.addTextChangedListener(twatcher)
analysisResult = findViewById(R.id.analysisResult)
updateAnalysis()
}
fun onMenuItemClick(choice: MenuItem): Boolean {
analysisMode = choice.getTitle() as String
updateAnalysis()
return true
}
// https://stackoverflow.com/questions/15580111/
fun showMenu(v: View) {
val menu = PopupMenu(this, v)
for (s in analysis.keys) {
menu.menu.add(s)
}
menu.setOnMenuItemClickListener(::onMenuItemClick)
menu.show()
}
private val twatcher = object : TextWatcher {
override fun afterTextChanged(s: Editable) {
updateAnalysis()
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
}
fun updateAnalysis() {
val inputText: Editable? = t.text
if (inputText != null) {
val analysisFunc: KFunction1<String, String>? = analysis[analysisMode]
if (analysisFunc != null) {
val r = analysisFunc(inputText.toString())
analysisResult.setText(analysisMode + ": " + r)
} else {
analysisResult.setText("Please choose an analysis mode.")
}
}
}
}
fun countUpper(s: String): String {
var count = 0
val upperCase = setOf("A","B","C","D","E","F","G","H","I","J","K","L","M",
"N","O","P","Q","R","S","T","U","V","W","X","Y","Z")
for (c in s) {
if (upperCase.contains(c.toString())) {
count += 1
}
}
return count.toString()
}
fun countCharacters(s: String): String {
val charcount = s.length
return charcount.toString()
}
val analysis: MutableMap<String, KFunction1<String, String>> = mutableMapOf(
"Count" to ::countCharacters,
"Upper Case" to ::countUpper
)
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/analysisMenuButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="26dp"
android:onClick="showMenu"
android:text="Analysis Mode"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/appTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Text Analyzer"
android:textAppearance="@style/TextAppearance.AppCompat.Display2"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/analysisMenuButton"
app:layout_constraintBottom_toTopOf="@id/t"
/>
<EditText
android:id="@+id/t"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="20"
android:hint="Enter Text"
android:inputType="text"
android:minHeight="48dp"
android:textAppearance="@style/TextAppearance.AppCompat.Body2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/analysisResult"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="Result Area"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/t"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>