回答編集履歴

4

修正(フラグメントからのダイアログ表示中に回転するとダイアログが消えるバグ)

2022/02/28 17:59

投稿

jimbe
jimbe

スコア12670

test CHANGED
@@ -18,6 +18,7 @@
18
18
 
19
19
  public class MainActivity extends AppCompatActivity {
20
20
  private static final String LOGTAG = "MainActivity";
21
+ private static final String TAG_MAINFRAGMENT = "MAIN_FRAGMENT";
21
22
  private static final String REQUESTKEY_MAINDIALOG = "FROM_ACTIVITY";
22
23
 
23
24
  @Override
@@ -37,9 +38,12 @@
37
38
  MainDialog.newInstance(REQUESTKEY_MAINDIALOG).show(fragmentManager, null);
38
39
  });
39
40
 
41
+ //回転等による自動再生成時には replace は行わない
42
+ if(fragmentManager.findFragmentByTag(TAG_MAINFRAGMENT) == null) {
40
- fragmentManager.beginTransaction()
43
+ fragmentManager.beginTransaction()
41
- .replace(R.id.fragmentBase, new MainFragment())
44
+ .replace(R.id.fragmentBase, new MainFragment(), TAG_MAINFRAGMENT)
42
- .commit();
45
+ .commit();
46
+ }
43
47
  }
44
48
  }
45
49
  ```

3

コード修正(Activityでダイアログ表示中の回転バグ, ダイアログへの RequestKey 受け渡し)

2022/02/28 17:02

投稿

jimbe
jimbe

スコア12670

test CHANGED
@@ -10,28 +10,34 @@
10
10
  MainActivity.java
11
11
  ```java
12
12
  import androidx.appcompat.app.AppCompatActivity;
13
+ import androidx.fragment.app.FragmentManager;
13
14
 
14
15
  import android.os.Bundle;
15
16
  import android.util.Log;
16
17
  import android.widget.Button;
17
18
 
18
19
  public class MainActivity extends AppCompatActivity {
20
+ private static final String LOGTAG = "MainActivity";
21
+ private static final String REQUESTKEY_MAINDIALOG = "FROM_ACTIVITY";
19
22
 
20
23
  @Override
21
24
  protected void onCreate(Bundle savedInstanceState) {
22
25
  super.onCreate(savedInstanceState);
23
26
  setContentView(R.layout.activity_main);
24
27
 
28
+ FragmentManager fragmentManager = getSupportFragmentManager();
29
+
30
+ fragmentManager.setFragmentResultListener(REQUESTKEY_MAINDIALOG, this, (requestKey, result) -> {
31
+ Log.d(LOGTAG, "dialog result="+result.getBoolean(MainDialog.RESULTKEY_FLAG_COUNT));
32
+ });
33
+
25
34
  Button showDialog = findViewById(R.id.showDialog);
26
35
  showDialog.setOnClickListener(v -> {
27
- Log.d("MainActivity", "click");
36
+ Log.d(LOGTAG, "click");
28
- getSupportFragmentManager().setFragmentResultListener(MainDialog.REQUEST_KEY, this, (requestKey, result) -> {
29
- Log.d("MainActivity", "dialog result="+result.getBoolean(MainDialog.RESULTKEY_COUNT));
30
- });
31
- new MainDialog().show(getSupportFragmentManager(), "MainDialog");
37
+ MainDialog.newInstance(REQUESTKEY_MAINDIALOG).show(fragmentManager, null);
32
38
  });
33
39
 
34
- getSupportFragmentManager().beginTransaction()
40
+ fragmentManager.beginTransaction()
35
41
  .replace(R.id.fragmentBase, new MainFragment())
36
42
  .commit();
37
43
  }
@@ -78,9 +84,11 @@
78
84
  import android.widget.Button;
79
85
 
80
86
  import androidx.annotation.*;
81
- import androidx.fragment.app.Fragment;
87
+ import androidx.fragment.app.*;
82
88
 
83
89
  public class MainFragment extends Fragment {
90
+ private static final String LOGTAG = "MainFragment";
91
+ private static final String REQUESTKEY_MAINDIALOG = "FROM_FRAGMENT";
84
92
 
85
93
  public MainFragment() {
86
94
  super(R.layout.fragment_main);
@@ -90,13 +98,16 @@
90
98
  public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
91
99
  super.onViewCreated(view, savedInstanceState);
92
100
 
101
+ FragmentManager fragmentManager = getChildFragmentManager();
102
+
103
+ fragmentManager.setFragmentResultListener(REQUESTKEY_MAINDIALOG, getViewLifecycleOwner(), (requestKey, result) -> {
104
+ Log.d(LOGTAG, "dialog result="+result.getBoolean(MainDialog.RESULTKEY_FLAG_COUNT));
105
+ });
106
+
93
107
  Button showDialog = view.findViewById(R.id.showDialog);
94
108
  showDialog.setOnClickListener(v -> {
95
- Log.d("MainFragment", "click");
109
+ Log.d(LOGTAG, "click");
96
- getChildFragmentManager().setFragmentResultListener(MainDialog.REQUEST_KEY, getViewLifecycleOwner(), (requestKey, result) -> {
97
- Log.d("MainFragment", "dialog result="+result.getBoolean(MainDialog.RESULTKEY_COUNT));
98
- });
99
- new MainDialog().show(getChildFragmentManager(), "MainDialog");
110
+ MainDialog.newInstance(REQUESTKEY_MAINDIALOG).show(fragmentManager, null);
100
111
  });
101
112
  }
102
113
  }
@@ -133,24 +144,32 @@
133
144
  import androidx.fragment.app.DialogFragment;
134
145
 
135
146
  public class MainDialog extends DialogFragment {
136
- static final String REQUEST_KEY = "DialogResult";
147
+ static final String ARGS_REQUEST_KEY = "REQUEST_KEY";
137
- static final String RESULTKEY_COUNT = "Count";
148
+ static final String RESULTKEY_FLAG_COUNT = "FLAG_COUNT";
149
+
150
+ static MainDialog newInstance(@Nullable String requestKey) {
151
+ MainDialog dialog = new MainDialog();
152
+ Bundle args = new Bundle();
153
+ args.putString(ARGS_REQUEST_KEY, requestKey);
154
+ dialog.setArguments(args);
155
+ return dialog;
156
+ }
157
+
138
158
  @NonNull
139
159
  @Override
140
160
  public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
141
161
  return new AlertDialog.Builder(getContext())
142
162
  .setTitle("ダイアログ")
143
- .setPositiveButton("True", (dialog, which) -> {
163
+ .setPositiveButton("True", (dialog, which) -> setFragmentResult(true))
144
- Bundle bundle = new Bundle();
145
- bundle.putBoolean(RESULTKEY_COUNT, true);
146
- getParentFragmentManager().setFragmentResult(REQUEST_KEY, bundle);
147
- })
148
- .setNegativeButton("False", (dialog, which) -> {
164
+ .setNegativeButton("False", (dialog, which) -> setFragmentResult(false))
149
- Bundle bundle = new Bundle();
150
- bundle.putBoolean(RESULTKEY_COUNT, false);
151
- getParentFragmentManager().setFragmentResult(REQUEST_KEY, bundle);
152
- })
153
165
  .create();
166
+ }
167
+
168
+ private void setFragmentResult(boolean flag_count) {
169
+ Bundle bundle = new Bundle();
170
+ bundle.putBoolean(RESULTKEY_FLAG_COUNT, flag_count);
171
+ String requestKey = getArguments().getString(ARGS_REQUEST_KEY, "MainDialog");
172
+ getParentFragmentManager().setFragmentResult(requestKey, bundle);
154
173
  }
155
174
  }
156
175
  ```

2

回転時に落ちるバグを修正

2022/02/28 09:09

投稿

jimbe
jimbe

スコア12670

test CHANGED
@@ -82,7 +82,7 @@
82
82
 
83
83
  public class MainFragment extends Fragment {
84
84
 
85
- MainFragment() {
85
+ public MainFragment() {
86
86
  super(R.layout.fragment_main);
87
87
  }
88
88
 

1

FragmentManager による受取サンプルコードの追加

2022/02/28 08:40

投稿

jimbe
jimbe

スコア12670

test CHANGED
@@ -1 +1,166 @@
1
1
  Fragment は FragmentManager によって管理されており、 FragmentManager には管理している Fragment を得るメソッドがあります。[既存のフラグメントを見つける](https://developer.android.com/guide/fragments/fragmentmanager?hl=ja#finding)
2
+
3
+ ---
4
+ >●●の4行上ところで、アクティビティを取得したように、●●の箇所でフラグメントを取得してflag_count_frの値を直接フラグメントに送りたい
5
+
6
+ ダイアログの結果として、その表示元である Activity か Fragment に true を送るという処理でしょうか。
7
+
8
+ 最近拡張された FragmentManager の機能により、Bundle を介してデータを受け取れるようです。
9
+
10
+ MainActivity.java
11
+ ```java
12
+ import androidx.appcompat.app.AppCompatActivity;
13
+
14
+ import android.os.Bundle;
15
+ import android.util.Log;
16
+ import android.widget.Button;
17
+
18
+ public class MainActivity extends AppCompatActivity {
19
+
20
+ @Override
21
+ protected void onCreate(Bundle savedInstanceState) {
22
+ super.onCreate(savedInstanceState);
23
+ setContentView(R.layout.activity_main);
24
+
25
+ Button showDialog = findViewById(R.id.showDialog);
26
+ showDialog.setOnClickListener(v -> {
27
+ Log.d("MainActivity", "click");
28
+ getSupportFragmentManager().setFragmentResultListener(MainDialog.REQUEST_KEY, this, (requestKey, result) -> {
29
+ Log.d("MainActivity", "dialog result="+result.getBoolean(MainDialog.RESULTKEY_COUNT));
30
+ });
31
+ new MainDialog().show(getSupportFragmentManager(), "MainDialog");
32
+ });
33
+
34
+ getSupportFragmentManager().beginTransaction()
35
+ .replace(R.id.fragmentBase, new MainFragment())
36
+ .commit();
37
+ }
38
+ }
39
+ ```
40
+ res/layout/activity_main.xml
41
+ ```xml
42
+ <?xml version="1.0" encoding="utf-8"?>
43
+ <androidx.constraintlayout.widget.ConstraintLayout
44
+ xmlns:android="http://schemas.android.com/apk/res/android"
45
+ xmlns:app="http://schemas.android.com/apk/res-auto"
46
+ xmlns:tools="http://schemas.android.com/tools"
47
+ android:layout_width="match_parent"
48
+ android:layout_height="match_parent"
49
+ tools:context=".MainActivity">
50
+
51
+ <Button
52
+ android:id="@+id/showDialog"
53
+ android:layout_width="0dp"
54
+ android:layout_height="0dp"
55
+ android:text="showDialog(Activity)"
56
+ app:layout_constraintBottom_toTopOf="@id/fragmentBase"
57
+ app:layout_constraintLeft_toLeftOf="parent"
58
+ app:layout_constraintRight_toRightOf="parent"
59
+ app:layout_constraintTop_toTopOf="parent" />
60
+
61
+ <LinearLayout
62
+ android:id="@+id/fragmentBase"
63
+ android:layout_width="0dp"
64
+ android:layout_height="0dp"
65
+ android:orientation="vertical"
66
+ app:layout_constraintBottom_toBottomOf="parent"
67
+ app:layout_constraintLeft_toLeftOf="parent"
68
+ app:layout_constraintRight_toRightOf="parent"
69
+ app:layout_constraintTop_toBottomOf="@id/showDialog" />
70
+
71
+ </androidx.constraintlayout.widget.ConstraintLayout>
72
+ ```
73
+ MainFragment.java
74
+ ```java
75
+ import android.os.Bundle;
76
+ import android.util.Log;
77
+ import android.view.View;
78
+ import android.widget.Button;
79
+
80
+ import androidx.annotation.*;
81
+ import androidx.fragment.app.Fragment;
82
+
83
+ public class MainFragment extends Fragment {
84
+
85
+ MainFragment() {
86
+ super(R.layout.fragment_main);
87
+ }
88
+
89
+ @Override
90
+ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
91
+ super.onViewCreated(view, savedInstanceState);
92
+
93
+ Button showDialog = view.findViewById(R.id.showDialog);
94
+ showDialog.setOnClickListener(v -> {
95
+ Log.d("MainFragment", "click");
96
+ getChildFragmentManager().setFragmentResultListener(MainDialog.REQUEST_KEY, getViewLifecycleOwner(), (requestKey, result) -> {
97
+ Log.d("MainFragment", "dialog result="+result.getBoolean(MainDialog.RESULTKEY_COUNT));
98
+ });
99
+ new MainDialog().show(getChildFragmentManager(), "MainDialog");
100
+ });
101
+ }
102
+ }
103
+ ```
104
+ res/layout/fragment_main.xml
105
+ ```xml
106
+ <?xml version="1.0" encoding="utf-8"?>
107
+ <androidx.constraintlayout.widget.ConstraintLayout
108
+ xmlns:android="http://schemas.android.com/apk/res/android"
109
+ xmlns:app="http://schemas.android.com/apk/res-auto"
110
+ xmlns:tools="http://schemas.android.com/tools"
111
+ android:layout_width="match_parent"
112
+ android:layout_height="match_parent"
113
+ tools:context=".MainFragment">
114
+
115
+ <Button
116
+ android:id="@+id/showDialog"
117
+ android:layout_width="match_parent"
118
+ android:layout_height="match_parent"
119
+ android:text="showDialog(Fragment)"
120
+ app:layout_constraintBottom_toBottomOf="parent"
121
+ app:layout_constraintLeft_toLeftOf="parent"
122
+ app:layout_constraintRight_toRightOf="parent"
123
+ app:layout_constraintTop_toTopOf="parent" />
124
+
125
+ </androidx.constraintlayout.widget.ConstraintLayout>
126
+ ```
127
+ MainDialog.java
128
+ ```java
129
+ import android.app.*;
130
+ import android.os.Bundle;
131
+
132
+ import androidx.annotation.*;
133
+ import androidx.fragment.app.DialogFragment;
134
+
135
+ public class MainDialog extends DialogFragment {
136
+ static final String REQUEST_KEY = "DialogResult";
137
+ static final String RESULTKEY_COUNT = "Count";
138
+ @NonNull
139
+ @Override
140
+ public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
141
+ return new AlertDialog.Builder(getContext())
142
+ .setTitle("ダイアログ")
143
+ .setPositiveButton("True", (dialog, which) -> {
144
+ Bundle bundle = new Bundle();
145
+ bundle.putBoolean(RESULTKEY_COUNT, true);
146
+ getParentFragmentManager().setFragmentResult(REQUEST_KEY, bundle);
147
+ })
148
+ .setNegativeButton("False", (dialog, which) -> {
149
+ Bundle bundle = new Bundle();
150
+ bundle.putBoolean(RESULTKEY_COUNT, false);
151
+ getParentFragmentManager().setFragmentResult(REQUEST_KEY, bundle);
152
+ })
153
+ .create();
154
+ }
155
+ }
156
+ ```
157
+ ```plain
158
+ D/MainActivity: click
159
+ D/MainActivity: dialog result=true
160
+ D/MainActivity: click
161
+ D/MainActivity: dialog result=false
162
+ D/MainFragment: click
163
+ D/MainFragment: dialog result=true
164
+ D/MainFragment: click
165
+ D/MainFragment: dialog result=false
166
+ ```