I created an app on Android Sudio using Kotlin as backend language, I have added a Bottom sheet dialog fragment that contains a simple calculator, but when I click on any button on that calculator in bottom sheet dialog, the app crashes and closes. but the same code in another activity is completely work perfect. but when I put those codes to the bottom sheet dialog, it is not working. I am trying to fix this problem, and it is third day. in logcat I saw this message when app crashes:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.append(java.lang.CharSequence)' on a null object reference
this is my ButtomSheetFragment.kt
package af.myconquer
import af.myconquer.databinding.ActivityBottomSheetFragment
import android.os.Bundle
import android.util.Log
import android.view.View
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import net.objecthunter.exp4j.Expression
import net.objecthunter.exp4j.ExpressionBuilder
class BottomSheetFragment : AppCompatActivity() {
private lateinit var binding: ActivityBottomSheetFragment
var lastNumeric = false
var stateError = false
var lastDot = false
private lateinit var expression: Expression
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityBottomSheetFragment.inflate(layoutInflater)
setContentView(binding.root)
}
fun onAllClearClick(view: View) {
binding.dataTv.text = ""
binding.resultTv.text = ""
stateError = false
lastDot = false
lastNumeric = false
binding.resultTv.visibility = View.GONE
}
fun onEqualClick(view: View) {
onEqual()
binding.dataTv.text = binding.resultTv.text.toString().drop(1)
}
fun onDigitClick(view: View) {
Log.d("onDigitClick", "View ID: ${view.id}, Class: ${view.javaClass.simpleName}")
if (view is Button) {
if (stateError) {
binding.dataTv.text = view.text
// Reset error state
stateError = false
} else {
binding.dataTv.append(view.text)
}
lastNumeric = true
onEqual()
} else {
Log.e("onDigitClick", "View is not a Button")
}
}
fun onOperatorClick(view: View) {
if (!stateError && lastNumeric){
binding.dataTv.append((view as Button).text)
lastDot = false
lastNumeric = false
onEqual()
}
}
fun onBackClick(view: View) {
binding.dataTv.text = binding.dataTv.text.toString().dropLast(1)
try {
val lastChar = binding.dataTv.text.toString().last()
if (lastChar.isDigit()){
onEqual()
}
}catch (e : Exception){
binding.resultTv.text = ""
binding.resultTv.visibility = View.GONE
Log.e("last char error", e.toString())
}
}
fun onClearClick(view: View) {
binding.dataTv.text = ""
lastNumeric = false
}
fun onEqual(){
if (lastNumeric && !stateError){
val txt = binding.dataTv.text.toString()
expression = ExpressionBuilder(txt).build()
try {
val result = expression.evaluate()
binding.resultTv.visibility = View.VISIBLE
binding.resultTv.text = "=" + result.toString()
}catch (ex : ArithmeticException){
Log.e("evalute error", ex.toString())
binding.resultTv.text = "Error"
stateError = true
lastNumeric = false
}
}
}
}
this is activity_bottom_sheet_fragment.xml :
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".ButtomSheetFragment"
android:layoutDirection="locale"
android:padding="16dp">
<View
android:id="@+id/close"
android:layout_width="35dp"
android:layout_height="4dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"
android:layout_marginBottom="15dp"
android:background="@drawable/rounded_divider" />
<View
android:id="@+id/line"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_below="@id/close"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_marginBottom="10dp"
android:background="@color/gray_light" />
<TextView
android:id="@+id/data_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/line"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="2dp"
android:gravity="end"
android:paddingStart="15dp"
android:paddingEnd="15dp"
android:text=""
android:textSize="24sp"
app:layout_constraintBottom_toTopOf="@id/result_tv" />
<TextView
android:id="@+id/result_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_below="@id/data_tv"
android:layout_marginStart="5dp"
android:visibility="gone"
android:layout_marginEnd="5dp"
android:layout_marginBottom="16dp"
android:gravity="end"
android:paddingStart="15dp"
android:paddingEnd="15dp"
android:text=""
android:textSize="24sp" />
<GridLayout
android:id="@+id/gridLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/result_tv"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:columnCount="4">
<!-- Digits -->
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_7"
android:layout_width="0dp"
android:onClick="onDigitClick"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:layout_margin="5dp"
android:background="@drawable/button_calculator"
android:text="7"
android:textSize="22sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_8"
android:layout_width="0dp"
android:onClick="onDigitClick"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:layout_margin="5dp"
android:background="@drawable/button_calculator"
android:text="8"
android:textSize="22sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_9"
android:layout_width="0dp"
android:onClick="onDigitClick"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:layout_margin="5dp"
android:background="@drawable/button_calculator"
android:text="9"
android:textSize="22sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_divide"
android:onClick="onOperatorClick"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:layout_margin="5dp"
android:background="@drawable/button_calculator_operations"
android:text="/"
android:textColor="@color/white_light"
android:textSize="22sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:onClick="onDigitClick"
android:layout_columnWeight="1"
android:layout_margin="5dp"
android:background="@drawable/button_calculator"
android:text="4"
android:textSize="22sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_5"
android:layout_width="0dp"
android:onClick="onDigitClick"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:layout_margin="5dp"
android:background="@drawable/button_calculator"
android:text="5"
android:textSize="22sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_6"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:onClick="onDigitClick"
android:layout_columnWeight="1"
android:layout_margin="5dp"
android:background="@drawable/button_calculator"
android:text="6"
android:textSize="22sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_multiply"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:onClick="onOperatorClick"
android:layout_margin="5dp"
android:background="@drawable/button_calculator_operations"
android:text="*"
android:textColor="@color/white_light"
android:textSize="22sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_1"
android:layout_width="0dp"
android:onClick="onDigitClick"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:layout_margin="5dp"
android:background="@drawable/button_calculator"
android:text="1"
android:textSize="22sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:onClick="onDigitClick"
android:layout_columnWeight="1"
android:layout_margin="5dp"
android:background="@drawable/button_calculator"
android:text="2"
android:textSize="22sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_3"
android:layout_width="0dp"
android:onClick="onDigitClick"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:layout_margin="5dp"
android:background="@drawable/button_calculator"
android:text="3"
android:textSize="22sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_subtract"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:onClick="onOperatorClick"
android:layout_margin="5dp"
android:background="@drawable/button_calculator_operations"
android:text="-"
android:textColor="@color/white_light"
android:textSize="22sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_clear"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:layout_margin="5dp"
android:background="@drawable/button_calculator"
android:text="C"
android:textColor="@color/orange"
android:textSize="22sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_0"
android:layout_width="0dp"
android:onClick="onDigitClick"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:layout_margin="5dp"
android:background="@drawable/button_calculator"
android:text="0"
android:textSize="22sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_dot"
android:layout_width="0dp"
android:onClick="onDigitClick"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:layout_margin="5dp"
android:background="@drawable/button_calculator"
android:text="."
android:textSize="22sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_add"
android:onClick="onOperatorClick"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnWeight="1"
android:layout_margin="5dp"
android:background="@drawable/button_calculator_operations"
android:text="+"
android:textColor="@color/white_light"
android:textSize="22sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_allClear"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnWeight="2"
android:layout_margin="5dp"
android:background="@drawable/button_calculator"
android:text="AC"
android:textColor="@color/orange"
android:textSize="22sp" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_back"
android:layout_width="0dp"
android:layout_columnWeight="2"
android:layout_margin="5dp"
android:background="@drawable/button_calculator"
android:drawableStart="@drawable/baseline_backspace_24"
android:paddingStart="27dp"
android:textSize="22sp" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_equal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_columnWeight="2"
android:layout_margin="5dp"
android:background="@drawable/button_calculator_color"
android:text="="
android:textColor="@color/white"
android:textSize="22sp"
android:textStyle="bold" />
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_modulo"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:onClick="onOperatorClick"
android:layout_columnWeight="2"
android:layout_margin="5dp"
android:background="@drawable/button_calculator_operations"
android:text="%"
android:textAllCaps="false"
android:textColor="@color/white_light"
android:textSize="22sp"
android:textStyle="bold" />
</GridLayout>
</RelativeLayout>
to clear more, this codes work perfectly in another simple activity ok? the problem starts just for Bottom Sheet dialog, I mean when I want to start this activity as Bottom Sheet dialog, it cuase the app crash.
If it helps you to clearance : I also have navigationdrawer and tablayout and toolbar inside this app.
one thing more : When I remove the :
android:onClick="onDigitClick"
from any button inside layout, the button click work perfectly and app dont crashes on click, but functionality not work.
I show this bottom sheet dialog, from Dashboard.kt file :
private fun showCalculatorBottomSheet() {
val bottomSheetDialog = BottomSheetDialog(this)
val view = layoutInflater.inflate(R.layout.activity_bottom_sheet_fragment, null)
bottomSheetDialog.setContentView(view)
bottomSheetDialog.show()
}
the button for showing this bottom sheet dialog is located at toolbar :
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_calculator"
android:icon="@drawable/baseline_calculate_24"
android:title="Calculator"
app:showAsAction="ifRoom" />
</menu>
let me know for any clearance : I will tell you if you ask, I know experts at Android and kotlin or java can help me to solve this. 🙂
I tried to fix this by changing codes and place of codes from BottomSheetFragment to Dashboard and another empty activity, in another activity calculator work perfectly but the other tries not helped me.