SelectDialog.java
8.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
package com.studymachine.www.ui.dialog;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.hjq.base.BaseAdapter;
import com.hjq.base.BaseDialog;
import com.studymachine.www.R;
import com.studymachine.www.aop.SingleClick;
import com.studymachine.www.app.AppAdapter;
import com.hjq.toast.ToastUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
/**
*
*
* time : 2019/10/09
* desc : 单选或者多选对话框
*/
public final class SelectDialog {
public static final class Builder
extends CommonDialog.Builder<Builder>
implements View.OnLayoutChangeListener, Runnable {
@SuppressWarnings("rawtypes")
@Nullable
private OnListener mListener;
private final RecyclerView mRecyclerView;
private final SelectAdapter mAdapter;
public Builder(Context context) {
super(context);
setCustomView(R.layout.select_dialog);
mRecyclerView = findViewById(R.id.rv_select_list);
mRecyclerView.setItemAnimator(null);
mAdapter = new SelectAdapter(getContext());
mRecyclerView.setAdapter(mAdapter);
}
public Builder setList(int... ids) {
List<String> data = new ArrayList<>(ids.length);
for (int id : ids) {
data.add(getString(id));
}
return setList(data);
}
public Builder setList(String... data) {
return setList(Arrays.asList(data));
}
@SuppressWarnings("all")
public Builder setList(List data) {
mAdapter.setData(data);
mRecyclerView.addOnLayoutChangeListener(this);
return this;
}
/**
* 设置默认选中的位置
*/
public Builder setSelect(int... positions) {
mAdapter.setSelect(positions);
return this;
}
/**
* 设置最大选择数量
*/
public Builder setMaxSelect(int count) {
mAdapter.setMaxSelect(count);
return this;
}
/**
* 设置最小选择数量
*/
public Builder setMinSelect(int count) {
mAdapter.setMinSelect(count);
return this;
}
/**
* 设置单选模式
*/
public Builder setSingleSelect() {
mAdapter.setSingleSelect();
return this;
}
@SuppressWarnings("rawtypes")
public Builder setListener(OnListener listener) {
mListener = listener;
return this;
}
@SingleClick
@SuppressWarnings("all")
@Override
public void onClick(View view) {
int viewId = view.getId();
if (viewId == R.id.tv_ui_confirm) {
HashMap<Integer, Object> data = mAdapter.getSelectSet();
if (data.size() >= mAdapter.getMinSelect()) {
autoDismiss();
if (mListener == null) {
return;
}
mListener.onSelected(getDialog(), data);
} else {
ToastUtils.show(String.format(getString(R.string.select_min_hint), mAdapter.getMinSelect()));
}
} else if (viewId == R.id.tv_ui_cancel) {
autoDismiss();
if (mListener == null) {
return;
}
mListener.onCancel(getDialog());
}
}
/**
* {@link View.OnLayoutChangeListener}
*/
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
mRecyclerView.removeOnLayoutChangeListener(this);
// 这里一定要加延迟,如果不加在 Android 9.0 上面会导致 setLayoutParams 无效
post(this);
}
@Override
public void run() {
final ViewGroup.LayoutParams params = mRecyclerView.getLayoutParams();
final int maxHeight = getScreenHeight() / 4 * 3;
if (mRecyclerView.getHeight() > maxHeight) {
if (params.height != maxHeight) {
params.height = maxHeight;
mRecyclerView.setLayoutParams(params);
}
} else {
if (params.height != ViewGroup.LayoutParams.WRAP_CONTENT) {
params.height = ViewGroup.LayoutParams.WRAP_CONTENT;
mRecyclerView.setLayoutParams(params);
}
}
}
/**
* 获取屏幕的高度
*/
private int getScreenHeight() {
Resources resources = getResources();
DisplayMetrics outMetrics = resources.getDisplayMetrics();
return outMetrics.heightPixels;
}
}
private static final class SelectAdapter extends AppAdapter<Object>
implements BaseAdapter.OnItemClickListener {
/** 最小选择数量 */
private int mMinSelect = 1;
/** 最大选择数量 */
private int mMaxSelect = Integer.MAX_VALUE;
/** 选择对象集合 */
@SuppressLint("UseSparseArrays")
private final HashMap<Integer, Object> mSelectSet = new HashMap<>();
private SelectAdapter(Context context) {
super(context);
setOnItemClickListener(this);
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new ViewHolder();
}
private void setSelect(int... positions) {
for (int position : positions) {
mSelectSet.put(position, getItem(position));
}
notifyDataSetChanged();
}
private void setMaxSelect(int count) {
mMaxSelect = count;
}
private void setMinSelect(int count) {
mMinSelect = count;
}
private int getMinSelect() {
return mMinSelect;
}
private void setSingleSelect() {
setMaxSelect(1);
setMinSelect(1);
}
private boolean isSingleSelect() {
return mMaxSelect == 1 && mMinSelect == 1;
}
private HashMap<Integer, Object> getSelectSet() {
return mSelectSet;
}
/**
* {@link BaseAdapter.OnItemClickListener}
*/
@Override
public void onItemClick(RecyclerView recyclerView, View itemView, int position) {
if (mSelectSet.containsKey(position)) {
// 当前必须不是单选模式才能取消选中
if (!isSingleSelect()) {
mSelectSet.remove(position);
notifyItemChanged(position);
}
} else {
if (mMaxSelect == 1) {
mSelectSet.clear();
notifyDataSetChanged();
}
if (mSelectSet.size() < mMaxSelect) {
mSelectSet.put(position, getItem(position));
notifyItemChanged(position);
} else {
ToastUtils.show(String.format(getString(R.string.select_max_hint), mMaxSelect));
}
}
}
private final class ViewHolder extends AppAdapter<?>.ViewHolder {
private final TextView mTextView;
private final CheckBox mCheckBox;
ViewHolder() {
super(R.layout.select_item);
mTextView = findViewById(R.id.tv_select_text);
mCheckBox = findViewById(R.id.tv_select_checkbox);
}
@Override
public void onBindView(int position) {
mTextView.setText(getItem(position).toString());
mCheckBox.setChecked(mSelectSet.containsKey(position));
if (mMaxSelect == 1) {
mCheckBox.setClickable(false);
} else {
mCheckBox.setEnabled(false);
}
}
}
}
public interface OnListener<T> {
/**
* 选择回调
*
* @param data 选择的位置和数据
*/
void onSelected(BaseDialog dialog, HashMap<Integer, T> data);
/**
* 取消回调
*/
default void onCancel(BaseDialog dialog) {}
}
}