質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

解決済

1回答

514閲覧

AndroidのListViewに表示される情報をDelete/Update後に更新したい (Android/Java)

Yakusugi

総合スコア123

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

0クリップ

投稿2022/06/17 11:29

編集2022/06/18 11:37

Androidで家計簿アプリをJavaで作成しています。

ここでやりたい事は、下記ProductFragmentの検索結果が表示されるListViewをDelete/Updateした後のListViewの更新です。

一連の動きは下記の通りです。
1.ProductFragmentでSEARCHボタンを押す
2.検索結果がListViewに表示される。
3.表示されたListView上のアイテムを1つクリックする。
4.別のアクティビティ(NewBudgetTracker)へ移動し、アイテムをDelete・Updateする。
5.Delete・Update後は元のProductFragmentへ戻る。

問題は上記5以降です。
最初に述べた通り、検索結果のアイテムをDelete・Updateすると、DB上のデータはDelete・Updateされるのですが、
ListViewが更新されず、Deleteされたはずのアイテムが残り続けていたり、Updateされず古い情報が残り続けています。

そのため、ProductFragmentで下記処理を追加し、再度SELECT文を発行する処理(getProductTypeLists)を行ってします。
最後に「productListViewAdapter.notifyDataSetChanged();」でAdapterを更新する処理を追加しているのですが、ListViewは更新されませんでした。

viewModelProductNameLists = budgetTrackerViewModel.getProductTypeLists(productType); ProductListViewAdapter productListViewAdapter; productListViewAdapter = new ProductListViewAdapter(getActivity(), viewModelProductNameLists); productListViewAdapter.notifyDataSetChanged(); productListView.setAdapter(productListViewAdapter);

大変お手数ですが、解決の為、ご助力頂けますと幸いです。

よろしくお願いいたします。

ProductFragment画面(検索処理)
イメージ説明

NewBudgetTracker画面(Delete/Update実行)
イメージ説明

ProductFragment.java

package com.myproject.offlinebudgettrackerappproject; <省略> /** * A simple {@link Fragment} subclass. * Use the {@link ProductFragment#newInstance} factory method to * create an instance of this fragment. */ public class ProductFragment extends Fragment { private static final int RESULT_OK = -1; BudgetTrackerViewModel budgetTrackerViewModel; private ProductListViewAdapter productListViewAdapter; public static final String PRODUCT_FRAGMENT_ID = "product_fragment_id"; private ListView productListView; private List<BudgetTracker> budgetTrackerList; private List<BudgetTracker> budgetTracker; List<BudgetTracker> viewModelProductNameLists; ActivityMainBinding activityMainBinding; private int newBudgetTrackerIntentId = 0; String productType; // TODO: Rename parameter arguments, choose names that match // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER private static final String ARG_PARAM1 = "param1"; private static final String ARG_PARAM2 = "param2"; // TODO: Rename and change types of parameters private String mParam1; private String mParam2; public ProductFragment() { // Required empty public constructor } /** * Use this factory method to create a new instance of * this fragment using the provided parameters. * * @param param1 Parameter 1. * @param param2 Parameter 2. * @return A new instance of fragment ProductFragment. */ // TODO: Rename and change types and number of parameters public static ProductFragment newInstance(String param1, String param2) { ProductFragment fragment = new ProductFragment(); Bundle args = new Bundle(); args.putString(ARG_PARAM1, param1); args.putString(ARG_PARAM2, param2); fragment.setArguments(args); return fragment; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (getArguments() != null) { mParam1 = getArguments().getString(ARG_PARAM1); mParam2 = getArguments().getString(ARG_PARAM2); } } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_product, container, false); EditText enterProductTypeForQuery = (EditText) view.findViewById(R.id.product_search_txt); Button productSearchQueryBtn = (Button) view.findViewById(R.id.btn_product_search); productListView = (ListView) view.findViewById(R.id.product_listview); TextView productTypeSum = (TextView) view.findViewById(R.id.product_type_sum_result_txt); activityMainBinding = ActivityMainBinding.inflate(getLayoutInflater()); BaseAdapter adapter = new StoreListViewAdapter(getActivity(), budgetTrackerList); productListViewAdapter = new ProductListViewAdapter(getActivity(), 1); productListView.setAdapter(productListViewAdapter); productSearchQueryBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { BudgetTracker budgetTracker; // 2022/02/11 追加 ProductListViewAdapter productListViewAdapter; productType = enterProductTypeForQuery.getText().toString(); budgetTrackerViewModel = new ViewModelProvider(requireActivity()).get(BudgetTrackerViewModel.class); budgetTracker = new BudgetTracker(); budgetTracker.setProductType(productType); viewModelProductNameLists = budgetTrackerViewModel.getProductTypeLists(productType); productListViewAdapter = new ProductListViewAdapter(getActivity(), viewModelProductNameLists); productListView.setAdapter(productListViewAdapter); String productTypeSumStr = String.valueOf(budgetTrackerViewModel.getProductTypeSum(productType)); productTypeSum.setText(productTypeSumStr); // Todo 2022/04/10 Tapped modified productListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { String date = adapterView.getItemAtPosition(position).toString(); List<BudgetTracker> budgetListItems = viewModelProductNameLists; int intId = (int) id; BudgetTracker productItemId = budgetListItems.get(intId); Intent productFragmentIntent = new Intent(getActivity(), NewBudgetTracker.class); productFragmentIntent.putExtra(PRODUCT_FRAGMENT_ID, productItemId.getId()); startActivityForResult(productFragmentIntent, 1); } }); Log.d("TAG", "onClick: " + enterProductTypeForQuery.getText().toString()); } }); return view; } @Override public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 1) { if (resultCode == RESULT_OK) { int result = data.getIntExtra("result", 0); viewModelProductNameLists = budgetTrackerViewModel.getProductTypeLists(productType); productListViewAdapter = new ProductListViewAdapter(getActivity(), viewModelProductNameLists); productListView.setAdapter(productListViewAdapter); } } } }

NewBudgetTracker.java

if (shopFragmentIntentId != 0) { setResult(RESULT_OK, shopFragmentGetIntent); } else if (productFragmentIntentId != 0) { setResult(RESULT_OK, productFragmentGetIntent); } else if (dateFragmentIntentId != 0) { setResult(RESULT_OK, dateFragmentGetIntent); }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hoshi-takanori

2022/06/17 12:11

startActivity を呼び出した直後に adapter を更新してますが、この時点ではまだ NewBudgetTracker を開こうとしている段階で、データは更新されてないので表示もそのままです。 実際にデータが更新された後に adapter を更新する必要があります。
Yakusugi

2022/06/17 13:32

早速ご回答頂きありがとうございます。 回答の中で「実際にデータが更新された後に adapter を更新する必要があります。」とありますが、 NewBudgetTrackerでUpdate処理が終わった後(finish();)に、下記処理を記載し、ProductFragmentへ処理を戻すIntentを書いたのですが、実際には呼び出し元のProductFragmentへは戻らず、バグが発生してしまいました。 当該処理を記載する前までは、Uodate/deleteが終わると、自動的に呼び出し元のProductFragmentへ戻っていました。 Intent nbtToPfIntent = new Intent(NewBudgetTracker.this, NewBudgetTracker.class); nbtToPfIntent.putExtra(NBT_TO_PF, 0); startActivity(nbtToPfIntent); ここでやりたかったのは、Intentを使って、NewBudgetTrackerからProductFragmentへ処理を戻し、 Intentを受領後、ProductFragmentでadapter更新を行おうとしました。 ご回答の中で仰っていた、データ更新をされた後と言うのは、実際にどちらにadapter処理を書くのが適当でしょうか。
hoshi-takanori

2022/06/17 15:04

startActivity はその名の通り新しいアクティビティを開くもので、元の画面には戻りません。元に戻るには finish() で良いのですが、元の画面の側で戻ってきたことを検知するには startActivityForResult しておく必要があります。(最近は startActivityForResult の代わりに ActivityResultContracts を使うべしってことになってますが…。)
Yakusugi

2022/06/18 11:38

ありがとうございました! startActivityForResultを使うことで解決出来ました!
guest

回答1

0

ベストアンサー

(全体的なことは「質問への追記・修正の依頼」のほうでお話が進んでいますので)部分的なことになりますが、

最後に「productListViewAdapter.notifyDataSetChanged();」でAdapterを更新する処理を追加しているのですが、ListViewは更新されませんでした。

viewModelProductNameLists = budgetTrackerViewModel.getProductTypeLists(productType);
ProductListViewAdapter productListViewAdapter;
productListViewAdapter = new ProductListViewAdapter(getActivity(), viewModelProductNameLists);
productListViewAdapter.notifyDataSetChanged();
productListView.setAdapter(productListViewAdapter);

notifyDataSetChanged() は、自身(アダプタ)に登録されているオブザーバに対してイベントを通知します。
簡単に言えば、アダプタを setAdapter している View に対してイベントを送る感じになります。
ですので setAdapter する前に実行しても意味がありません。
そして、通常は setAdapter によって表示を更新しますので、 setAdapter 直後に notifyDataSetChanged() は必要ありません。
結果的には、該当箇所は View の更新がされないことには関係ないものと思います。

投稿2022/06/17 16:45

編集2022/06/17 16:52
jimbe

総合スコア12648

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Yakusugi

2022/06/18 11:39

いつもご回答頂きありがとうございます。 hoshi-takanoriさんのご回答も含めて、解決しました。
jimbe

2022/06/18 19:39

ベストアンサーは、 hoshi-rakanori さんのご指摘からどのようにされたのかを自己回答で書いていただいてそちらに付けた方が、ご質問と回答が一致して良いように思います ^^;
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問