回答編集履歴

3

コード追加

2024/11/10 08:34

投稿

jimbe
jimbe

スコア13170

test CHANGED
@@ -19,3 +19,209 @@
19
19
 
20
20
  表ではプログレスが動き裏では更新処理が動くようにするというのであれば、マルチスレッドにする必要があると思います。
21
21
  (参考にされた情報がどのようなものだったのかが気になります。)
22
+
23
+ ---
24
+ 取り合えずテキトウに想像しました。
25
+ (なお、ダイアログでプログレスを表示することはユーザが他の操作をすることを出来なくしてしまう可能性があるため推奨されません。)
26
+
27
+ MainActivity.java
28
+ ```java
29
+ import androidx.appcompat.app.AppCompatActivity;
30
+
31
+ import android.app.Dialog;
32
+ import android.os.*;
33
+ import android.view.*;
34
+ import android.widget.*;
35
+
36
+ import java.time.*;
37
+ import java.util.*;
38
+ import java.util.function.*;
39
+
40
+ public class MainActivity extends AppCompatActivity {
41
+ @Override
42
+ protected void onCreate(Bundle savedInstanceState) {
43
+ super.onCreate(savedInstanceState);
44
+ setContentView(R.layout.activity_main);
45
+
46
+ ListView listView = findViewById(R.id.list_view);
47
+ Adapter adapter = new Adapter();
48
+ listView.setAdapter(adapter);
49
+
50
+ EditText searchCodeEdit = findViewById(R.id.search_code);
51
+ Button searchButton = findViewById(R.id.search_button);
52
+ searchButton.setOnClickListener(e -> {
53
+ String storeCode = searchCodeEdit.getText().toString();
54
+ new AsyncProgressDialog<>(null, ()->getData(storeCode), adapter::setItemList).show();
55
+ });
56
+ }
57
+
58
+ //時間のかかる処理を模倣
59
+ private List<Item> getData(String storeCode) {
60
+ String date = LocalDateTime.now().toString();
61
+ int max = new Random().nextInt(10) + 3; //テキトウな数のデータを用意する
62
+ List<Item> list = new ArrayList<>();
63
+ for(int i=0; i<max; i++) {
64
+ if(i != 0) {
65
+ try {
66
+ Thread.sleep(500); //[ms]
67
+ } catch(InterruptedException e) {
68
+ break; //中止
69
+ }
70
+ }
71
+ list.add(new Item(storeCode, (i+1)+" : "+date));
72
+ }
73
+ return list;
74
+ }
75
+
76
+ private class AsyncProgressDialog<E> extends Dialog {
77
+ AsyncProgressDialog(Runnable pre, Supplier<E> back, Consumer<E> post) {
78
+ super(MainActivity.this);
79
+ setContentView(R.layout.dialog_progress);
80
+
81
+ setOnShowListener(d -> {
82
+ if(pre != null) {
83
+ try {
84
+ pre.run();
85
+ } catch(Throwable t) {
86
+ dismiss();
87
+ throw t;
88
+ }
89
+ }
90
+ new Thread(() -> {
91
+ try {
92
+ E v = back.get();
93
+ runOnUiThread(() -> {
94
+ try {
95
+ if(post != null) post.accept(v);
96
+ } finally {
97
+ dismiss();
98
+ }
99
+ });
100
+ } catch(Throwable t) {
101
+ runOnUiThread(() -> dismiss());
102
+ throw t;
103
+ }
104
+ }).start();
105
+ });
106
+ }
107
+ }
108
+
109
+ private static class Item {
110
+ final String code, text;
111
+ Item(String code, String text) {
112
+ this.code = code;
113
+ this.text = text;
114
+ }
115
+ }
116
+
117
+ private static class Adapter extends BaseAdapter {
118
+ private List<Item> itemList = new ArrayList<>();
119
+ private Comparator<Item> itemComparator = Comparator.comparing(a -> a.code);
120
+
121
+ void setItemList(List<Item> itemList) {
122
+ this.itemList = new ArrayList<>(itemList); //防御コピー
123
+ Collections.sort(itemList, itemComparator);
124
+ notifyDataSetChanged();
125
+ }
126
+
127
+ @Override
128
+ public int getCount() {
129
+ return itemList.size();
130
+ }
131
+
132
+ @Override
133
+ public Object getItem(int position) {
134
+ return itemList.get(position);
135
+ }
136
+
137
+ @Override
138
+ public long getItemId(int position) {
139
+ return 0;
140
+ }
141
+
142
+ @Override
143
+ public View getView(int position, View convertView, ViewGroup parent) {
144
+ ViewHolder vh = convertView == null ? new ViewHolder(parent) : (ViewHolder)convertView.getTag();
145
+ vh.bind(itemList.get(position));
146
+ return vh.itemView;
147
+ }
148
+
149
+ private static class ViewHolder {
150
+ final View itemView;
151
+ private TextView text1, text2;
152
+
153
+ ViewHolder(ViewGroup parent) {
154
+ itemView = LayoutInflater.from(parent.getContext()).inflate(android.R.layout.simple_list_item_2, parent, false);
155
+ itemView.setTag(this);
156
+ text1 = itemView.findViewById(android.R.id.text1);
157
+ text2 = itemView.findViewById(android.R.id.text2);
158
+ }
159
+
160
+ void bind(Item item) {
161
+ text1.setText(item.code);
162
+ text2.setText(item.text);
163
+ }
164
+ }
165
+ }
166
+ }
167
+ ```
168
+ layout/activity_main.xml
169
+ ```xml
170
+ <?xml version="1.0" encoding="utf-8"?>
171
+ <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
172
+ xmlns:app="http://schemas.android.com/apk/res-auto"
173
+ xmlns:tools="http://schemas.android.com/tools"
174
+ android:layout_width="match_parent"
175
+ android:layout_height="match_parent"
176
+ tools:context=".MainActivity">
177
+
178
+ <TextView
179
+ android:id="@+id/search_code_label"
180
+ android:layout_width="0dp"
181
+ android:layout_height="wrap_content"
182
+ android:text="CODE:"
183
+ app:layout_constraintStart_toStartOf="parent"
184
+ app:layout_constraintBaseline_toBaselineOf="@id/search_code" />
185
+ <EditText
186
+ android:id="@+id/search_code"
187
+ android:layout_width="0dp"
188
+ android:layout_height="wrap_content"
189
+ app:layout_constraintEnd_toEndOf="parent"
190
+ app:layout_constraintStart_toEndOf="@id/search_code_label"
191
+ app:layout_constraintTop_toTopOf="parent" />
192
+ <Button
193
+ android:id="@+id/search_button"
194
+ android:layout_width="wrap_content"
195
+ android:layout_height="wrap_content"
196
+ android:text="search"
197
+ app:layout_constraintEnd_toEndOf="parent"
198
+ app:layout_constraintTop_toBottomOf="@id/search_code" />
199
+
200
+ <ListView
201
+ android:id="@+id/list_view"
202
+ android:layout_width="0dp"
203
+ android:layout_height="0dp"
204
+ android:background="#d0ffff"
205
+ app:layout_constraintBottom_toBottomOf="parent"
206
+ app:layout_constraintEnd_toEndOf="parent"
207
+ app:layout_constraintStart_toStartOf="parent"
208
+ app:layout_constraintTop_toBottomOf="@id/search_button" />
209
+ </androidx.constraintlayout.widget.ConstraintLayout>
210
+ ```
211
+ layout/dialog_progress.xml
212
+ ```xml
213
+ <?xml version="1.0" encoding="utf-8"?>
214
+ <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
215
+ android:layout_width="match_parent"
216
+ android:layout_height="match_parent"
217
+ xmlns:app="http://schemas.android.com/apk/res-auto">
218
+
219
+ <ProgressBar
220
+ android:layout_width="wrap_content"
221
+ android:layout_height="wrap_content"
222
+ app:layout_constraintBottom_toBottomOf="parent"
223
+ app:layout_constraintEnd_toEndOf="parent"
224
+ app:layout_constraintStart_toStartOf="parent"
225
+ app:layout_constraintTop_toTopOf="parent" />
226
+ </androidx.constraintlayout.widget.ConstraintLayout>
227
+ ```

2

URL追加

2024/11/08 15:58

投稿

jimbe
jimbe

スコア13170

test CHANGED
@@ -9,6 +9,9 @@
9
9
  で時間が掛かっている間プログレスが表示されていて処理が終わったらプログレスのダイアログを閉じる…とされたいのだと思いますが。
10
10
 
11
11
  android は UI スレッドという単一のスレッドがアプリ全体の処理を行っていることはご理解されているでしょうか。
12
+
13
+ https://developer.android.com/guide/components/processes-and-threads?hl=ja#Threads
14
+
12
15
  ダイアログ等の表示処理は実際には UI スレッドへの通知(処理要求)であって、実行したら即表示されるものではありません。
13
16
  また View の操作によるイベントの発火もまた UI スレッドが処理していて、その場合イベントの処理が終わらない限り UI スレッドは次の処理は出来ません。
14
17
  従って、もし SearchData の呼び出しがボタン操作等によるイベント処理メソッドからであれば、まさしく UI スレッド上で動いている状態であり、ダイアログの表示の要求は SearchData が終わらなければ実行されないことになります。

1

用語間違い?

2024/11/08 15:55

投稿

jimbe
jimbe

スコア13170

test CHANGED
@@ -8,10 +8,10 @@
8
8
 
9
9
  で時間が掛かっている間プログレスが表示されていて処理が終わったらプログレスのダイアログを閉じる…とされたいのだと思いますが。
10
10
 
11
- android はイベントディパッチスレッド(EDT)という単一のスレッドがアプリ全体の処理を行っていることはご理解されているでしょうか。
11
+ android は UI スレッドという単一のスレッドがアプリ全体の処理を行っていることはご理解されているでしょうか。
12
- ダイアログ等の表示処理は実際にはEDTへの通知(処理要求)であって、実行したら即表示されるものではありません。
12
+ ダイアログ等の表示処理は実際には UI スレッドへの通知(処理要求)であって、実行したら即表示されるものではありません。
13
- また View の操作によるイベントの発火もまた EDT が処理していて、その場合イベントの処理が終わらない限り EDT は次の処理は出来ません。
13
+ また View の操作によるイベントの発火もまた UI スレッドが処理していて、その場合イベントの処理が終わらない限り UI スレッドは次の処理は出来ません。
14
- 従って、もし SearchData の呼び出しがボタン操作等によるイベント処理メソッドからであれば、まさしく EDT 上で動いている状態であり、ダイアログの表示の要求は SearchData が終わらなければ実行されないことになります。
14
+ 従って、もし SearchData の呼び出しがボタン操作等によるイベント処理メソッドからであれば、まさしく UI スレッド上で動いている状態であり、ダイアログの表示の要求は SearchData が終わらなければ実行されないことになります。
15
15
  SearchData は表示・処理の後にダイアログを閉じるまで行っていますから、 SearchData が終わってダイアログを表示後即閉じとなり、結局何も起きていないような状態になるでしょう。
16
16
 
17
17
  表ではプログレスが動き裏では更新処理が動くようにするというのであれば、マルチスレッドにする必要があると思います。