NullPointerException:Attempt to invoke virtual method 'double java.lang.Double.doubleValue()' on ..

今天在开发过程中,加载界面,然后在初始化数据的时候报错“  Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'double java.lang.Double.doubleValue()' on a null object reference”。定位报错代码到对应的行数:

 private Double totalExpenses; //提前声明好了变量

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_decoration_bills);

       .......
       totalExpenses = totalExpenses + pay;
       .......

    }


这是因为 声明的全局变量totalExpenses,没有初始化。改成:初始化就好了 就不会报空指针了

private Double totalExpenses = 0.0;


这些小的细节很重要。


crash日志: 08-19 09:26:57.321 13888 14095 F libc : Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0xb400007300000000 in tid 14095 (initCameraInfo), pid 13888 (om.oplus.camera) 08-19 09:27:02.619 17868 17868 F DEBUG : Process name is com.oplus.camera, uid is 10172, not key_process 08-19 09:27:02.620 17868 17868 F DEBUG : keyProcess: 0 08-19 09:27:02.620 17868 17868 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 08-19 09:27:02.620 17868 17868 F DEBUG : Build fingerprint: 'realme/RMX5253IN/RE644C:15/AP3A.240617.008/V.R4T2.2f4847c-100eb7c-100ecfe:user/release-keys' 08-19 09:27:02.620 17868 17868 F DEBUG : Revision: '0' 08-19 09:27:02.620 17868 17868 F DEBUG : ABI: 'arm64' 08-19 09:27:02.620 17868 17868 F DEBUG : Timestamp: 2025-08-19 09:26:57.959834776+0800 08-19 09:27:02.620 17868 17868 F DEBUG : Process uptime: 91s 08-19 09:27:02.620 17868 17868 F DEBUG : Cmdline: com.oplus.camera 08-19 09:27:02.620 17868 17868 F DEBUG : pid: 13888, tid: 14095, name: initCameraInfo >>> com.oplus.camera <<< 08-19 09:27:02.620 17868 17868 F DEBUG : uid: 10172 08-19 09:27:02.620 17868 17868 F DEBUG : tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE) 08-19 09:27:02.620 17868 17868 F DEBUG : signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0xb400007300000000 08-19 09:27:02.620 17868 17868 F DEBUG : x0 b400007300000000 x1 0000007315411f6f x2 0000000000000000 x3 00000a3a65636172 08-19 09:27:02.620 17868 17868 F DEBUG : x4 0000000000000000 x5 8080000000000000 x6 feff093964626071 x7 7f7f7f7f7f7f7f7f 08-19 09:27:02.620 17868 17868 F DEBUG : x8 6468d103908d46de x9 6468d103908d46de x10 0000000000000002 x11 00000073b640a028 08-19 09:27:02.620 17868 17868 F DEBUG : x12 0000000000000003 x13 00000075ec9a3398 x14 0000000000000001 x15 0000000000000008 08-19 09:27:02.620 17868 17868 F DEBUG : x16 00000073155315d0 x17 0000007314f364a8 x18 000000000000005a x19 b4000073a5cdde20 08-19 09:27:02.620 17868 17868 F DEBUG : x20 0000000000000000 x21 b400007300000000 x22 b4000073a8c0d100 x23 b4000073a5cddd90 08-19 09:27:02.620 17868 17868 F DEBUG : x24 0000000000000000 x25 00000074404aa140 x26 000000748c428108 x27 000000748c428100 08-19 09:27:02.620 17868 17868 F DEBUG : x28 000000748c428110 x29 000000748c427f60 08-19 09:27:02.620 17868 17868 F DEBUG : lr 0000007314f47720 sp 000000748c427f50 pc 0000007314f364b4 pst 0000000060001000 08-19 09:27:02.620 17868 17868 F DEBUG : 21 total frames 08-19 09:27:02.620 17868 17868 F DEBUG : backtrace: 08-19 09:27:02.620 17868 17868 F DEBUG : #00 pc 00000000000b54b4 /odm/lib64/libXDocProcessSDK.so (xsdk::XDocDetector::~XDocDetector()+12) (BuildId: fc607651bf45e25a3db1441a3a35ff1c435e2a55) 08-19 09:27:02.620 17868 17868 F DEBUG : #01 pc 00000000000c671c /odm/lib64/libXDocProcessSDK.so (xsdk::QuadDetector::Init(unsigned char const*, unsigned long, int)+168) (BuildId: fc607651bf45e25a3db1441a3a35ff1c435e2a55) 08-19 09:27:02.620 17868 17868 F DEBUG : #02 pc 00000000000100fc /odm/lib64/libSuperTextWrapper.so (xnnInitedByByte+116) (BuildId: ae32866688049b7aabb663b359b94fc994d77513) 08-19 09:27:02.620 17868 17868 F DEBUG : #03 pc 000000000001329c /product/lib64/libXDocProcessSDK-jni.so (Java_com_youtu_ocr_docprocess_DocDetector_xnnInitedByByte+88) (BuildId: d3b90c13fb4c862fc9f126b36f9cd89338665a31) 08-19 09:27:02.620 17868 17868 F DEBUG : #04 pc 00000000000c91cc /system/framework/arm64/boot.oat (art_jni_trampoline+124) (BuildId: 8a0148760ce648144175623fdb3235cc5d70660c) 08-19 09:27:02.620 17868 17868 F DEBUG : #05 pc 0000000000782420 /apex/com.android.art/lib64/libart.so (nterp_helper+4016) (BuildId: 4ccb65ae9ac5ad5da3af5a342d5b0b92) 08-19 09:27:02.620 17868 17868 F DEBUG : #06 pc 000000000012b588 /product/app/OplusCamera/OplusCamera.apk (com.oplus.ocs.camera.SuperTextHelper.xnnInitedByByte+4) 08-19 09:27:02.620 17868 17868 F DEBUG : #07 pc 00000000007823c4 /apex/com.android.art/lib64/libart.so (nterp_helper+3924) (BuildId: 4ccb65ae9ac5ad5da3af5a342d5b0b92) 08-19 09:27:02.621 17868 17868 F DEBUG : #08 pc 00000000000a5be2 /product/app/OplusCamera/OplusCamera.apk (com.oplus.camera.feature.sticker.ui.n.run+722) 08-19 09:27:02.621 17868 17868 F DEBUG : #09 pc 00000000007831e4 /apex/com.android.art/lib64/libart.so (nterp_helper+7540) (BuildId: 4ccb65ae9ac5ad5da3af5a342d5b0b92) 08-19 09:27:02.621 17868 17868 F DEBUG : #10 pc 00000000000efede /product/app/OplusCamera/OplusCamera.apk (d6.g$a.run+50) 08-19 09:27:02.621 17868 17868 F DEBUG : #11 pc 0000000000338070 /system/framework/arm64/boot.oat (java.util.concurrent.ThreadPoolExecutor.runWorker+784) (BuildId: 8a0148760ce648144175623fdb3235cc5d70660c) 08-19 09:27:02.621 17868 17868 F DEBUG : #12 pc 0000000000334338 /system/framework/arm64/boot.oat (java.util.concurrent.ThreadPoolExecutor$Worker.run+56) (BuildId: 8a0148760ce648144175623fdb3235cc5d70660c) 08-19 09:27:02.621 17868 17868 F DEBUG : #13 pc 00000000001bb790 /system/framework/arm64/boot.oat (java.lang.Thread.run+64) (BuildId: 8a0148760ce648144175623fdb3235cc5d70660c) 08-19 09:27:02.621 17868 17868 F DEBUG : #14 pc 0000000000368774 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: 4ccb65ae9ac5ad5da3af5a342d5b0b92) 08-19 09:27:02.621 17868 17868 F DEBUG : #15 pc 0000000000353f24 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+132) (BuildId: 4ccb65ae9ac5ad5da3af5a342d5b0b92) 08-19 09:27:02.621 17868 17868 F DEBUG : #16 pc 0000000000947748 /apex/com.android.art/lib64/libart.so (art::detail::ShortyTraits<(char)86>::Type art::ArtMethod::InvokeInstance<(char)86>(art::Thread*, art::ObjPtr<art::mirror::Object>, art::detail::ShortyTraits<>::Type...)+60) (BuildId: 4ccb65ae9ac5ad5da3af5a342d5b0b92) 08-19 09:27:02.621 17868 17868 F DEBUG : #17 pc 0000000000636e80 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback(void*)+1344) (BuildId: 4ccb65ae9ac5ad5da3af5a342d5b0b92) 08-19 09:27:02.621 17868 17868 F DEBUG : #18 pc 0000000000636930 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallbackWithUffdGc(void*)+8) (BuildId: 4ccb65ae9ac5ad5da3af5a342d5b0b92) 08-19 09:27:02.621 17868 17868 F DEBUG : #19 pc 00000000000a67a4 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+196) (BuildId: b963824e1119e1e9ec07440f1ee81f14) 08-19 09:27:02.621 17868 17868 F DEBUG : #20 pc 0000000000097b20 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: b963824e1119e1e9ec07440f1ee81f14) android日志: 行 236711: 08-19 09:27:02.215 13888 13888 V OCAM_PreviewExceptionProcessor: prePostPreviewException delay: 5000 行 236711: 08-19 09:27:02.215 13888 13888 V OCAM_PreviewExceptionProcessor: prePostPreviewException delay: 5000 行 237467: 08-19 09:27:02.326 13888 14751 E CameraUnit, Camera2Impl: checkSmaWireStatusAndModuleIdArrived, key does not exist: java.lang.IllegalArgumentException: Could not find tag for key 'com.oplus.double.ois.wirecutoff.detection.sn') 行 238996: 08-19 09:27:02.716 18002 18002 D AEE_AED : Duplicated exception, cnt = 2 行 238997: 08-19 09:27:02.716 18002 18002 D AEE_AED : Last exception time: 1755541196 行 239224: 08-19 09:27:02.749 18002 18002 I AEE_AED : $** *** *** *** *** *** *** *** Exception *** *** *** *** *** *** *** **$ 行 239854: 08-19 09:27:02.888 01383 18049 E ifunc_camsv: [vendor/mediatek/proprietary/hardware/mtkcam/drv/src/isp/isp_6s/imageio/drv/cam/isp_function_camsv.cpp, waitBufReady, line1155] ERROR: [0x9]:, m_buf_cnt(0), waitbufready fail is caused by no enque (waitBufReady){#1155:vendor/mediatek/proprietary/hardware/mtkcam/drv/src/isp/isp_6s/imageio/drv/cam/isp_function_camsv.cpp} 行 240135: 08-19 09:27:02.985 18002 18002 I AEE_AED : Exception Log Time:[Tue Aug 19 09:27:02 CST 2025] [70030.923036] 行 240137: 08-19 09:27:02.985 18002 18002 I AEE_AED : Exception Class: Native (NE) 行 240138: 08-19 09:27:02.985 18002 18002 I AEE_AED : Exception Type: SIGSEGV 行 240145: 08-19 09:27:02.986 18002 18002 I AEE_AED : $** *** *** *** *** *** *** *** Exception *** *** *** *** *** *** *** **$ 行 240337: 08-19 09:27:03.083 01733 18054 W AES : Exception Log handling... 行 240370: 08-19 09:27:03.088 01733 18054 D AES : ExceptionLog: notify aed, process:com.oplus.camera pid:13888 cause:system_app_native_crash 行 240524: 08-19 09:27:03.109 13888 14798 V OCAM_PreviewExceptionProcessor: removePreviewException 行 240524: 08-19 09:27:03.109 13888 14798 V OCAM_PreviewExceptionProcessor: removePreviewException 行 240884: 08-19 09:27:03.252 01733 01883 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 241592: 08-19 09:27:03.623 13888 13888 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 241637: 08-19 09:27:03.631 02552 02552 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 241757: 08-19 09:27:03.695 01383 18049 E ifunc_camsv: [vendor/mediatek/proprietary/hardware/mtkcam/drv/src/isp/isp_6s/imageio/drv/cam/isp_function_camsv.cpp, waitBufReady, line1155] ERROR: [0x9]:, m_buf_cnt(0), waitbufready fail is caused by no enque (waitBufReady){#1155:vendor/mediatek/proprietary/hardware/mtkcam/drv/src/isp/isp_6s/imageio/drv/cam/isp_function_camsv.cpp} 行 241785: 08-19 09:27:03.696 13888 13888 V OCAM_PreviewExceptionProcessor: removePreviewException 行 241785: 08-19 09:27:03.696 13888 13888 V OCAM_PreviewExceptionProcessor: removePreviewException 行 242241: 08-19 09:27:03.765 15375 15375 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 242466: 08-19 09:27:03.821 01733 01887 D callGcDesupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 242477: 08-19 09:27:03.824 02276 02276 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 243654: 08-19 09:27:04.292 15375 15375 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 243662: 08-19 09:27:04.298 02276 02276 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 243671: 08-19 09:27:04.307 13888 13888 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 243692: 08-19 09:27:04.322 02552 02552 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 243871: 08-19 09:27:04.443 02552 02552 D OplusGcSupressionExtImpl: callGcSupression : java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 243902: 08-19 09:27:04.451 02552 02552 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 243912: 08-19 09:27:04.452 02552 02552 D OplusGcSupressionExtImpl: callGcDesupression : java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 244302: 08-19 09:27:04.713 18094 18094 D OplusActivityThreadExtImpl: java.lang.NoSuchMethodException: dalvik.system.VMRuntime.SupressionGC [int, int] 行 244306: zv69jrUu7c:0 android.view.InsetsAnimationThreadControlRunner$1$$ExternalSyntheticLambda1.run:0 android.os.Handler.handleCallback:995 android.os.Handler.dispatchMessage:105 android.os.Looper.loopOnce:288 android.os.Looper.loop:393 com.android.launcher.monitor.exception.MainThreadExceptionMonitor.startWatching$lambda$2:15 com.android.launcher.monitor.exception.MainThreadExceptionMonitor.gda:1 行 244306: .view.InsetsAnimationThreadControlRunner$1$$ExternalSyntheticLambda1.run:0 android.os.Handler.handleCallback:995 android.os.Handler.dispatchMessage:105 android.os.Looper.loopOnce:288 android.os.Looper.loop:393 com.android.launcher.monitor.exception.MainThreadExceptionMonitor.startWatching$lambda$2:15 com.android.launcher.monitor.exception.MainThreadExceptionMonitor.gda:1 行 244306: :0 android.os.Handler.handleCallback:995 android.os.Handler.dispatchMessage:105 android.os.Looper.loopOnce:288 android.os.Looper.loop:393 com.android.launcher.monitor.exception.MainThreadExceptionMonitor.startWatching$lambda$2:15 com.android.launcher.monitor.exception.MainThreadExceptionMonitor.gda:1 行 244306: r.handleCallback:995 android.os.Handler.dispatchMessage:105 android.os.Looper.loopOnce:288 android.os.Looper.loop:393 com.android.launcher.monitor.exception.MainThreadExceptionMonitor.startWatching$lambda$2:15 com.android.launcher.monitor.exception.MainThreadExceptionMonitor.gda:1 行 244340: 08-19 09:27:04.769 13888 13888 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 244363: 08-19 09:27:04.784 18094 18110 D OplusAppHeapManager: java.lang.NoSuchMethodException: dalvik.system.VMRuntime.updateProcessValue [int, int, int] 行 244409: 08-19 09:27:04.800 18094 18094 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 请排查问题
09-05
const JavaMap = java.util.HashMap; const globalMapSymbol = Symbol("globalMap"); const mapSymbol = Symbol("myJavaMap"); const selfSymbol = Symbol("selfKey"); function getTypeName(obj) { return Object.prototype.toString.call(obj); } const protoDic = new Map([ ["[object Array]", Array], ["[object Date]", Date], ["[object Object]", Object], ["[object Promise]", Promise], ["[object Map]", Map], ["[object Symbol]", Symbol], ["[object Array]", Array], ["[object Function]", Function], ["Error", Error], ["TypeError", TypeError], ["EvalError", EvalError], ["SyntaxError", SyntaxError], ["ReferenceError", ReferenceError], ["RangeError", RangeError] ]); function dealWithVal(val) { let typeName = getTypeName(val); let errorName; if (val instanceof java.lang.String) { return String(val); } else if (val instanceof java.lang.Double) { return Number(val); } else if (val instanceof java.lang.Boolean) { if (String(val) === "true") { val = true; } else { val = false; } return val; } else if (typeName === "[object Error]" && protoDic.has((errorName = val.toString()))) { val.__proto__ = val.__proto__ && Object.assign(Object.create(protoDic.get(typeName).prototype), val.__proto__); return val; } else if (typeName !== "[object javaObject]" && protoDic.has(typeName)) { val.__proto__ = val.__proto__ && Object.assign(Object.create(protoDic.get(typeName).prototype), val.__proto__); return val; } return val; } function isString(str) { return typeof(str) === "string" || str instanceof java.lang.String; } function GlobalVar(javaMap, selfKey) { this[globalMapSymbol] = javaMap; this[selfSymbol] = selfKey; this.raw = false; } Object.assign(GlobalVar.prototype, { getHashMap(symbol) { if (symbol !== mapSymbol) return null; if (this[mapSymbol]) return this[mapSymbol]; let selfKey = this[selfSymbol]; if (!selfKey) { throw Error("当前没有全局环境,请使用setSelfKey指定规则名"); } this[mapSymbol] = this[globalMapSymbol]; return this[mapSymbol]; }, setSelfKey(key) { //if (!this[selfSymbol]) this[selfSymbol] = key; this[selfSymbol] = key; }, getSelfKey(){ return this[selfSymbol]; }, getMapKey(key) { return String(this[selfSymbol] + key); }, get(key, def) { key = this.getMapKey(key); let hashMap = this.getHashMap(mapSymbol); if (!hashMap.containsKey(key)) return def; let val = hashMap.get(key); if (this.raw) { return val; } else { return dealWithVal(val); } }, getRaw(key, def) { key = this.getMapKey(key); let hashMap = this.getHashMap(mapSymbol); if (!hashMap.containsKey(key)) return def; return hashMap.get(key); }, useRaw(noUseRaw) { this.raw = !noUseRaw; return this; }, put(key, val) { if (val === void 0) return; let hashMap = this.getHashMap(mapSymbol); hashMap.put(this.getMapKey(key), val); return val; }, clearAll() { let self = this[selfSymbol]; let hashMap = this.getHashMap(mapSymbol); this.getHashMap(mapSymbol).forEach((key, value) => { if (isString(key) && String(key).startsWith(self)) { hashMap.remove(key); } }); }, clear(key, call) { if (this.hasButNoCall(key)) { let hashMap = this.getHashMap(mapSymbol); if (typeof call === "function") { call(this.get(key)); } hashMap.remove(this.getMapKey(key)); } }, has(key, call) { let mapKey = this.getMapKey(key); let hashMap = this.getHashMap(mapSymbol); let res = !!hashMap.containsKey(mapKey); if (res && typeof call === "function") { call(this.get(key)); } return res; }, hasButNoCall(key) { let mapKey = this.getMapKey(key); let hashMap = this.getHashMap(mapSymbol); return !!hashMap.containsKey(mapKey); }, define(key, val) { if (this.hasButNoCall(key)) { return this.get(key); } return this.put(key, val); }, defineLazy(key, lazy) { if (this.hasButNoCall(key)) { return this.get(key); } return this.put(key, lazy()); }, defineModule(key, path, isNew) { if(path===undefined){ path=key; } if (isNew) return this.put(key, $.require(path, key)); return this.defineLazy(key, () => $.require(path, key)); }, listKeys() { let entrySet = this.getHashMap(mapSymbol).entrySet(); let selfKey = this[selfSymbol]; let keys = []; for (let entry of entrySet) { let key = entry.getKey(); if (isString(key) && key.startsWith(selfKey)) { keys.push(String(key).replace(selfKey, "")); } } return keys; }, toJSON() { let object = {}; let hashMap = this.getHashMap(mapSymbol); let selfKey = this[selfSymbol]; hashMap.forEach((key, value) => { if (!isString(key)) { return; } let keyString = String(key); if (keyString.startsWith(selfKey)) { object[keyString.replace(selfKey, "")] = hashMap.get(key); } }); return object; } }); GlobalVar.prototype[Symbol.iterator] = function() { let hashMap = this.getHashMap(mapSymbol); let selfKey = this[selfSymbol]; let iterator = hashMap.entrySet().iterator(); return (function*() { while (iterator.hasNext()) { let me = iterator.next(); let key = me.getKey(); if (!isString(key)) { continue; } key = String(key); if (key.startsWith(selfKey)) { yield [key.replace(selfKey, ""), dealWithVal(me.getValue())]; } } })(); } const GlobalMap = _globalMap; //_globalMap = void 0; let RuleGlobalMapKey = (typeof MY_RULE !== "undefined"&&MY_RULE) ? MY_RULE.title : ""; let AppGlobalMapKey = "AppGlobalMap"; if (RuleGlobalMapKey === AppGlobalMapKey) { let randomKey = ""; if (GlobalMap.containsKey(0)) { randomKey = String(GlobalMap.get(0)); } else { randomKey = String(Date.now()); GlobalMap.put(0, randomKey); } RuleGlobalMapKey = RuleGlobalMapKey + randomKey; } $.exports = { GA: new GlobalVar(GlobalMap, AppGlobalMapKey), GM: new GlobalVar(GlobalMap, RuleGlobalMapKey) } 分析 JavaException: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Object.hashCode()' on a null object reference
最新发布
11-20
package com.example.kucun2.entity; import android.annotation.SuppressLint; import com.example.kucun2.entity.data.EntityClassGrassrootsid; import com.example.kucun2.entity.data.SynchronizableEntity; import java.util.Collections; import java.util.Map; import java.util.Objects; //板材 public class Bancai extends SynchronizableEntity implements EntityClassGrassrootsid { private Integer id; private Caizhi caizhi; private Mupi mupi1; private Mupi mupi2; private Double houdu; private Dingdan_chanpin_zujian Dingdan_chanpin_zujian; public Bancai() { } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Bancai bancai = (Bancai) o; return Objects.equals(id, bancai.id) && Objects.equals(caizhi, bancai.caizhi) && Objects.equals(mupi1, bancai.mupi1) && Objects.equals(mupi2, bancai.mupi2) && Objects.equals(houdu, bancai.houdu); } @Override public int hashCode() { return Objects.hash(id, caizhi, mupi1, mupi2, houdu); } public Bancai(Integer id, Caizhi caizhi, Mupi mupi1, Mupi mupi2, Double houdu) { this.id = id; this.caizhi = caizhi; this.mupi1 = mupi1; this.mupi2 = mupi2; this.houdu = houdu; } @Override public Integer getId() { return id; } public void setId(Integer id) { Integer oldValue = this.id; this.id = id; firePropertyChange("id", oldValue, id); } public Caizhi getCaizhi() { return caizhi; } public void setCaizhi(Caizhi caizhi) { Caizhi oldValue = this.caizhi; this.caizhi = caizhi; firePropertyChange("caizhi", oldValue, caizhi); } public Mupi getMupi1() { return mupi1; } public void setMupi1(Mupi mupi1) { Mupi oldValue = this.mupi1; this.mupi1 = mupi1; firePropertyChange("mupi1", oldValue, mupi1); } public Mupi getMupi2() { return mupi2; } public void setMupi2(Mupi mupi2) { Mupi oldValue = this.mupi2; this.mupi2 = mupi2; firePropertyChange("mupi2", oldValue, mupi2); } public Double getHoudu() { return houdu; } public void setHoudu(Double houdu) { Double oldValue = this.houdu; this.houdu = houdu; firePropertyChange("houdu", oldValue, houdu); } /** * 表格中显示的文字 * @return */ @SuppressLint("DefaultLocale") public String TableText(){ String boardInfo=""; boardInfo +=String.format("%.1f", this.getHoudu())+this.getCaizhi().getName()+"("; if (mupi1 != null) { boardInfo += (this.getMupi1().getYou()?this.getMupi1().getName()+"油":this.getMupi1().getName()); } if (mupi2 != null&&mupi1 != null) { boardInfo+=","; } if (mupi2 != null) { boardInfo += (this.getMupi2().getYou()?this.getMupi2().getName()+"油":this.getMupi2().getName()); } boardInfo+=")"; return boardInfo; } public com.example.kucun2.entity.Dingdan_chanpin_zujian getDingdan_chanpin_zujian() { return Dingdan_chanpin_zujian; } public void setDingdan_chanpin_zujian(com.example.kucun2.entity.Dingdan_chanpin_zujian dingdan_chanpin_zujian) { com.example.kucun2.entity.Dingdan_chanpin_zujian oldValue = this.Dingdan_chanpin_zujian; Dingdan_chanpin_zujian = dingdan_chanpin_zujian; firePropertyChange("dingdan_chanpin_zujian", oldValue, dingdan_chanpin_zujian); } } I Displayed com.example.kucun2/.MainActivity for user 0: +435ms 2025-06-12 01:34:05.700 27173-27173 AndroidRuntime com.example.kucun2 E FATAL EXCEPTION: main Process: com.example.kucun2, PID: 27173 java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference at com.example.kucun2.entity.Bancai.TableText(Bancai.java:109) at com.example.kucun2.function.Adapter$3.formatDisplayText(Adapter.java:93) at com.example.kucun2.function.Adapter$3.formatDisplayText(Adapter.java:90) at com.example.kucun2.function.Adapter$SafeSpinnerAdapter.getView(Adapter.java:42) at android.widget.Spinner.measureContentWidth(Spinner.java:892) at android.widget.Spinner.onMeasure(Spinner.java:626) at androidx.appcompat.widget.AppCompatSpinner.onMeasure(AppCompatSpinner.java:444) at android.view.View.measure(View.java:29007) at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7132)package com.example.kucun2.entity; import android.annotation.SuppressLint; import com.example.kucun2.entity.data.EntityClassGrassrootsid; import com.example.kucun2.entity.data.SynchronizableEntity; import java.util.ArrayList; import java.util.List; public class Mupi extends SynchronizableEntity implements EntityClassGrassrootsid { private Integer id; private String name; /** * 是否有油漆 */ private Boolean you=false; private List<Bancai> bancais=new ArrayList<>(); @Override public Integer getId() { return id; } public void setId(Integer id) { Integer oldValue = this.id; this.id = id; firePropertyChange("id", oldValue, id); } public String getName() { return name; } public void setName(String name) { String oldValue = this.name; this.name = name; firePropertyChange("name", oldValue, name); } public Boolean getYou() { return you; } public void setYou(Boolean you) { Boolean oldValue = this.you; this.you = you; firePropertyChange("you", oldValue, you); } public List<Bancai> getBancais() { return bancais; } public void setBancais(List<Bancai> bancais) { List<Bancai> oldValue = this.bancais; this.bancais = bancais; firePropertyChange("bancais", oldValue, bancais); } public Mupi() { } public Mupi(Integer id, String name, List<Bancai> bancais) { this.id = id; this.name = name; this.bancais = bancais; } public Mupi(List<Bancai> bancais, Boolean you, String name, Integer id) { this.bancais = bancais; this.you = you; this.name = name; this.id = id; } // 3. 木皮显示格式化方法 public String formatMupiDisplay() { return getName() + (getYou() ? "油" : ""); } }
06-13
package com.example.kucun2.ui.dingdan;//package com.example.kucun2; import static android.content.ContentValues.TAG; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; import android.app.AlertDialog; import android.content.Context; import android.graphics.Color; import android.graphics.Typeface; import android.os.Bundle; import android.util.Log; import android.util.TypedValue; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.FrameLayout; import android.widget.HorizontalScrollView; import android.widget.LinearLayout; import android.widget.PopupMenu; import android.widget.SearchView; import android.widget.Spinner; import android.widget.TableLayout; import android.widget.TableRow; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; import androidx.fragment.app.Fragment; import com.example.kucun2.MainActivity; import com.example.kucun2.R; import com.example.kucun2.View.HorizontalScrollTextView; import com.example.kucun2.entity.Bancai; import com.example.kucun2.entity.Chanpin; import com.example.kucun2.entity.Chanpin_Zujian; import com.example.kucun2.entity.Dingdan; import com.example.kucun2.entity.Dingdan_chanpin_zujian; import com.example.kucun2.entity.Dingdan_Chanpin; import com.example.kucun2.entity.data.Data; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; public class OrderDisplayFragment extends Fragment { private TableLayout table; private HorizontalScrollView horizontalScrollView; private ValueAnimator scrollIndicatorAnimator; private boolean isIndicatorVisible = false; // 添加排序相关的成员变量 private int currentSortColumn = -1; private boolean sortAscending = true; private List<Object[]> allTableRowsData = new ArrayList<>(); // 添加搜索相关成员变量 private SearchView searchView; private Spinner columnSelector; private List<Object[]> filteredTableRowsData = new ArrayList<>(); private boolean isDataLoaded = false; /** * 加载初始化 * * @param inflater The LayoutInflater object that can be used to inflate * any views in the fragment, * @param container If non-null, this is the parent view that the fragment's * UI should be attached to. The fragment should not add the view itself, * but this can be used to generate the LayoutParams of the view. * @param savedInstanceState If non-null, this fragment is being re-constructed * from a previous saved state as given here. * @return */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_order_display, container, false); table = view.findViewById(R.id.orderTable); horizontalScrollView = view.findViewById(R.id.horizontalScrollContainer); View scrollIndicator = view.findViewById(R.id.scroll_indicator); // 获取搜索控件 searchView = view.findViewById(R.id.search_view); columnSelector = view.findViewById(R.id.column_selector); // 初始化表头选择器 initColumnSelector(); // 设置搜索监听 searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String query) { applySearchFilter(); return true; } @Override public boolean onQueryTextChange(String newText) { applySearchFilter(); return true; } }); LinearLayout fixedSearchBar = view.findViewById(R.id.fixedSearchBar); View placeholder = view.findViewById(R.id.search_bar_placeholder); // 添加全局布局监听器以获取正确的搜索框高度 fixedSearchBar.getViewTreeObserver().addOnGlobalLayoutListener( new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // 获取搜索框的实际高度 int searchBarHeight = fixedSearchBar.getHeight(); // 设置占位视图的高度 ViewGroup.LayoutParams params = placeholder.getLayoutParams(); params.height = searchBarHeight; placeholder.setLayoutParams(params); // 确保仅运行一次 fixedSearchBar.getViewTreeObserver().removeOnGlobalLayoutListener(this); } } ); Log.d(TAG, "onCreateView: " + Data.dingdans.get(0).getNumber()); // 添加表头 addTableHeader(table); // 检查数据是否已加载 if (Data.dingdans.isEmpty()) { // 显示加载指示器 showLoadingIndicator(); // 设置数据加载监听器 if (getActivity() instanceof MainActivity) { ((MainActivity) getActivity()).setOnDataLoadListener(new MainActivity.OnDataLoadListener() { @Override public void onDataLoaded() { requireActivity().runOnUiThread(() -> { hideLoadingIndicator(); isDataLoaded = true; fillTableData(); // 填充数据 }); } @Override public void onDataError() { requireActivity().runOnUiThread(() -> { hideLoadingIndicator(); Toast.makeText(getContext(), "检查网络", Toast.LENGTH_SHORT).show(); //showError("数据加载失败"); }); } }); } } else { // 数据已加载,直接填充 fillTableData(); isDataLoaded = true; } // 填充表格数据 // fillTableData(); // 添加滚动监听 horizontalScrollView.getViewTreeObserver().addOnScrollChangedListener(() -> { int maxScroll = horizontalScrollView.getChildAt(0).getWidth() - horizontalScrollView.getWidth(); int currentScroll = horizontalScrollView.getScrollX(); if (currentScroll > 0 && maxScroll > 0) { if (!isIndicatorVisible) { showScrollIndicator(); } // 更新滚动指示器位置 updateScrollIndicatorPosition(currentScroll, maxScroll); } else { hideScrollIndicator(); } }); return view; } // 显示/隐藏加载指示器的方法 private void showLoadingIndicator() { // 实现加载动画或进度条 } private void hideLoadingIndicator() { // 隐藏加载指示器 } @Override public void onAttach(@NonNull Context context) { super.onAttach(context); if (context instanceof MainActivity) { ((MainActivity) context).setOnDataLoadListener(new MainActivity.OnDataLoadListener() { @Override public void onDataLoaded() { // 数据加载完成后填充表格 getActivity().runOnUiThread(() -> { Log.d("DataLoad", "Data loaded, filling table"); fillTableData(); }); } @Override public void onDataError() { //showToast("数据加载失败"); } }); } } /** * 获取数据 */ private void fillTableData() { List<Dingdan> orders = Data.dingdans; List<Dingdan_Chanpin> orderProducts = Data.dingdan_chanpins; List<Dingdan_chanpin_zujian> orderMaterials = Data.Dingdan_chanpin_zujians; allTableRowsData.clear(); filteredTableRowsData.clear(); // 创建映射关系提高效率 Map<Integer, List<Dingdan_Chanpin>> orderProductMap = new HashMap<>(); Map<Integer, List<Chanpin_Zujian>> productComponentMap = new HashMap<>(); Map<Integer, List<Dingdan_chanpin_zujian>> componentMaterialMap = new HashMap<>(); // 构建映射 for (Dingdan_Chanpin op : orderProducts) { if (op != null && op.getDingdan() != null) { int orderId = op.getDingdan().getId(); orderProductMap.computeIfAbsent(orderId, k -> new ArrayList<>()).add(op); } } for (Chanpin_Zujian cz : Data.chanpin_zujians) { int productId = cz.getChanpin().getId(); productComponentMap.computeIfAbsent(productId, k -> new ArrayList<>()).add(cz); } for (Dingdan_chanpin_zujian dm : orderMaterials) { int componentId = dm.getZujian().getId(); componentMaterialMap.computeIfAbsent(componentId, k -> new ArrayList<>()).add(dm); } // 重组数据 for (Dingdan order : orders) { List<Dingdan_Chanpin> productsForOrder = orderProductMap.get(order.getId()); if (productsForOrder != null) { for (Dingdan_Chanpin op : productsForOrder) { Chanpin product = op.getChanpin(); List<Chanpin_Zujian> componentsForProduct = productComponentMap.get(product.getId()); if (componentsForProduct != null) { for (Chanpin_Zujian cz : componentsForProduct) { List<Dingdan_chanpin_zujian> materialsForComponent = componentMaterialMap.get(cz.getZujian().getId()); if (materialsForComponent != null) { for (Dingdan_chanpin_zujian dm : materialsForComponent) { Object[] rowData = createRowData(order, product, op, cz, dm); allTableRowsData.add(rowData); filteredTableRowsData.add(rowData); } } } } } } } // 日志记录添加行数 Log.d("TableFill", "Total rows created: " + allTableRowsData.size()); // 初始排序 sortTableData(-1, true); } /** * 排序表格数据并刷新显示 * * @param columnIndex 要排序的列索引 * @param ascending 是否升序排列 */ private void sortTableData(int columnIndex, boolean ascending) { // 更新排序状态 if (columnIndex >= 0) { if (currentSortColumn == columnIndex) { // 相同列点击时切换排序方向 sortAscending = !ascending; } else { currentSortColumn = columnIndex; sortAscending = true; // 新列默认升序 } } // 创建排序比较器 Comparator<Object[]> comparator = (row1, row2) -> { if (currentSortColumn < 0) { return 0; // 返回0表示相等,保持原顺序 } Object value1 = row1[currentSortColumn]; Object value2 = row2[currentSortColumn]; if (value1 == null && value2 == null) return 0; if (value1 == null) return -1; if (value2 == null) return 1; // 根据不同列数据类型定制比较规则 try { // 数值列:2(数量), 5(板材/组件), 6(订购数量) if (currentSortColumn == 2 || currentSortColumn == 5 || currentSortColumn == 6) { double d1 = Double.parseDouble(value1.toString()); double d2 = Double.parseDouble(value2.toString()); return sortAscending ? Double.compare(d1, d2) : Double.compare(d2, d1); } // 其他列按字符串排序 else { String s1 = value1.toString().toLowerCase(); String s2 = value2.toString().toLowerCase(); return sortAscending ? s1.compareTo(s2) : s2.compareTo(s1); } } catch (NumberFormatException e) { // 解析失败时按字符串比较 String s1 = value1.toString().toLowerCase(); String s2 = value2.toString().toLowerCase(); return sortAscending ? s1.compareTo(s2) : s2.compareTo(s1); } }; // 特殊处理初始未排序状态 if (columnIndex == -1) { // 直接复制数据而不排序 filteredTableRowsData.clear(); filteredTableRowsData.addAll(allTableRowsData); } else { Collections.sort(filteredTableRowsData, comparator); } // 刷新显示 refreshTableWithData(filteredTableRowsData); } /** * 表格数据动态添加 * * @param rowData */ private void addTableRow(Object[] rowData) { TableRow row = new TableRow(requireContext()); TableLayout.LayoutParams rowParams = new TableLayout.LayoutParams( TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT ); row.setLayoutParams(rowParams); row.setMinimumHeight(dpToPx(36)); for (int i = 0; i < rowData.length; i++) { final Object data = rowData[i]; // 判断是否为操作列(最后一列) if (i == rowData.length - 1) { // 创建操作按钮 Button actionButton = new Button(requireContext()); actionButton.setText("操作"); actionButton.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14); actionButton.setBackgroundResource(R.drawable.btn_selector); // 自定义按钮样式 // 设置按钮点击监听器 actionButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { handleRowAction(rowData, v); } }); // 设置按钮布局参数 TableRow.LayoutParams btnParams = new TableRow.LayoutParams( 0, // 宽度由权重控制 TableRow.LayoutParams.WRAP_CONTENT, 0.5f ); btnParams.weight = 0.5f; int margin = dpToPx(1); btnParams.setMargins(margin, margin, margin, margin); actionButton.setLayoutParams(btnParams); actionButton.setHeight(11); row.addView(actionButton); } else { // 正常文本列的代码(保持原逻辑) HorizontalScrollTextView textView = new HorizontalScrollTextView(requireContext()); textView.setText(String.valueOf(data)); textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14); int padding = dpToPx(8); textView.setPadding(padding, padding / 2, padding, padding); textView.setMinWidth(dpToPx(50)); TableRow.LayoutParams colParams = null; // 设置背景边框 textView.setBackgroundResource(R.drawable.cell_border); if (data.toString().length() > 10) { colParams = new TableRow.LayoutParams( 0, // 宽度将由权重控制 TableRow.LayoutParams.MATCH_PARENT, 2.0f ); colParams.weight = 2; } else { colParams = new TableRow.LayoutParams( 0, // 宽度将由权重控制 TableRow.LayoutParams.MATCH_PARENT, 1.0f ); colParams.weight = 1; } textView.setLayoutParams(colParams); row.addView(textView); } } table.addView(row); } // 动态添加表头 (使用自定义TextView) private void addTableHeader(TableLayout table) { TableRow headerRow = new TableRow(requireContext()); headerRow.setLayoutParams(new TableLayout.LayoutParams( TableLayout.LayoutParams.MATCH_PARENT, TableLayout.LayoutParams.WRAP_CONTENT )); // 设置行背景颜色 headerRow.setBackgroundColor(ContextCompat.getColor(requireContext(), R.color.purple_500)); // 定义表头 // 更新表头数组(添加操作列) String[] headers = getResources().getStringArray(R.array.table_headers); List<String> headerList = new ArrayList<>(Arrays.asList(headers)); headerList.add("操作"); // 添加操作列标题 headers = headerList.toArray(new String[0]); // 更新权重数组(添加操作列权重) float[] weights = {1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 1.0f, 1.0f, 0.5f}; // 新增操作列权重0.5 // 更新优先级数组(添加操作列优先级) boolean[] priority = {false, false, false, false, true, false, false, false}; for (int i = 0; i < headers.length; i++) { HorizontalScrollTextView headerView = new HorizontalScrollTextView(requireContext()); headerView.setText(headers[i]); headerView.setTextColor(Color.WHITE); headerView.setTypeface(null, Typeface.BOLD); headerView.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16); headerView.setPadding(dpToPx(8), dpToPx(8), dpToPx(8), dpToPx(8)); // 为优先级高的列设置最小宽度 if (priority[i]) { headerView.setMinWidth(dpToPx(220)); } // 设置布局参数 TableRow.LayoutParams colParams = new TableRow.LayoutParams( priority[i] ? TableRow.LayoutParams.WRAP_CONTENT : 0, TableRow.LayoutParams.MATCH_PARENT, priority[i] ? 0 : weights[i] // 优先级列不使用权重 ); headerView.setLayoutParams(colParams); final int columnIndex = i; headerView.setOnClickListener(v -> { // 排序并刷新表格 sortTableData(columnIndex, sortAscending); // 更新排序指示器(可选) showSortIndicator(headerView); }); headerRow.addView(headerView); } table.addView(headerRow); } // 添加排序指示器(可选) private void showSortIndicator(View header) { // 实现:在表头右侧添加↑或↓指示符 // 实现逻辑根据设计需求 // header.setTooltipText(new ); } /** * */ private void showScrollIndicator() { isIndicatorVisible = true; View indicator = getView().findViewById(R.id.scroll_indicator); if (scrollIndicatorAnimator != null && scrollIndicatorAnimator.isRunning()) { scrollIndicatorAnimator.cancel(); } indicator.setVisibility(View.VISIBLE); indicator.setAlpha(0f); scrollIndicatorAnimator = ObjectAnimator.ofFloat(indicator, "alpha", 0f, 0.8f); scrollIndicatorAnimator.setDuration(300); scrollIndicatorAnimator.start(); } /** * + */ private void hideScrollIndicator() { isIndicatorVisible = false; View indicator = getView().findViewById(R.id.scroll_indicator); if (scrollIndicatorAnimator != null && scrollIndicatorAnimator.isRunning()) { scrollIndicatorAnimator.cancel(); } scrollIndicatorAnimator = ObjectAnimator.ofFloat(indicator, "alpha", indicator.getAlpha(), 0f); scrollIndicatorAnimator.setDuration(300); scrollIndicatorAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { indicator.setVisibility(View.INVISIBLE); } }); scrollIndicatorAnimator.start(); } /** * @param currentScroll * @param maxScroll */ private void updateScrollIndicatorPosition(int currentScroll, int maxScroll) { View indicator = getView().findViewById(R.id.scroll_indicator); FrameLayout.LayoutParams params = (FrameLayout.LayoutParams) indicator.getLayoutParams(); // 计算指示器位置(0-100%) float percentage = (float) currentScroll / maxScroll; int maxMargin = getResources().getDisplayMetrics().widthPixels - indicator.getWidth(); // 设置右边距(控制位置) params.rightMargin = (int) (maxMargin * percentage); indicator.setLayoutParams(params); } // 处理行操作的方法 private void handleRowAction(Object[] rowData, View anchorButton) { // 安全地从行数据中提取关键信息 String orderNumber = safeGetString(rowData[0]); // 订单号 String productId = safeGetString(rowData[1]); // 产品ID String componentName = safeGetString(rowData[3]); // 组件名称 // 安全地获取订购数量 double materialQuantity = 0.0; try { if (rowData[6] != null) { if (rowData[6] instanceof Number) { materialQuantity = ((Number) rowData[6]).doubleValue(); } else { materialQuantity = Double.parseDouble(rowData[6].toString()); } } } catch (Exception e) { Log.e("OrderFragment", "Failed to parse material quantity", e); } Context context = getContext(); if (context == null || anchorButton == null) { Log.w("PopupMenu", "Context or anchorButton is null"); return; } PopupMenu popupMenu = new PopupMenu(context, anchorButton); // 强制设置菜单在锚点视图下方显示(关键设置) popupMenu.setGravity(Gravity.BOTTOM); // 如果使用支持库,设置弹出方向 // 设置在锚点视图下方显示 // popupMenu.setOverlapAnchor(true); // 填充菜单项 popupMenu.getMenuInflater().inflate(R.menu.row_actions_menu, popupMenu.getMenu()); // 设置菜单项点击监听器 popupMenu.setOnMenuItemClickListener(item -> { int itemId = item.getItemId(); if (itemId == R.id.action_view_details) { showDetailDialog(orderNumber, productId); return true; } else if (itemId == R.id.action_edit) { editRowData(rowData); return true; } else if (itemId == R.id.action_delete) { deleteRowWithConfirm(rowData); return true; } return false; }); popupMenu.show(); } // 安全获取字符串值的方法 private String safeGetString(Object value) { if (value == null) return ""; if (value instanceof String) return (String) value; return value.toString(); } // 查看详情对话框 private void showDetailDialog(String orderNumber, String productId) { AlertDialog.Builder builder = new AlertDialog.Builder(requireContext()); builder.setTitle("订单详情") .setMessage("订单号: " + orderNumber + "\n产品ID: " + productId) .setPositiveButton("确定", null) .show(); } // 编辑行数据 private void editRowData(Object[] rowData) { // 实现编辑逻辑 // 这里创建包含表单的对话框 Toast.makeText(requireContext(), "编辑操作: " + rowData[0], Toast.LENGTH_SHORT).show(); } // 带确认的删除操作 private void deleteRowWithConfirm(Object[] rowData) { new AlertDialog.Builder(requireContext()) .setTitle("确认删除") .setMessage("确定要删除订单 " + rowData[0] + " 吗?") .setPositiveButton("删除", (dialog, which) -> { // 实际删除逻辑 deleteRow(rowData); }) .setNegativeButton("取消", null) .show(); } // 实际删除行数据 private void deleteRow(Object[] rowData) { // 1. 从allTableRowsData中移除对应行 for (Iterator<Object[]> iterator = allTableRowsData.iterator(); iterator.hasNext(); ) { Object[] row = iterator.next(); if (Arrays.equals(row, rowData)) { iterator.remove(); break; } } // 2. 从filteredTableRowsData中移除 filteredTableRowsData.removeIf(row -> Arrays.equals(row, rowData)); // 3. 刷新表格 refreshTableWithData(filteredTableRowsData); Toast.makeText(requireContext(), "已删除订单", Toast.LENGTH_SHORT).show(); } // DP转PX工具方法 private int dpToPx(int dp) { return (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, dp, getResources().getDisplayMetrics() ); } /** * 数据组合 * * @param order * @param product * @param component * @param material * @return */ private Object[] createRowData(Dingdan order, Chanpin product, Dingdan_Chanpin dingdan_chanpin, Chanpin_Zujian component, Dingdan_chanpin_zujian material) { Bancai board = material.getBancai(); String boardInfo = board.TableText(); ; return new Object[]{ order.getNumber(), // 订单号 product.getBianhao(), // 产品编号 dingdan_chanpin.getShuliang(), // 产品数量 (根据需求调整) component.getZujian().getName(), // 组件名 boardInfo, // 板材信息 Math.round(component.getOne_howmany()), // 板材/组件 material.getShuliang(), // 订购数量 "操作" }; } // 初始化列选择器 private void initColumnSelector() { ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource( requireContext(), R.array.table_headers, android.R.layout.simple_spinner_item ); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); columnSelector.setAdapter(adapter); // 添加"所有列"选项 columnSelector.setSelection(0); // 默认选择第一个选项(所有列) // 列选择变化监听 columnSelector.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { applySearchFilter(); } @Override public void onNothingSelected(AdapterView<?> parent) { } }); } // 应用搜索过滤 private void applySearchFilter() { String query = searchView.getQuery().toString().trim().toLowerCase(); int selectedColumn = columnSelector.getSelectedItemPosition(); filteredTableRowsData.clear(); if (query.isEmpty()) { // 没有搜索词,显示所有数据 filteredTableRowsData.addAll(allTableRowsData); } else { // 根据选择的列进行过滤 for (Object[] row : allTableRowsData) { // 如果选择"所有列"(位置0),检查所有列 if (selectedColumn == 0) { for (Object cell : row) { if (cell != null && cell.toString().toLowerCase().contains(query)) { filteredTableRowsData.add(row); break; } } } // 检查特定列 else if (selectedColumn >= 1 && selectedColumn <= row.length) { int columnIndex = selectedColumn - 1; // 调整索引(0=所有列,1=第一列) if (row[columnIndex] != null && row[columnIndex].toString().toLowerCase().contains(query)) { filteredTableRowsData.add(row); } } } } // 刷新表格显示 refreshTableWithData(filteredTableRowsData); } /** * 刷新表格显示 */ private void refreshTableWithData(Iterable<? extends Object[]> dataToShow) { // Log.d("TableRefresh", "Refreshing table with " + currentSortColumn + " rows"); // 添加调试信息 Log.d("TableRefresh", "Refreshing table with " + currentSortColumn + " rows"); removeAllRowsSafely(); int addedRows = 0; for (Object[] rowData : dataToShow) { addTableRow(rowData); addedRows++; } // 添加空数据提示 if (addedRows == 0) { addEmptyTableRow(); } } private void addEmptyTableRow() { TableRow row = new TableRow(requireContext()); TextView emptyView = new TextView(requireContext()); emptyView.setText("暂无数据"); emptyView.setGravity(Gravity.CENTER); emptyView.setLayoutParams(new TableRow.LayoutParams( TableRow.LayoutParams.MATCH_PARENT, TableRow.LayoutParams.WRAP_CONTENT )); row.addView(emptyView); table.addView(row); } private void removeAllRowsSafely() { // 移除除表头外的所有行(如果有表头) if (table.getChildCount() > 0) { // 保留表头(索引0) for (int i = table.getChildCount() - 1; i >= 1; i--) { View child = table.getChildAt(i); table.removeView(child); // 清理视图引用(非常重要!) cleanupRowViews((TableRow) child); } } } private void cleanupRowViews(TableRow row) { int childCount = row.getChildCount(); for (int i = 0; i < childCount; i++) { View view = row.getChildAt(i); // 解除视图的所有监听器 view.setOnClickListener(null); // 特别是操作按钮,需要取消所有监听器 if (view instanceof Button) { Button button = (Button) view; button.setOnClickListener(null); // 清空按钮的数据引用 button.setTag(null); } } // 从父视图中移除行 if (row.getParent() != null) { ((ViewGroup) row.getParent()).removeView(row); } } } E FATAL EXCEPTION: main Process: com.example.kucun2, PID: 2475 java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference at com.example.kucun2.ui.dingdan.OrderDisplayFragment.hideScrollIndicator(OrderDisplayFragment.java:553) at com.example.kucun2.ui.dingdan.OrderDisplayFragment.lambda$onCreateView$0(OrderDisplayFragment.java:199) at com.example.kucun2.ui.dingdan.OrderDisplayFragment.$r8$lambda$VEviHEc8N_lTbpxv9eW9n-N0BE8(Unknown Source:0) at com.example.kucun2.ui.dingdan.OrderDisplayFragment$$ExternalSyntheticLambda8.onScrollChanged(D8$$SyntheticClass:0) at android.view.ViewTreeObserver.dispatchOnScrollChanged(ViewTreeObserver.java:1301) at android.view.ViewRootImpl.draw(ViewRootImpl.java:6618) at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:6390) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:5268) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:3667) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:12113) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2459) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:2468) at android.view.Choreographer.doCallbacks(Choreographer.java:1693) at android.view.Choreographer.doFrame(Choreographer.java:1448) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:2284) at android.os.Handler.handleCallback(Handler.java:1014) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loopOnce(Looper.java:250) at android.os.Looper.loop(Looper.java:340) at android.app.ActivityThread.main(ActivityThread.java:9913) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:621) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:957)
06-14
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值