JavaでAndroidの家計簿アプリを作成しています。
現在、Fragment間のデータの受け渡しで問題が起きています。
目的としては、
Fragment1からFragment2へデータを渡し、
Fragment2で渡されたデータの編集を行い、
Fragment1に戻し、問題無くFragment1のListViewでもデータの閲覧が出来、
戻ったFragment1のListViewの同じアイテムか別のアイテムを選択しても、
問題無く続けて編集(Fragment1からFragment2へデータを渡す)が出来るようにすることです。
上記説明に当てはめると、
SearchFragment.javaがFragment1(データ閲覧画面で、ListView上のアイテムをクリックするとAddSpendingFragmentへ画面遷移)、
AddSpendingFragmentがFragment2(受け取ったデータを編集し、SearchFragmentに戻す画面)
となります。
問題なのは、AddSpendingFragmentの方で、
fragmentManager.popBackStack();で呼び出し元のSearchFragmentに画面遷移しますが、
SearchFragmentで改めて検索を行い、ListView上のアイテムをクリックすると、アプリが落ちてしまいます。
下記がエラー表示となります。
java.lang.NullPointerException: Attempt to invoke interface method 'androidx.lifecycle.Lifecycle androidx.lifecycle.LifecycleOwner.getLifecycle()' on a null object reference at androidx.lifecycle.LiveData.observe(LiveData.java:192) at com.myproject.offlinebudgettrackerappproject.AddSpendingFragment$4.onFragmentResult(AddSpendingFragment.java:229) at androidx.fragment.app.FragmentManager$LifecycleAwareResultListener.onFragmentResult(FragmentManager.java:249) at androidx.fragment.app.FragmentManager.setFragmentResult(FragmentManager.java:916) at com.myproject.offlinebudgettrackerappproject.SearchFragment$4.onItemClick(SearchFragment.java:208) at android.widget.AdapterView.performItemClick(AdapterView.java:330) at android.widget.AbsListView.performItemClick(AbsListView.java:1190) at android.widget.AbsListView$PerformClick.run(AbsListView.java:3198) at android.widget.AbsListView$3.run(AbsListView.java:4116) at android.os.Handler.handleCallback(Handler.java:883) at android.os.Handler.dispatchMessage(Handler.java:100) at android.os.Looper.loop(Looper.java:214) at android.app.ActivityThread.main(ActivityThread.java:7356) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
具体的なアプリの動きに関しては、YouTube動画として公開していますので、ご確認頂ければ幸いです。
https://youtube.com/shorts/dutsY6umTLU?feature=share
下記コードでは、SearchFragmentでFragmentManagerを使ってfragment間でのデータの受け渡しを行っています。
SearchFragment
searchListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { String date = adapterView.getItemAtPosition(position).toString(); List<BudgetTrackerSpending> budgetSpendingListItems = searchStoreNameLists; int intId = (int) id; BudgetTrackerSpending storeItemId = budgetSpendingListItems.get(intId); //fragment intent Fragment fragment = new AddSpendingFragment(); Bundle result = new Bundle(); result.putInt("storeId", storeItemId.getId()); fragment.setArguments(result); FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); fragmentManager.setFragmentResult("shop_search_id", result); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragmentTransaction.replace(R.id.main_container, fragment); fragmentTransaction.addToBackStack(null); fragmentTransaction.commit(); } });
※下記コメントアウトしている箇所は、今後実装予定箇所となるため、一時的にコメントアウトしています。
AddSpendingFragment
updateButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (searchShopId != 0) { // idStore = shopFragmentIntentId; // idProduct = productFragmentIntentId; // idDate = dateFragmentIntentId; // idReplace = replacedActivityIntentId; String date = enterDate.getText().toString(); String storeName = enterStoreName.getText().toString(); String productName = enterProductName.getText().toString(); String productType = enterProductType.getText().toString(); double price = Double.parseDouble(enterPrice.getText().toString()); if (enterVatRate.getText().toString().trim().length() > 0) { Log.d("09120222", "onClick: " + enterVatRate.getText().toString()); // enterVatRate.setText(String.valueOf(0.0)); enterVatRate.setText(null); } else { vatRate = Double.parseDouble(enterVatRate.getText().toString()); } String notes = enterNotes.getText().toString(); if (TextUtils.isEmpty(date) || TextUtils.isEmpty(storeName) || TextUtils.isEmpty(productName) || TextUtils.isEmpty(productType) || TextUtils.isEmpty(String.valueOf(price)) || TextUtils.isEmpty(String.valueOf(vatRate)) || TextUtils.isEmpty(notes)) { Snackbar.make(enterProductName, R.string.empty, Snackbar.LENGTH_SHORT).show(); } else { BudgetTrackerSpending budgetTrackerSpending = new BudgetTrackerSpending(); if (searchShopId != 0) { budgetTrackerSpending.setId(searchShopId); } // } else if (productFragmentIntentId != 0) { // budgetTracker.setId(idProduct); // } else if (dateFragmentIntentId != 0) { // budgetTracker.setId(idDate); // } else if (replacedActivityIntentId != 0) { // budgetTracker.setId(idReplace); // } budgetTrackerSpending.setDate(date); budgetTrackerSpending.setStoreName(storeName); budgetTrackerSpending.setProductName(productName); budgetTrackerSpending.setProductType(productType); budgetTrackerSpending.setPrice(price); budgetTrackerSpending.setTaxRate(vatRate); budgetTrackerSpending.setNotes(notes); BudgetTrackerSpendingViewModel.updateBudgetTrackerSpending(budgetTrackerSpending); // Todo Automatic search after updated an item // if (searchShopId != 0) { // setResult(RESULT_OK, shopFragmentGetIntent); // } else if (productFragmentIntentId != 0) { // setResult(RESULT_OK, productFragmentGetIntent); // } FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); fragmentManager.popBackStack(); } } } });
お手数ですが、解決の為、アドバイスがあればご教示頂けますと幸いです。
回答1件
あなたの回答
tips
プレビュー