1

I am pretty much a beginner in app development. I am creating a GPA calculator. I was able to create a button that would create a new EditText view for each time it was tapped. but I don't know how can get the values from those EditTexts separately so I can use them to calculate GPA. I looked up every similar question here and on the internet in general, but none of them helped me. Here is my code:

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">

    <LinearLayout
        android:id="@+id/layout_list"
        android:layout_width="match_parent"
        android:layout_height="500dp"
        android:orientation="vertical"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <Button
            android:id="@+id/add_button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:layout_marginTop="20dp"
            android:drawableRight="@drawable/ic_baseline_add_24"
            android:text="Add"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/textView" />


    </LinearLayout>

    <Button
        android:id="@+id/calculate_button"
        android:layout_width="180dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:text="Calculate"
        app:layout_constraintLeft_toLeftOf="@id/layout_list"
        app:layout_constraintTop_toBottomOf="@id/layout_list" />

    <TextView
        android:id="@+id/result"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="13dp"
        android:hint="GPA:0.0"
        android:textSize="20dp"
        app:layout_constraintStart_toEndOf="@id/calculate_button"
        app:layout_constraintTop_toBottomOf="@id/layout_list"
        tools:text="GPA:0.0" />
</androidx.constraintlayout.widget.ConstraintLayout>

new_layout.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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <EditText
        android:id="@+id/gpa_points"
        android:layout_width="150dp"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:background="@drawable/custom_input"
        android:hint=" GPA point"
        android:inputType="number"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <EditText
        android:id="@+id/credit_points"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_margin="20dp"
        android:background="@drawable/custom_input"
        android:hint=" ETCS"
        android:inputType="number"
        app:layout_constraintStart_toEndOf="@+id/gpa_points"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/close"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="18dp"
        android:background="@drawable/ic_baseline_close_24"
        app:layout_constraintLeft_toRightOf="@id/credit_points"
        app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.kt

package com.example.gpacalculator

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Button
import android.widget.LinearLayout


class MainActivity : AppCompatActivity() {

    private var layout: LinearLayout? = null

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

        layout = findViewById(R.id.layout_list)

        val addButton: Button = findViewById(R.id.add_button)
        addButton.setOnClickListener { addView() }

      val calculateButton: Button = findViewById(R.id.calculate_button)
        calculateButton.setOnClickListener { calculate() }

    }

    private fun addView() {
        val gpaView: View = layoutInflater.inflate(R.layout.new_layout, null, false)
        

        layout?.addView(gpaView)
    }

i added this function to my code

    fun calculate(){
        var total = 0.0
        var etcs = 0.0

        layout.children.forEach { newLayout ->
            // Find the gpa_points EditText in the child layout
            val gpaPointsEditText = newLayout.findViewById<EditText>(R.id.gpa_points) as? EditText
            val creditsEditText = newLayout.findViewById<EditText>(R.id.credit_points) as? EditText
            // Parse the text to be able to perform calculations
            val gpaPoints = gpaPointsEditText?.text.toString().toDouble()
            val credits = creditsEditText?.text.toString().toDouble()
            total+=gpaPoints*credits
            etcs+=credits
        }
        var gpa = total/etcs

        val result:TextView = findViewById(R.id.result)
        result.text=gpa.toString()
    }

but it gives me an error like this

java.lang.NumberFormatException: For input string: "null"
atsun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2043)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.lang.Double.parseDouble(Double.java:538)
at com.example.gpacalculator.MainActivity.calculate(MainActivity.kt:46)
at com.example.gpacalculator.MainActivity.onCreate$lambda1(MainActivity.kt:27)
at com.example.gpacalculator.MainActivity.$r8$lambda$1xRU0rpJNKxzUpdKrPz49s5lowk(Unknown Source:0)
at com.example.gpacalculator.MainActivity$$ExternalSyntheticLambda0.onClick(Unknown Source:2)
jane
  • 124
  • 10

1 Answers1

1

You can iterate on the child views of layout, and retrieve the GPA.


// Get a decimal format for the current locale
private val decimalFormat = DecimalFormat.getInstance()

// Iterate on the children of layout
layout.children.forEach { newLayout ->

    // Find the gpa_points EditText in the child layout 
    val gpaPointsEditText = newLayout.findViewById<EditText>(R.id.gpa_points) as EditText

    // Parse the text to be able to perform calculations
    val gpaPointsStr = gpaPointsEditText.text.toString()
    
    val gpaPoints = decimalFormat.parse(str)
}

To learn more about layouts :

https://developer.android.com/guide/topics/ui/declaring-layout

GerbenDev
  • 26
  • 3
  • thank you for your answer! i did what u suggested but i am getting an error. i edited my question, can you take a look? it gives an error at this line `val gpaPoints = gpaPointsEditText?.text.toString().toDouble()` (which is MainActivity.kt :46) – jane Jun 26 '22 at 09:34
  • 1
    You're welcome :) You can use .toDoubleOrNull() instead, which will return null if the parsing fails. (number is not properly formatted). – GerbenDev Jun 26 '22 at 13:21
  • 1
    For an international approach to parsing floating numbers you should check this out : https://stackoverflow.com/a/4323627/14718206 ( .toDouble() only works for languages where a dot "." is used as seperator for floating numbers) – GerbenDev Jun 26 '22 at 13:29