问题描述
我正在尝试在我的多用途应用程序中实现一个计算器,但我遇到了一个小问题。我已经在 Fragment 类中实现了计算器功能。每次我点击计算器片段时,整个应用都会崩溃。
这是代码并从教程中获得帮助。
计算器片段
package com.khumomashapa.notes.fragments
import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import com.khumomashapa.notes.R
import com.khumomashapa.notes.helper.OperationsHelper
import kotlinx.android.synthetic.main.fragment_calculator.*
class CalculatorFragment : Fragment() {
var digit_on_screen = StringBuilder(12)
var operation: Char = ' '
var leftHandSide: Double = 0.0
var rightHandSide: Double = 0.0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
result_id.text = "0"
initializeButtons()
}
override fun onCreateView(
inflater: LayoutInflater,container: ViewGroup?,savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_calculator,container,false)
}
private fun initializeButtons() {
functionalButtons()
operationalButtons()
numericalButtons()
}
/**
* This function initializes all of our numerical buttons from
* [0 - 9]
*/
private fun numericalButtons() {
one_btn.setonClickListener {
appendToDigitOnScreen("1")
}
two_btn.setonClickListener {
appendToDigitOnScreen("2")
}
three_btn.setonClickListener {
appendToDigitOnScreen("3")
}
four_btn.setonClickListener {
appendToDigitOnScreen("4")
}
five_btn.setonClickListener {
appendToDigitOnScreen("5")
}
six_btn.setonClickListener {
appendToDigitOnScreen("6")
}
seven_btn.setonClickListener {
appendToDigitOnScreen("7")
}
eight_btn.setonClickListener {
appendToDigitOnScreen("8")
}
nine_btn.setonClickListener {
appendToDigitOnScreen("9")
}
zero_btn.setonClickListener {
appendToDigitOnScreen("0")
}
dot_btn.setonClickListener {
appendToDigitOnScreen(".")
}
}
/**
* Insert the button been clicked onto the screen so user can see
* inputs for the button clicked
*/
private fun appendToDigitOnScreen(digit: String) {
// Add each digit to our string builder
digit_on_screen.append(digit)
// display it on the screen of our mobile app
result_id.text = digit_on_screen.toString()
}
/**
* Initialize the operation keys in our calculator like the
* addition key,subtraction key and the likes
*/
private fun operationalButtons() {
addition_btn.setonClickListener {
selectOperation('A')
}
subtract_btn.setonClickListener {
selectOperation('S')
}
divide_btn.setonClickListener {
selectOperation('D')
}
multipy_btn.setonClickListener {
selectOperation('M')
}
}
/**
* Function to assign operational sign to our math calculations
*/
private fun selectOperation(c: Char) {
operation = c
leftHandSide = digit_on_screen.toString().todouble()
digit_on_screen.clear()
result_id.text = "0"
}
/**
* Handles functional operations in out application like
* clear button,backspace button and the clear everything button
*/
private fun functionalButtons() {
clear_everything_btn.setonClickListener {
digit_on_screen.clear()
result_id.text = "0"
}
clear_btn.setonClickListener {
if (digit_on_screen.length <= 0) {
return@setonClickListener
} else {
clearDigit()
}
}
backspace_btn.setonClickListener {
if (digit_on_screen.length <= 0) {
return@setonClickListener
} else {
clearDigit()
}
}
equal_btn.setonClickListener {
performMathOperation()
}
}
/**
* This function performs our Math Operation which is then showed on the screen.
*/
private fun performMathOperation() {
rightHandSide = digit_on_screen.toString().todouble()
when (operation) {
'A' -> {
val sum = OperationsHelper.add(leftHandSide,rightHandSide)
result_id.text = sum.toString()
digit_on_screen.clear()
digit_on_screen.append(sum)
}
'S' -> {
val subtract = OperationsHelper.subtract(leftHandSide,rightHandSide)
result_id.text = subtract.toString()
digit_on_screen.clear()
digit_on_screen.append(subtract)
}
'M' -> {
val multiply = OperationsHelper.multiply(leftHandSide,rightHandSide)
result_id.text = multiply.toString()
digit_on_screen.clear()
digit_on_screen.append(multiply)
}
'D' -> {
val divide = OperationsHelper.divide(leftHandSide,rightHandSide)
result_id.text = divide.toString()
digit_on_screen.clear()
digit_on_screen.append(divide)
}
}
}
/**
* This function remove the last digit on the screen.
*/
private fun clearDigit() {
val length = digit_on_screen.length
digit_on_screen.deleteCharat(length - 1)
if (length <= 0) {
result_id.text = "0"
}else{
result_id.text = digit_on_screen.toString()
}
}
}
Logcat
2021-03-28 11:25:35.688 25778-25778/? E/Zygote: isWhitelistProcess - Process is Whitelisted
2021-03-28 11:25:35.689 25778-25778/? E/Zygote: accessInfo : 1
2021-03-28 11:25:35.697 25778-25778/? I/momashapa.note: Late-enabling -Xcheck:jni
2021-03-28 11:25:35.716 25778-25778/? E/momashapa.note: UnkNown bits set in runtime_flags: 0x8000
2021-03-28 11:25:35.724 25778-25778/? D/ActivityThread: setConscryptValidator
2021-03-28 11:25:35.724 25778-25778/? D/ActivityThread: setConscryptValidator - put
2021-03-28 11:25:36.122 25778-25778/com.khumomashapa.notes D/PhoneWindow: forceLight changed to true [] from com.android.internal.policy.PhoneWindow.updateForceLightNavigationBar:4274 com.android.internal.policy.DecorView.updateColorViews:1547 com.android.internal.policy.PhoneWindow.dispatchWindowAttributesChanged:3252 android.view.Window.setFlags:1153 com.android.internal.policy.PhoneWindow.generateLayout:2474
2021-03-28 11:25:36.123 25778-25778/com.khumomashapa.notes I/MultiWindowDecorSupport: [INFO] isPopOver = false
2021-03-28 11:25:36.123 25778-25778/com.khumomashapa.notes I/MultiWindowDecorSupport: updateCaptionType >> DecorView@ab7bf2e[],isFloating: false,isApplication: true,hasWindowDecorCaption: false,hasWindowControllerCallback: true
2021-03-28 11:25:36.123 25778-25778/com.khumomashapa.notes D/MultiWindowDecorSupport: setCaptionType = 0,DecorView = DecorView@ab7bf2e[]
2021-03-28 11:25:36.181 25778-25778/com.khumomashapa.notes W/momashapa.note: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (greylist,reflection,allowed)
2021-03-28 11:25:36.182 25778-25778/com.khumomashapa.notes W/momashapa.note: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (greylist,allowed)
2021-03-28 11:25:36.403 25778-25778/com.khumomashapa.notes I/ViewRootImpl@32ff46b[MainActivity]: setView = com.android.internal.policy.DecorView@ab7bf2e TM=true MM=false
2021-03-28 11:25:36.445 25778-25778/com.khumomashapa.notes I/ViewRootImpl@32ff46b[MainActivity]: Relayout returned: old=(0,1080,2400) new=(0,2400) req=(1080,2400)0 dur=15 res=0x7 s={true 507110252544} ch=true
2021-03-28 11:25:36.445 25778-27904/com.khumomashapa.notes D/Openglrenderer: createReliableSurface : 0x758376d580(0x7612206000)
2021-03-28 11:25:36.446 25778-27904/com.khumomashapa.notes I/AdrenoGLES: QUALCOMM build : eb230ec,I000594fe7d
Build Date : 04/01/20
OpenGL ES Shader Compiler Version: EV031.27.05.03
Local Branch :
Remote Branch : refs/tags/AU_LINUX_ANDROID_LA.UM.8.9.R1.10.00.00.558.065
Remote Branch : NONE
Reconstruct Branch : nothing
2021-03-28 11:25:36.446 25778-27904/com.khumomashapa.notes I/AdrenoGLES: Build Config : S P 8.0.12 AArch64
2021-03-28 11:25:36.451 25778-27904/com.khumomashapa.notes I/AdrenoGLES: PFP: 0x016ee187,ME: 0x00000000
2021-03-28 11:25:36.481 25778-27904/com.khumomashapa.notes D/Openglrenderer: makeCurrent EglSurface : 0x0 -> 0x0
2021-03-28 11:25:36.485 25778-27904/com.khumomashapa.notes D/Openglrenderer: eglCreateWindowSurface : 0x757f3dce80
2021-03-28 11:25:36.522 25778-27904/com.khumomashapa.notes D/Openglrenderer: makeCurrent EglSurface : 0x0 -> 0x757f3dce80
2021-03-28 11:25:36.527 25778-27904/com.khumomashapa.notes W/Gralloc3: mapper 3.x is not supported
2021-03-28 11:25:36.625 25778-25778/com.khumomashapa.notes I/ViewRootImpl@32ff46b[MainActivity]: MSG_WINDOW_FOCUS_CHANGED 1 1
2021-03-28 11:25:36.626 25778-25778/com.khumomashapa.notes D/InputMethodManager: prepareNavigationBarInfo() DecorView@ab7bf2e[MainActivity]
2021-03-28 11:25:36.626 25778-25778/com.khumomashapa.notes D/InputMethodManager: getNavigationBarColor() -855310
2021-03-28 11:25:36.633 25778-25778/com.khumomashapa.notes D/InputMethodManager: prepareNavigationBarInfo() DecorView@ab7bf2e[MainActivity]
2021-03-28 11:25:36.633 25778-25778/com.khumomashapa.notes D/InputMethodManager: getNavigationBarColor() -855310
2021-03-28 11:25:36.633 25778-25778/com.khumomashapa.notes V/InputMethodManager: Starting input: tba=com.khumomashapa.notes ic=null mNaviBarColor -855310 mIsGetNaviBarColorSuccess true,NavVisible : true,NavTrans : false
2021-03-28 11:25:36.633 25778-25778/com.khumomashapa.notes D/InputMethodManager: startInputInner - Id : 0
2021-03-28 11:25:36.633 25778-25778/com.khumomashapa.notes I/InputMethodManager: startInputInner - mService.startInputOrWindowGainedFocus
2021-03-28 11:25:36.647 25778-25778/com.khumomashapa.notes I/ViewRootImpl@32ff46b[MainActivity]: MSG_RESIZED: frame=(0,2400) ci=(0,91,126) vi=(0,126) or=1
2021-03-28 11:25:36.655 25778-25778/com.khumomashapa.notes D/InputMethodManager: prepareNavigationBarInfo() DecorView@ab7bf2e[MainActivity]
2021-03-28 11:25:36.655 25778-25778/com.khumomashapa.notes D/InputMethodManager: getNavigationBarColor() -855310
2021-03-28 11:25:36.655 25778-25778/com.khumomashapa.notes V/InputMethodManager: Starting input: tba=com.khumomashapa.notes ic=null mNaviBarColor -855310 mIsGetNaviBarColorSuccess true,NavTrans : false
2021-03-28 11:25:36.656 25778-25778/com.khumomashapa.notes D/InputMethodManager: startInputInner - Id : 0
2021-03-28 11:25:37.295 25778-25778/com.khumomashapa.notes I/ViewRootImpl@32ff46b[MainActivity]: ViewPostIme pointer 0
2021-03-28 11:25:37.334 25778-25778/com.khumomashapa.notes I/ViewRootImpl@32ff46b[MainActivity]: ViewPostIme pointer 1
2021-03-28 11:25:37.363 25778-25778/com.khumomashapa.notes D/AndroidRuntime: Shutting down VM
2021-03-28 11:25:37.364 25778-25778/com.khumomashapa.notes E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.khumomashapa.notes,PID: 25778
java.lang.NullPointerException: result_id must not be null
at com.khumomashapa.notes.fragments.CalculatorFragment.onCreate(CalculatorFragment.kt:22)
at androidx.fragment.app.Fragment.performCreate(Fragment.java:2586)
at androidx.fragment.app.FragmentManagerImpl.movetoState(FragmentManagerImpl.java:838)
at androidx.fragment.app.FragmentTransition.addToFirstInLastOut(FragmentTransition.java:1197)
at androidx.fragment.app.FragmentTransition.calculateFragments(FragmentTransition.java:1080)
at androidx.fragment.app.FragmentTransition.startTransitions(FragmentTransition.java:119)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManagerImpl.java:1866)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManagerImpl.java:1824)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManagerImpl.java:1727)
at androidx.fragment.app.FragmentManagerImpl$2.run(FragmentManagerImpl.java:150)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.app.ActivityThread.main(ActivityThread.java:8167)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
2021-03-28 11:25:37.385 25778-25778/com.khumomashapa.notes I/Process: Sending signal. PID: 25778 SIG: 9
解决方法
对于片段,在创建视图之前调用 onCreate
。您应该考虑的生命周期方法是 onViewCreated
,即保证此时已创建视图层次结构。
您可以在 documentation 中查看有关片段生命周期的更多详细信息。