Commit 67fd5373bf77b6b1ed2b351cf057f79e8d383074

Authored by shixianjie
1 parent 25e17c06b1
Exists in master

bugfix; 布局优化; 交互逻辑调整;

app/src/main/java/com/hjx/parent/App.java
1 package com.hjx.parent; 1 package com.hjx.parent;
2 2
3 import com.prws.common.CommonApplication; 3 import com.prws.common.CommonApplication;
4 import com.prws.common.bean.GradeAndSubject; 4 import com.prws.common.bean.GradeAndSubject;
5 import com.prws.common.utils.SharedPreferencesUtil; 5 import com.prws.common.utils.SharedPreferencesUtil;
6 import com.uuzuche.lib_zxing.activity.ZXingLibrary; 6 import com.uuzuche.lib_zxing.activity.ZXingLibrary;
7 7
8 import java.util.ArrayList;
8 import java.util.List; 9 import java.util.List;
9 10
10 public class App extends CommonApplication { 11 public class App extends CommonApplication {
11 private static App instance; 12 private static App instance;
12 13
13 public static App getInstance() { 14 public static App getInstance() {
14 return instance; 15 return instance;
15 } 16 }
16 17
17 private static String baiduToken; 18 private static String baiduToken;
18 19
19 public static void setBaiduToken(String baiduToken) { 20 public static void setBaiduToken(String baiduToken) {
20 App.baiduToken = baiduToken; 21 App.baiduToken = baiduToken;
21 } 22 }
22 23
23 public static String getBaiduToken() { 24 public static String getBaiduToken() {
24 return baiduToken; 25 return baiduToken;
25 } 26 }
26 27
27 private static List<GradeAndSubject> gradeAndSubjects; 28 private static List<GradeAndSubject> gradeAndSubjects = new ArrayList<>();
28 29
29 public void setGradeAndSubjects(List<GradeAndSubject> gradeAndSubjects) { 30 public void setGradeAndSubjects(List<GradeAndSubject> gradeAndSubjects) {
30 App.gradeAndSubjects = gradeAndSubjects; 31 App.gradeAndSubjects = gradeAndSubjects == null ? App.gradeAndSubjects : gradeAndSubjects;
31 } 32 }
32 33
33 public List<GradeAndSubject> getGradeAndSubjects() { 34 public List<GradeAndSubject> getGradeAndSubjects() {
35 if (gradeAndSubjects == null) gradeAndSubjects = new ArrayList<>();
34 return gradeAndSubjects; 36 return gradeAndSubjects;
35 } 37 }
36 38
37 @Override 39 @Override
38 public void onCreate() { 40 public void onCreate() {
39 super.onCreate(); 41 super.onCreate();
40 this.instance = this; 42 this.instance = this;
41 SharedPreferencesUtil.getInstance(this, "config"); 43 SharedPreferencesUtil.getInstance(this, "config");
42 SharedPreferencesUtil.checkVersion(this); 44 SharedPreferencesUtil.checkVersion(this);
43 ZXingLibrary.initDisplayOpinion(this); 45 ZXingLibrary.initDisplayOpinion(this);
44 } 46 }
45 } 47 }
46 48
app/src/main/java/com/hjx/parent/ImageActivity.java
1 package com.hjx.parent; 1 package com.hjx.parent;
2 2
3 import android.annotation.SuppressLint; 3 import android.annotation.SuppressLint;
4 import android.app.Dialog; 4 import android.app.Dialog;
5 import android.content.Intent; 5 import android.content.Intent;
6 import android.graphics.Bitmap; 6 import android.graphics.Bitmap;
7 import android.graphics.BitmapFactory; 7 import android.graphics.BitmapFactory;
8 import android.graphics.Rect; 8 import android.graphics.Rect;
9 import android.net.Uri; 9 import android.net.Uri;
10 import android.os.Bundle; 10 import android.os.Bundle;
11 import android.os.Handler; 11 import android.os.Handler;
12 import android.provider.MediaStore; 12 import android.provider.MediaStore;
13 import android.text.TextUtils; 13 import android.text.TextUtils;
14 import android.util.Log; 14 import android.util.Log;
15 import android.view.KeyEvent; 15 import android.view.KeyEvent;
16 import android.view.View; 16 import android.view.View;
17 17
18 18
19 import androidx.annotation.Nullable; 19 import androidx.annotation.Nullable;
20 import androidx.core.content.FileProvider; 20 import androidx.core.content.FileProvider;
21 import androidx.viewpager2.widget.ViewPager2; 21 import androidx.viewpager2.widget.ViewPager2;
22 22
23 import com.google.gson.Gson; 23 import com.google.gson.Gson;
24 import com.google.gson.JsonObject; 24 import com.google.gson.JsonObject;
25 import com.hjx.parent.adapter.ImageAdapter; 25 import com.hjx.parent.adapter.ImageAdapter;
26 import com.hjx.parent.databinding.ActivityImageBinding; 26 import com.hjx.parent.databinding.ActivityImageBinding;
27 import com.hjx.parent.databinding.ItemImageBinding; 27 import com.hjx.parent.databinding.ItemImageBinding;
28 import com.hjx.parent.dialog.AddHomeworkDialog; 28 import com.hjx.parent.dialog.AddHomeworkDialog;
29 import com.hjx.parent.dialog.ErrorInputDialog; 29 import com.hjx.parent.dialog.ErrorInputDialog;
30 import com.hjx.parent.dialog.PhotoViewDialog; 30 import com.hjx.parent.dialog.PhotoViewDialog;
31 import com.hjx.parent.dialog.TipDialog; 31 import com.hjx.parent.dialog.TipDialog;
32 import com.hjx.parent.rx.BaseRxActivity; 32 import com.hjx.parent.rx.BaseRxActivity;
33 import com.hjx.parent.utils.CutUtil; 33 import com.hjx.parent.utils.CutUtil;
34 import com.prws.common.bean.CutPicBean; 34 import com.prws.common.bean.CutPicBean;
35 import com.prws.common.bean.ImageBean; 35 import com.prws.common.bean.ImageBean;
36 import com.prws.common.bean.TopicBean; 36 import com.prws.common.bean.TopicBean;
37 import com.prws.common.net.NetWorks; 37 import com.prws.common.net.NetWorks;
38 import com.prws.common.utils.BitmapUtils; 38 import com.prws.common.utils.BitmapUtils;
39 import com.prws.common.utils.CommonUtil; 39 import com.prws.common.utils.CommonUtil;
40 import com.xiasuhuei321.loadingdialog.view.LoadingDialog; 40 import com.xiasuhuei321.loadingdialog.view.LoadingDialog;
41 41
42 import java.io.File; 42 import java.io.File;
43 import java.util.ArrayList; 43 import java.util.ArrayList;
44 import java.util.List; 44 import java.util.List;
45 import java.util.stream.Collectors; 45 import java.util.stream.Collectors;
46 46
47 import io.reactivex.Observer; 47 import io.reactivex.Observer;
48 import io.reactivex.Single; 48 import io.reactivex.Single;
49 import io.reactivex.disposables.Disposable; 49 import io.reactivex.disposables.Disposable;
50 50
51 public class ImageActivity extends BaseRxActivity<ActivityImageBinding> implements View.OnClickListener { 51 public class ImageActivity extends BaseRxActivity<ActivityImageBinding> implements View.OnClickListener {
52 52
53 private final List<String> images = new ArrayList<>(); 53 private final List<String> images = new ArrayList<>();
54 private ImageAdapter imageAdapter; 54 private ImageAdapter imageAdapter;
55 private List<ImageBean> list = new ArrayList<>(); 55 private List<ImageBean> list = new ArrayList<>();
56 private String filePath; 56 private String filePath;
57 57
58 private int type = 0; 58 private int type = 0;
59 private AddHomeworkDialog addHomeworkDialog; 59 private AddHomeworkDialog addHomeworkDialog;
60 60
61 @SuppressLint("CheckResult") 61 @SuppressLint("CheckResult")
62 @Override 62 @Override
63 public void initView(Bundle savedInstanceState) { 63 public void initView(Bundle savedInstanceState) {
64 type = getIntent().getIntExtra("type", 0); 64 type = getIntent().getIntExtra("type", 0);
65 binding.tvSave.setText(type == 0 ? "保存错题" : "录入题目"); 65 binding.tvSave.setText(type == 0 ? "保存错题" : "录入题目");
66 66
67 List<String> originList = getIntent().getStringArrayListExtra("images"); 67 List<String> originList = getIntent().getStringArrayListExtra("images");
68 List<String> originListFinal = originList == null ? new ArrayList<>() : originList; 68 List<String> originListFinal = originList == null ? new ArrayList<>() : originList;
69 Single.fromCallable(() -> CutUtil.compressAllSync(this, originListFinal, 200)) 69 Single.fromCallable(() -> CutUtil.compressAllSync(this, originListFinal, 200))
70 .map(it -> it.stream().map(File::getAbsolutePath).collect(Collectors.toList())) 70 .map(it -> it.stream().map(File::getAbsolutePath).collect(Collectors.toList()))
71 .compose(transformSingle()) 71 .compose(transformSingle())
72 .subscribe((it, throwable) -> { 72 .subscribe((it, throwable) -> {
73 if (throwable != null) Log.e(getClass().getName(), "", throwable); 73 if (throwable != null) Log.e(getClass().getName(), "", throwable);
74 images.clear(); 74 images.clear();
75 if (it == null) { 75 if (it == null) {
76 images.addAll(originListFinal); 76 images.addAll(originListFinal);
77 } else { 77 } else {
78 images.addAll(it); 78 images.addAll(it);
79 } 79 }
80 start(); 80 start();
81 }); 81 });
82 } 82 }
83 83
84 private void start() { 84 private void start() {
85 if (images == null || images.size() <= 1) { 85 if (images == null || images.size() <= 1) {
86 binding.rlPrevious.setVisibility(View.GONE); 86 binding.rlPrevious.setVisibility(View.GONE);
87 binding.rlNext.setVisibility(View.GONE); 87 binding.rlNext.setVisibility(View.GONE);
88 } 88 }
89 for (String s : images) { 89 for (String s : images) {
90 String filepath = context.getExternalFilesDir("images").getPath() + "/" + System.currentTimeMillis() + CommonUtil.getStr() + ".jpg"; 90 String filepath = context.getExternalFilesDir("images").getPath() + "/" + System.currentTimeMillis() + CommonUtil.getStr() + ".jpg";
91 ImageBean imageBean = new ImageBean(); 91 ImageBean imageBean = new ImageBean();
92 Bitmap bitmap = BitmapUtils.getimage(s); 92 Bitmap bitmap = BitmapUtils.getimage(s);
93 CommonUtil.saveBitmapToUri(bitmap, filepath); 93 CommonUtil.saveBitmapToUri(bitmap, filepath);
94 imageBean.setPath(filepath); 94 imageBean.setPath(filepath);
95 imageBean.source = filepath; 95 imageBean.source = filepath;
96 list.add(imageBean); 96 list.add(imageBean);
97 } 97 }
98 imageAdapter = new ImageAdapter(this, list); 98 imageAdapter = new ImageAdapter(this, list);
99 binding.viewPager.setAdapter(imageAdapter); 99 binding.viewPager.setAdapter(imageAdapter);
100 binding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { 100 binding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
101 @Override 101 @Override
102 public void onPageSelected(int position) { 102 public void onPageSelected(int position) {
103 if (list.get(position).getCuts() == null) { 103 if (list.get(position).getCuts() == null) {
104 clearText(); 104 clearText();
105 } 105 }
106 binding.tvTitle.setText((binding.viewPager.getCurrentItem() + 1) + "/" + list.size()); 106 binding.tvTitle.setText((binding.viewPager.getCurrentItem() + 1) + "/" + list.size());
107 if (position == 0) { 107 if (position == 0) {
108 binding.ivPrevious.setImageResource(R.mipmap.ic_previous_gray); 108 binding.ivPrevious.setImageResource(R.mipmap.ic_previous_gray);
109 } else { 109 } else {
110 binding.ivPrevious.setImageResource(R.mipmap.ic_previous); 110 binding.ivPrevious.setImageResource(R.mipmap.ic_previous);
111 } 111 }
112 if (position == list.size() - 1) { 112 if (position == list.size() - 1) {
113 binding.ivNext.setImageResource(R.mipmap.ic_next_gray); 113 binding.ivNext.setImageResource(R.mipmap.ic_next_gray);
114 } else { 114 } else {
115 binding.ivNext.setImageResource(R.mipmap.ic_next); 115 binding.ivNext.setImageResource(R.mipmap.ic_next);
116 } 116 }
117 super.onPageSelected(position); 117 super.onPageSelected(position);
118 } 118 }
119 }); 119 });
120 binding.rlNext.setOnClickListener(this); 120 binding.rlNext.setOnClickListener(this);
121 binding.rlPrevious.setOnClickListener(this); 121 binding.rlPrevious.setOnClickListener(this);
122 binding.ivBack.setOnClickListener(this); 122 binding.ivBack.setOnClickListener(this);
123 binding.tvPhoto.setOnClickListener(this); 123 binding.tvPhoto.setOnClickListener(this);
124 binding.tvAdd.setOnClickListener(this); 124 binding.tvAdd.setOnClickListener(this);
125 binding.llEdit.setOnClickListener(this); 125 binding.llEdit.setOnClickListener(this);
126 binding.tvSave.setOnClickListener(this); 126 binding.tvSave.setOnClickListener(this);
127 binding.btnShowSource.setOnClickListener(v -> { 127 binding.btnShowSource.setOnClickListener(v -> {
128 if (list.isEmpty()) return; 128 if (list.isEmpty()) return;
129 ImageBean data = list.get(binding.viewPager.getCurrentItem()); 129 ImageBean data = list.get(binding.viewPager.getCurrentItem());
130 new PhotoViewDialog(this).show(data.source); 130 new PhotoViewDialog(this).show(data.source);
131 }); 131 });
132 132
133 binding.btnJudge.setVisibility(type == 0 ? View.VISIBLE : View.GONE); 133 binding.btnJudge.setVisibility(type == 0 ? View.VISIBLE : View.GONE);
134 binding.btnJudge.setOnClickListener(v -> { 134 binding.btnJudge.setOnClickListener(v -> {
135 goJudge(); 135 goJudge();
136 }); 136 });
137 } 137 }
138 138
139 private void goJudge() { 139 private void goJudge() {
140 if (list.isEmpty()) return; 140 if (list.isEmpty()) return;
141 int position = binding.viewPager.getCurrentItem(); 141 int position = binding.viewPager.getCurrentItem();
142 ImageBean imageBean = list.get(position); 142 ImageBean imageBean = list.get(position);
143 Bitmap bitmap = BitmapFactory.decodeFile(imageBean.getPath()); 143 Bitmap bitmap = BitmapFactory.decodeFile(imageBean.getPath());
144 if (bitmap == null || imageBean.getCuts() == null) { 144 if (bitmap == null || imageBean.getCuts() == null) {
145 showToast("请先框选题目"); 145 showToast("请先框选题目");
146 return; 146 return;
147 } 147 }
148 ItemImageBinding ib = imageAdapter.viewArray.get(position); 148 ItemImageBinding ib = imageAdapter.viewArray.get(position);
149 if (ib == null) { 149 if (ib == null) {
150 showToast("出错"); 150 showToast("出错");
151 return; 151 return;
152 } 152 }
153 View view = ib.ivPic; 153 View view = ib.ivPic;
154 float[] size = CutUtil.measureBitmap(view, bitmap); 154 float[] size = CutUtil.measureBitmap(view, bitmap);
155 155
156 ArrayList<Rect> rects = new ArrayList<>(); 156 ArrayList<Rect> rects = new ArrayList<>();
157 for (ImageBean.Cut cut: imageBean.getCuts()) { 157 for (ImageBean.Cut cut: imageBean.getCuts()) {
158 if (cut.getRect1() == null) continue; 158 if (cut.getRect1() == null || !cut.isSelect()) continue;
159 Rect rectV = cut.getRect1(); 159 Rect rectV = cut.getRect1();
160 rects.add(getRectB(rectV, bitmap, size)); 160 rects.add(getRectB(rectV, bitmap, size));
161 } 161 }
162 if (list.isEmpty()) { 162 if (list.isEmpty()) {
163 showToast("请先框选题目"); 163 showToast("请选择要批改的题目");
164 return; 164 return;
165 } 165 }
166 166
167 Intent intent = new Intent(this, JudgeActivity.class); 167 Intent intent = new Intent(this, JudgeActivity.class);
168 intent.putExtra("path", imageBean.getPath()); 168 intent.putExtra("path", imageBean.getPath());
169 intent.putParcelableArrayListExtra("rects", rects); 169 intent.putParcelableArrayListExtra("rects", rects);
170 170
171 startActivity(intent); 171 startActivity(intent);
172 } 172 }
173 173
174 private Rect getRectB(Rect rectV, Bitmap bitmap, float[] measuredSize) { 174 private Rect getRectB(Rect rectV, Bitmap bitmap, float[] measuredSize) {
175 float realW = measuredSize[0]; 175 float realW = measuredSize[0];
176 float realH = measuredSize[1]; 176 float realH = measuredSize[1];
177 float offsetX = measuredSize[2]; 177 float offsetX = measuredSize[2];
178 float offsetY = measuredSize[3]; 178 float offsetY = measuredSize[3];
179 float percentX = bitmap.getWidth() / realW; 179 float percentX = bitmap.getWidth() / realW;
180 float percentY = bitmap.getHeight() / realH; 180 float percentY = bitmap.getHeight() / realH;
181 181
182 float left = (rectV.left - offsetX) * percentX; 182 float left = (rectV.left - offsetX) * percentX;
183 float right = (rectV.right - offsetX) * percentX; 183 float right = (rectV.right - offsetX) * percentX;
184 float top = (rectV.top - offsetY) * percentY; 184 float top = (rectV.top - offsetY) * percentY;
185 float bottom = (rectV.bottom - offsetY) * percentY; 185 float bottom = (rectV.bottom - offsetY) * percentY;
186 Rect rectB = new Rect((int) left, (int) top, (int) right, (int) bottom); 186 Rect rectB = new Rect((int) left, (int) top, (int) right, (int) bottom);
187 return rectB; 187 return rectB;
188 } 188 }
189 189
190 public void clearText() { 190 public void clearText() {
191 int index = binding.viewPager.getCurrentItem(); 191 int index = binding.viewPager.getCurrentItem();
192 showLoadingDialog(getString(R.string.loading_text), new LoadingDialog.DismissListener() { 192 showLoadingDialog(getString(R.string.loading_text), new LoadingDialog.DismissListener() {
193 @Override 193 @Override
194 public void dimiss() { 194 public void dimiss() {
195 // binding.ivPrevious.setEnabled(index != 0); 195 // binding.ivPrevious.setEnabled(index != 0);
196 // binding.ivNext.setEnabled(index != list.size() - 1); 196 // binding.ivNext.setEnabled(index != list.size() - 1);
197 } 197 }
198 }); 198 });
199 Log.i("clearText", list.get(index).getPath()); 199 Log.i("clearText", list.get(index).getPath());
200 String base64 = BitmapUtils.imageToBase64(list.get(index).getPath(), false); 200 String base64 = BitmapUtils.imageToBase64(list.get(index).getPath(), false);
201 NetWorks.baiduEnhance(base64, new Observer<JsonObject>() { 201 NetWorks.baiduEnhance(base64, new Observer<JsonObject>() {
202 @Override 202 @Override
203 public void onSubscribe(Disposable d) { 203 public void onSubscribe(Disposable d) {
204 204
205 } 205 }
206 206
207 @Override 207 @Override
208 public void onNext(JsonObject jsonObject) { 208 public void onNext(JsonObject jsonObject) {
209 if (jsonObject != null && jsonObject.get("image_processed") != null) { 209 if (jsonObject != null && jsonObject.get("image_processed") != null) {
210 String image = jsonObject.get("image_processed").getAsString(); 210 String image = jsonObject.get("image_processed").getAsString();
211 if (image != null) { 211 if (image != null) {
212 String filepath = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg"; 212 String filepath = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg";
213 CommonUtil.saveBitmapToUri(BitmapUtils.stringToBitmap(image), filepath); 213 CommonUtil.saveBitmapToUri(BitmapUtils.stringToBitmap(image), filepath);
214 list.get(index).setPath(filepath); 214 list.get(index).setPath(filepath);
215 if (list.get(index).getCuts() == null) { 215 if (list.get(index).getCuts() == null) {
216 list.get(index).setCuts(new ArrayList<>()); 216 list.get(index).setCuts(new ArrayList<>());
217 } 217 }
218 imageAdapter.notifyItemChanged(index); 218 imageAdapter.notifyItemChanged(index);
219 cut(filepath); 219 cut(filepath);
220 } else { 220 } else {
221 loadFail("去除字迹失败"); 221 loadFail("去除字迹失败");
222 } 222 }
223 } else { 223 } else {
224 loadFail("去除字迹失败"); 224 loadFail("去除字迹失败");
225 } 225 }
226 } 226 }
227 227
228 @Override 228 @Override
229 public void onError(Throwable e) { 229 public void onError(Throwable e) {
230 e.printStackTrace(); 230 e.printStackTrace();
231 loadFail("去除字迹失败"); 231 loadFail("去除字迹失败");
232 } 232 }
233 233
234 @Override 234 @Override
235 public void onComplete() { 235 public void onComplete() {
236 236
237 } 237 }
238 }); 238 });
239 } 239 }
240 240
241 public void cut(String path) { 241 public void cut(String path) {
242 String base64 = BitmapUtils.imageToBase64WithUrlEncode(path); 242 String base64 = BitmapUtils.imageToBase64WithUrlEncode(path);
243 Log.i("figLoaction", path); 243 Log.i("figLoaction", path);
244 NetWorks.cut(base64, new Observer<CutPicBean>() { 244 NetWorks.cut(base64, new Observer<CutPicBean>() {
245 @Override 245 @Override
246 public void onSubscribe(Disposable d) { 246 public void onSubscribe(Disposable d) {
247 247
248 } 248 }
249 249
250 @Override 250 @Override
251 public void onNext(CutPicBean cutPicBean) { 251 public void onNext(CutPicBean cutPicBean) {
252 if (cutPicBean != null) { 252 if (cutPicBean != null) {
253 if (cutPicBean.getDirection() != 0) { 253 if (cutPicBean.getDirection() != 0) {
254 rotatingImage(cutPicBean); 254 rotatingImage(cutPicBean);
255 } else { 255 } else {
256 if (cutPicBean.getQus_figure() != null && cutPicBean.getQus_figure().size() > 0) { 256 if (cutPicBean.getQus_figure() != null && cutPicBean.getQus_figure().size() > 0) {
257 List<CutPicBean.FigLoaction> figLoactions = new ArrayList<>(); 257 List<CutPicBean.FigLoaction> figLoactions = new ArrayList<>();
258 for (CutPicBean.CutLocation cutLocation : cutPicBean.getQus_figure()) { 258 for (CutPicBean.CutLocation cutLocation : cutPicBean.getQus_figure()) {
259 figLoactions.add(cutLocation.getFig_location()); 259 figLoactions.add(cutLocation.getFig_location());
260 } 260 }
261 new Handler().postDelayed(new Runnable() { 261 new Handler().postDelayed(new Runnable() {
262 @Override 262 @Override
263 public void run() { 263 public void run() {
264 getRects(figLoactions); 264 getRects(figLoactions);
265 } 265 }
266 }, 1000); 266 }, 1000);
267 } else { 267 } else {
268 cancelLoadingDialog(); 268 cancelLoadingDialog();
269 } 269 }
270 } 270 }
271 } else { 271 } else {
272 loadFail("自动切题失败"); 272 loadFail("自动切题失败");
273 } 273 }
274 } 274 }
275 275
276 @Override 276 @Override
277 public void onError(Throwable e) { 277 public void onError(Throwable e) {
278 loadFail("自动切题失败"); 278 loadFail("自动切题失败");
279 } 279 }
280 280
281 @Override 281 @Override
282 public void onComplete() { 282 public void onComplete() {
283 283
284 } 284 }
285 }); 285 });
286 } 286 }
287 287
288 private void getRects(List<CutPicBean.FigLoaction> figLoactions) { 288 private void getRects(List<CutPicBean.FigLoaction> figLoactions) {
289 Log.i("figLoaction", new Gson().toJson(figLoactions)); 289 Log.i("figLoaction", new Gson().toJson(figLoactions));
290 int index = binding.viewPager.getCurrentItem(); 290 int index = binding.viewPager.getCurrentItem();
291 List<ImageBean.Cut> cuts = new ArrayList<>(); 291 List<ImageBean.Cut> cuts = new ArrayList<>();
292 for (CutPicBean.FigLoaction figLoaction : figLoactions) { 292 for (CutPicBean.FigLoaction figLoaction : figLoactions) {
293 ImageBean.Cut cut = new ImageBean.Cut(); 293 ImageBean.Cut cut = new ImageBean.Cut();
294 cut.setRect(figLoaction); 294 cut.setRect(figLoaction);
295 cut.setSelect(false); 295 cut.setSelect(true);
296 cuts.add(cut); 296 cuts.add(cut);
297 } 297 }
298 list.get(index).setCuts(cuts); 298 list.get(index).setCuts(cuts);
299 imageAdapter.notifyItemChanged(index); 299 imageAdapter.notifyItemChanged(index);
300 cancelLoadingDialog(); 300 cancelLoadingDialog();
301 } 301 }
302 302
303 private void rotatingImage(CutPicBean cutPicBean) { 303 private void rotatingImage(CutPicBean cutPicBean) {
304 int index = binding.viewPager.getCurrentItem(); 304 int index = binding.viewPager.getCurrentItem();
305 Bitmap bitmap = BitmapFactory.decodeFile(list.get(index).getPath()); 305 Bitmap bitmap = BitmapFactory.decodeFile(list.get(index).getPath());
306 int angle = 0; 306 int angle = 0;
307 switch (cutPicBean.getDirection()) { 307 switch (cutPicBean.getDirection()) {
308 case 1: 308 case 1:
309 angle = 90; 309 angle = 90;
310 break; 310 break;
311 case 2: 311 case 2:
312 angle = 180; 312 angle = 180;
313 break; 313 break;
314 case 3: 314 case 3:
315 angle = 270; 315 angle = 270;
316 break; 316 break;
317 } 317 }
318 if (cutPicBean.getQus_figure() != null && cutPicBean.getQus_figure().size() > 0) { 318 if (cutPicBean.getQus_figure() != null && cutPicBean.getQus_figure().size() > 0) {
319 List<CutPicBean.FigLoaction> figLoactions = new ArrayList<>(); 319 List<CutPicBean.FigLoaction> figLoactions = new ArrayList<>();
320 for (CutPicBean.CutLocation cutLocation : cutPicBean.getQus_figure()) { 320 for (CutPicBean.CutLocation cutLocation : cutPicBean.getQus_figure()) {
321 figLoactions.add(cutLocation.getFig_location()); 321 figLoactions.add(cutLocation.getFig_location());
322 } 322 }
323 figLoactions = CommonUtil.rotaingLocation(angle, figLoactions, bitmap.getWidth(), bitmap.getHeight()); 323 figLoactions = CommonUtil.rotaingLocation(angle, figLoactions, bitmap.getWidth(), bitmap.getHeight());
324 bitmap = CommonUtil.rotaingImageView(angle, bitmap); 324 bitmap = CommonUtil.rotaingImageView(angle, bitmap);
325 String filepath = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg"; 325 String filepath = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg";
326 CommonUtil.saveBitmapToUri(bitmap, filepath); 326 CommonUtil.saveBitmapToUri(bitmap, filepath);
327 list.get(index).setPath(filepath); 327 list.get(index).setPath(filepath);
328 imageAdapter.notifyItemChanged(index); 328 imageAdapter.notifyItemChanged(index);
329 List<CutPicBean.FigLoaction> finalFigLoactions = figLoactions; 329 List<CutPicBean.FigLoaction> finalFigLoactions = figLoactions;
330 new Handler().postDelayed(new Runnable() { 330 new Handler().postDelayed(new Runnable() {
331 @Override 331 @Override
332 public void run() { 332 public void run() {
333 getRects(finalFigLoactions); 333 getRects(finalFigLoactions);
334 } 334 }
335 }, 500); 335 }, 500);
336 } else { 336 } else {
337 cancelLoadingDialog(); 337 cancelLoadingDialog();
338 } 338 }
339 } 339 }
340 340
341 @Override 341 @Override
342 protected ActivityImageBinding getViewBinding() { 342 protected ActivityImageBinding getViewBinding() {
343 return ActivityImageBinding.inflate(getLayoutInflater()); 343 return ActivityImageBinding.inflate(getLayoutInflater());
344 } 344 }
345 345
346 @SuppressLint("SetTextI18n") 346 @SuppressLint("SetTextI18n")
347 public void refreshNum() { 347 public void refreshNum() {
348 int num = 0; 348 int num = 0;
349 for (ImageBean imageBean : list) { 349 for (ImageBean imageBean : list) {
350 if (imageBean.getCuts() != null && imageBean.getCuts().size() > 0) { 350 if (imageBean.getCuts() != null && imageBean.getCuts().size() > 0) {
351 for (ImageBean.Cut cut : imageBean.getCuts()) { 351 for (ImageBean.Cut cut : imageBean.getCuts()) {
352 if (cut.isSelect()) { 352 if (cut.isSelect()) {
353 num++; 353 num++;
354 } 354 }
355 } 355 }
356 } 356 }
357 } 357 }
358 String btnText = type == 0 ? "保存错题" : "录入题目"; 358 String btnText = type == 0 ? "保存错题" : "录入题目";
359 if (num > 0) { 359 if (num > 0) {
360 binding.tvSave.setEnabled(true); 360 binding.tvSave.setEnabled(true);
361 binding.tvSave.setBackgroundResource(R.drawable.bg_soild_blue_5); 361 binding.tvSave.setBackgroundResource(R.drawable.bg_soild_blue_5);
362 binding.tvSave.setText(btnText + "(" + num + ")"); 362 binding.tvSave.setText(btnText + "(" + num + ")");
363 } else { 363 } else {
364 binding.tvSave.setEnabled(false); 364 binding.tvSave.setEnabled(false);
365 binding.tvSave.setBackgroundResource(R.drawable.bg_soild_blue_light_5); 365 binding.tvSave.setBackgroundResource(R.drawable.bg_soild_blue_light_5);
366 binding.tvSave.setText(btnText); 366 binding.tvSave.setText(btnText);
367 } 367 }
368 } 368 }
369 369
370 @Override 370 @Override
371 public void onClick(View v) { 371 public void onClick(View v) {
372 switch (v.getId()) { 372 switch (v.getId()) {
373 case R.id.iv_back: 373 case R.id.iv_back:
374 back(); 374 back();
375 break; 375 break;
376 case R.id.rl_next: 376 case R.id.rl_next:
377 if (binding.viewPager.getCurrentItem() + 1 < list.size()) { 377 if (binding.viewPager.getCurrentItem() + 1 < list.size()) {
378 binding.viewPager.setCurrentItem(binding.viewPager.getCurrentItem() + 1); 378 binding.viewPager.setCurrentItem(binding.viewPager.getCurrentItem() + 1);
379 } 379 }
380 break; 380 break;
381 case R.id.rl_previous: 381 case R.id.rl_previous:
382 if (binding.viewPager.getCurrentItem() != 0) { 382 if (binding.viewPager.getCurrentItem() != 0) {
383 binding.viewPager.setCurrentItem(binding.viewPager.getCurrentItem() - 1); 383 binding.viewPager.setCurrentItem(binding.viewPager.getCurrentItem() - 1);
384 } 384 }
385 break; 385 break;
386 case R.id.ll_edit: 386 case R.id.ll_edit:
387 Intent intent = new Intent(context, ImageEditActivity.class); 387 Intent intent = new Intent(context, ImageEditActivity.class);
388 intent.putExtra("path", list.get(binding.viewPager.getCurrentItem()).getPath()); 388 intent.putExtra("path", list.get(binding.viewPager.getCurrentItem()).getPath());
389 startActivityForResult(intent, 1001); 389 startActivityForResult(intent, 1001);
390 break; 390 break;
391 case R.id.tv_photo: 391 case R.id.tv_photo:
392 Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 392 Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
393 //确保有相机来处理Intent 393 //确保有相机来处理Intent
394 filePath = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg"; 394 filePath = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg";
395 File photoFile = new File(filePath); 395 File photoFile = new File(filePath);
396 if (photoFile != null) { 396 if (photoFile != null) {
397 //适配Android 7.0文件权限,通过FileProvider创建一个content类型的Uri 397 //适配Android 7.0文件权限,通过FileProvider创建一个content类型的Uri
398 Uri photoUri = FileProvider.getUriForFile(activity, "com.hjx.parent.fileprovider", photoFile); 398 Uri photoUri = FileProvider.getUriForFile(activity, "com.hjx.parent.fileprovider", photoFile);
399 takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 399 takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
400 takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); 400 takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
401 activity.startActivityForResult(takePictureIntent, 1002); 401 activity.startActivityForResult(takePictureIntent, 1002);
402 } 402 }
403 break; 403 break;
404 case R.id.tv_add: 404 case R.id.tv_add:
405 Intent intent1 = new Intent(context, ImageSelectActivity.class); 405 Intent intent1 = new Intent(context, ImageSelectActivity.class);
406 intent1.putExtra("path", list.get(binding.viewPager.getCurrentItem()).getPath()); 406 intent1.putExtra("path", list.get(binding.viewPager.getCurrentItem()).getPath());
407 intent1.putExtra("source", list.get(binding.viewPager.getCurrentItem()).source); 407 intent1.putExtra("source", list.get(binding.viewPager.getCurrentItem()).source);
408 startActivityForResult(intent1, 1001); 408 startActivityForResult(intent1, 1001);
409 break; 409 break;
410 case R.id.tv_save: 410 case R.id.tv_save:
411 List<TopicBean> topicBeans = new ArrayList<>(); 411 List<TopicBean> topicBeans = new ArrayList<>();
412 for (ImageBean imageBean : list) { 412 for (ImageBean imageBean : list) {
413 if (imageBean.getCuts() != null && imageBean.getCuts().size() > 0) { 413 if (imageBean.getCuts() != null && imageBean.getCuts().size() > 0) {
414 for (ImageBean.Cut cut : imageBean.getCuts()) { 414 for (ImageBean.Cut cut : imageBean.getCuts()) {
415 if (cut.isSelect()) { 415 if (cut.isSelect()) {
416 TopicBean bean = new TopicBean(); 416 TopicBean bean = new TopicBean();
417 String path = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg"; 417 String path = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg";
418 BitmapUtils.saveBitmap(cut.getBitmap(), path); 418 BitmapUtils.saveBitmap(cut.getBitmap(), path);
419 bean.setPath(path); 419 bean.setPath(path);
420 topicBeans.add(bean); 420 topicBeans.add(bean);
421 } 421 }
422 } 422 }
423 } 423 }
424 } 424 }
425 save(topicBeans); 425 save(topicBeans);
426 break; 426 break;
427 } 427 }
428 } 428 }
429 429
430 private void save(List<TopicBean> topicBeans) { 430 private void save(List<TopicBean> topicBeans) {
431 if (type == 0) { 431 if (type == 0) {
432 ErrorInputDialog dialog = new ErrorInputDialog(this, topicBeans); 432 ErrorInputDialog dialog = new ErrorInputDialog(this, topicBeans);
433 dialog.show(() -> { 433 dialog.show(() -> {
434 Intent intent = new Intent(this, AddSuccessActivity.class); 434 Intent intent = new Intent(this, AddSuccessActivity.class);
435 startActivity(intent); 435 startActivity(intent);
436 finish(); 436 finish();
437 }); 437 });
438 } else { 438 } else {
439 List<String> paths = new ArrayList<>(); 439 List<String> paths = new ArrayList<>();
440 for (TopicBean it: topicBeans) { 440 for (TopicBean it: topicBeans) {
441 paths.add(it.getPath()); 441 paths.add(it.getPath());
442 } 442 }
443 if (addHomeworkDialog == null) { 443 if (addHomeworkDialog == null) {
444 addHomeworkDialog = new AddHomeworkDialog(this); 444 addHomeworkDialog = new AddHomeworkDialog(this);
445 } 445 }
446 addHomeworkDialog.show(paths, student -> { 446 addHomeworkDialog.show(paths, student -> {
447 Intent intent = new Intent(context, AddSuccessActivity.class); 447 Intent intent = new Intent(context, AddSuccessActivity.class);
448 intent.putExtra("type", type); 448 intent.putExtra("type", type);
449 intent.putExtra("studentJson", new Gson().toJson(student)); 449 intent.putExtra("studentJson", new Gson().toJson(student));
450 startActivity(intent); 450 startActivity(intent);
451 finish(); 451 finish();
452 }); 452 });
453 } 453 }
454 } 454 }
455 455
456 @Override 456 @Override
457 protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { 457 protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
458 super.onActivityResult(requestCode, resultCode, data); 458 super.onActivityResult(requestCode, resultCode, data);
459 if (requestCode == 1001) { 459 if (requestCode == 1001) {
460 if (resultCode == 1002) { 460 if (resultCode == 1002) {
461 if (list.size() > 1) { 461 if (list.size() > 1) {
462 list.remove(binding.viewPager.getCurrentItem()); 462 list.remove(binding.viewPager.getCurrentItem());
463 if (list.size() <= 1) { 463 if (list.size() <= 1) {
464 binding.rlPrevious.setVisibility(View.GONE); 464 binding.rlPrevious.setVisibility(View.GONE);
465 binding.rlNext.setVisibility(View.GONE); 465 binding.rlNext.setVisibility(View.GONE);
466 } 466 }
467 imageAdapter.notifyItemRemoved(binding.viewPager.getCurrentItem()); 467 imageAdapter.notifyItemRemoved(binding.viewPager.getCurrentItem());
468 binding.tvTitle.setText((binding.viewPager.getCurrentItem() + 1) + "/" + list.size()); 468 binding.tvTitle.setText((binding.viewPager.getCurrentItem() + 1) + "/" + list.size());
469 refreshNum(); 469 refreshNum();
470 } else { 470 } else {
471 finish(); 471 finish();
472 } 472 }
473 } else if (resultCode == 1003) { 473 } else if (resultCode == 1003) {
474 int position = binding.viewPager.getCurrentItem(); 474 int position = binding.viewPager.getCurrentItem();
475 String src = list.get(position).source; 475 String src = list.get(position).source;
476 list.remove(position); 476 list.remove(position);
477 String path = data.getStringExtra("path"); 477 String path = data.getStringExtra("path");
478 ImageBean imageBean = new ImageBean(); 478 ImageBean imageBean = new ImageBean();
479 imageBean.setPath(path); 479 imageBean.setPath(path);
480 imageBean.source = src; 480 imageBean.source = src;
481 list.add(position, imageBean); 481 list.add(position, imageBean);
482 imageAdapter.notifyItemChanged(position); 482 imageAdapter.notifyItemChanged(position);
483 clearText(); 483 clearText();
484 refreshNum(); 484 refreshNum();
485 } else if (resultCode == 1004) { 485 } else if (resultCode == 1004) {
486 Rect rect = data.getParcelableExtra("cut"); 486 Rect rect = data.getParcelableExtra("cut");
487 if (rect != null) { 487 if (rect != null) {
488 int position = binding.viewPager.getCurrentItem(); 488 int position = binding.viewPager.getCurrentItem();
489 ImageBean.Cut cut = new ImageBean.Cut(); 489 ImageBean.Cut cut = new ImageBean.Cut();
490 cut.setRect1(rect); 490 cut.setRect1(rect);
491 cut.setSelect(false); 491 cut.setSelect(false);
492 if (list.get(position).getCuts() != null) { 492 if (list.get(position).getCuts() != null) {
493 list.get(position).getCuts().add(cut); 493 list.get(position).getCuts().add(cut);
494 } else { 494 } else {
495 List<ImageBean.Cut> cuts =new ArrayList<>(); 495 List<ImageBean.Cut> cuts =new ArrayList<>();
496 cuts.add(cut); 496 cuts.add(cut);
497 list.get(position).setCuts(cuts); 497 list.get(position).setCuts(cuts);
498 } 498 }
499 imageAdapter.notifyItemChanged(position); 499 imageAdapter.notifyItemChanged(position);
500 refreshNum(); 500 refreshNum();
501 } 501 }
502 } else if (resultCode == 1005) { 502 } else if (resultCode == 1005) {
503 int i = data.getIntExtra("position", 0); 503 int i = data.getIntExtra("position", 0);
504 int position = binding.viewPager.getCurrentItem(); 504 int position = binding.viewPager.getCurrentItem();
505 Rect rect = data.getParcelableExtra("cut"); 505 Rect rect = data.getParcelableExtra("cut");
506 if (rect != null) { 506 if (rect != null) {
507 ImageBean.Cut cut = new ImageBean.Cut(); 507 ImageBean.Cut cut = new ImageBean.Cut();
508 cut.setRect1(rect); 508 cut.setRect1(rect);
509 cut.setSelect(false); 509 cut.setSelect(false);
510 list.get(position).getCuts().remove(i); 510 list.get(position).getCuts().remove(i);
511 list.get(position).getCuts().add(i, cut); 511 list.get(position).getCuts().add(i, cut);
512 imageAdapter.notifyItemChanged(position); 512 imageAdapter.notifyItemChanged(position);
513 refreshNum(); 513 refreshNum();
514 } else { 514 } else {
515 list.get(position).getCuts().remove(i); 515 list.get(position).getCuts().remove(i);
516 imageAdapter.notifyItemChanged(position); 516 imageAdapter.notifyItemChanged(position);
517 refreshNum(); 517 refreshNum();
518 } 518 }
519 } 519 }
520 } else if (requestCode == 1002 && resultCode == RESULT_OK && !TextUtils.isEmpty(filePath)) { 520 } else if (requestCode == 1002 && resultCode == RESULT_OK && !TextUtils.isEmpty(filePath)) {
521 Bitmap b = BitmapUtils.compress(BitmapFactory.decodeFile(filePath)); 521 Bitmap b = BitmapUtils.compress(BitmapFactory.decodeFile(filePath));
522 String path = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg"; 522 String path = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg";
523 CommonUtil.saveBitmapToUri(b, path); 523 CommonUtil.saveBitmapToUri(b, path);
524 int position = binding.viewPager.getCurrentItem(); 524 int position = binding.viewPager.getCurrentItem();
525 list.remove(position); 525 list.remove(position);
526 ImageBean imageBean = new ImageBean(); 526 ImageBean imageBean = new ImageBean();
527 imageBean.setPath(path); 527 imageBean.setPath(path);
528 imageBean.source = path; 528 imageBean.source = path;
529 list.add(position, imageBean); 529 list.add(position, imageBean);
530 imageAdapter.notifyItemChanged(position); 530 imageAdapter.notifyItemChanged(position);
531 clearText(); 531 clearText();
532 refreshNum(); 532 refreshNum();
533 } 533 }
534 } 534 }
535 535
536 private void back() { 536 private void back() {
537 showTipDialog("温馨提示", "是否确认退出?", "取消", "确定", new TipDialog.TipDialogInterface() { 537 showTipDialog("温馨提示", "是否确认退出?", "取消", "确定", new TipDialog.TipDialogInterface() {
538 @Override 538 @Override
539 public void onConfirm(Dialog dialog) { 539 public void onConfirm(Dialog dialog) {
540 dialog.dismiss(); 540 dialog.dismiss();
541 finish(); 541 finish();
542 } 542 }
543 543
544 @Override 544 @Override
545 public void onCancel(Dialog dialog) { 545 public void onCancel(Dialog dialog) {
546 dialog.dismiss(); 546 dialog.dismiss();
547 } 547 }
548 }); 548 });
549 } 549 }
550 550
551 @Override 551 @Override
552 public boolean onKeyDown(int keyCode, KeyEvent event) { 552 public boolean onKeyDown(int keyCode, KeyEvent event) {
553 if (keyCode == KeyEvent.KEYCODE_BACK) { 553 if (keyCode == KeyEvent.KEYCODE_BACK) {
554 back(); 554 back();
555 return true; 555 return true;
556 } 556 }
557 return super.onKeyDown(keyCode, event); 557 return super.onKeyDown(keyCode, event);
558 } 558 }
559 } 559 }
560 560
app/src/main/java/com/hjx/parent/JudgeActivity.java
1 package com.hjx.parent; 1 package com.hjx.parent;
2 2
3 import android.annotation.SuppressLint; 3 import android.annotation.SuppressLint;
4 import android.content.Intent; 4 import android.content.Intent;
5 import android.graphics.Bitmap; 5 import android.graphics.Bitmap;
6 import android.graphics.Rect; 6 import android.graphics.Rect;
7 import android.os.Bundle; 7 import android.os.Bundle;
8 import android.util.Log; 8 import android.util.Log;
9 9
10 import com.bumptech.glide.Glide; 10 import com.bumptech.glide.Glide;
11 import com.hjx.parent.api.JudgeRepository; 11 import com.hjx.parent.api.JudgeRepository;
12 import com.hjx.parent.databinding.ActivityJudgeBinding; 12 import com.hjx.parent.databinding.ActivityJudgeBinding;
13 import com.hjx.parent.databinding.LayoutJudgeRectBinding; 13 import com.hjx.parent.databinding.LayoutJudgeRectBinding;
14 import com.hjx.parent.dialog.ErrorInputDialog; 14 import com.hjx.parent.dialog.ErrorInputDialog;
15 import com.hjx.parent.rx.BaseRxActivity; 15 import com.hjx.parent.rx.BaseRxActivity;
16 import com.hjx.parent.utils.CutUtil; 16 import com.hjx.parent.utils.CutUtil;
17 import com.prws.common.bean.TopicBean; 17 import com.prws.common.bean.TopicBean;
18 18
19 import java.io.File; 19 import java.io.File;
20 import java.util.ArrayList; 20 import java.util.ArrayList;
21 import java.util.List; 21 import java.util.List;
22 import java.util.stream.Collectors; 22 import java.util.stream.Collectors;
23 23
24 import io.reactivex.Observable; 24 import io.reactivex.Observable;
25 import io.reactivex.Single; 25 import io.reactivex.Single;
26 import top.zibin.luban.Luban; 26 import top.zibin.luban.Luban;
27 27
28 public class JudgeActivity extends BaseRxActivity<ActivityJudgeBinding> { 28 public class JudgeActivity extends BaseRxActivity<ActivityJudgeBinding> {
29 29
30 private Bitmap bitmap; 30 private Bitmap bitmap;
31 31
32 private final List<JudgeCut> mList = new ArrayList<>(); 32 private final List<JudgeCut> mList = new ArrayList<>();
33 33
34 @SuppressLint("CheckResult") 34 @SuppressLint("CheckResult")
35 @Override 35 @Override
36 public void initView(Bundle savedInstanceState) { 36 public void initView(Bundle savedInstanceState) {
37 binding.ivBack.setOnClickListener(v -> { 37 binding.ivBack.setOnClickListener(v -> {
38 onBackPressed(); 38 onBackPressed();
39 }); 39 });
40 String path = getIntent().getStringExtra("path"); 40 String path = getIntent().getStringExtra("path");
41 if (path == null) return; 41 if (path == null) return;
42 final ArrayList<Rect> rects = getIntent().getParcelableArrayListExtra("rects"); 42 final ArrayList<Rect> rects = getIntent().getParcelableArrayListExtra("rects");
43 if (rects == null) return; 43 if (rects == null) return;
44 44
45 Single.just(path) 45 Single.just(path)
46 .map(origin -> Luban.with(this).load(origin).ignoreBy(300).get().get(0)) 46 .map(origin -> Luban.with(this).load(origin).ignoreBy(300).get().get(0))
47 .map(file -> Glide.with(this).asBitmap().load(file).submit().get()) 47 .map(file -> Glide.with(this).asBitmap().load(file).submit().get())
48 .compose(transformSingle()) 48 .compose(transformSingle())
49 .subscribe((bitmap, th) -> { 49 .subscribe((bitmap, th) -> {
50 if (th != null) th.printStackTrace(); 50 if (th != null) th.printStackTrace();
51 if (bitmap == null) return; 51 if (bitmap == null) return;
52 this.bitmap = bitmap; 52 this.bitmap = bitmap;
53 53
54 binding.ivPic.setImageBitmap(bitmap); 54 binding.ivPic.setImageBitmap(bitmap);
55 CutUtil.onLayoutReady(binding.ivPic, v -> { 55 CutUtil.onLayoutReady(binding.ivPic, v -> {
56 prepareRects(rects); 56 prepareRects(rects);
57 }); 57 });
58 }); 58 });
59 binding.btnSelectAll.setOnClickListener(v -> { 59 binding.btnSelectAll.setOnClickListener(v -> {
60 if (mList.isEmpty()) return; 60 if (mList.isEmpty()) return;
61 mList.forEach(it -> it.vb.getRoot().setSelected(true)); 61 mList.forEach(it -> it.vb.getRoot().setSelected(true));
62 checkCount(); 62 checkCount();
63 }); 63 });
64 binding.btnSelectNone.setOnClickListener(v -> {
65 if (mList.isEmpty()) return;
66 mList.forEach(it -> it.vb.getRoot().setSelected(false));
67 checkCount();
68 });
64 binding.btnAdd.setOnClickListener(v -> { 69 binding.btnAdd.setOnClickListener(v -> {
65 if (mList.isEmpty()) return; 70 if (mList.isEmpty()) return;
66 List<TopicBean> selected = mList.stream() 71 List<TopicBean> selected = mList.stream()
67 .filter(it -> it.vb.getRoot().isSelected()) 72 .filter(it -> it.vb.getRoot().isSelected())
68 .map(it -> { 73 .map(it -> {
69 TopicBean bean = new TopicBean(); 74 TopicBean bean = new TopicBean();
70 bean.setPath(it.getPath()); 75 bean.setPath(it.getPath());
71 return bean; 76 return bean;
72 }) 77 })
73 .collect(Collectors.toList()); 78 .collect(Collectors.toList());
74 79
75 ErrorInputDialog dialog = new ErrorInputDialog(this, selected); 80 ErrorInputDialog dialog = new ErrorInputDialog(this, selected);
76 dialog.show(() -> { 81 dialog.show(() -> {
77 showToast("已加入错题本"); 82 showToast("已加入错题本");
78 finish(); 83 finish();
79 }); 84 });
80 }); 85 });
81 } 86 }
82 87
83 private void prepareRects(List<Rect> rects) { 88 private void prepareRects(List<Rect> rects) {
84 mList.clear(); 89 mList.clear();
85 binding.flRects.removeAllViews(); 90 binding.flRects.removeAllViews();
86 float[] measuredSize = CutUtil.measureBitmap(binding.ivPic, bitmap); 91 float[] measuredSize = CutUtil.measureBitmap(binding.ivPic, bitmap);
87 for (int i = 0; i < rects.size(); i++) { 92 for (int i = 0; i < rects.size(); i++) {
88 Rect it = rects.get(i); 93 Rect it = rects.get(i);
89 Bitmap bitmap = CutUtil.cut(this.bitmap, it.left, it.top, it.width(), it.height(), this); 94 Bitmap bitmap = CutUtil.cut(this.bitmap, it.left, it.top, it.width(), it.height(), this);
90 Rect rect = measureRect(it, measuredSize); 95 Rect rect = measureRect(it, measuredSize);
91 LayoutJudgeRectBinding vb = showRect(rect); 96 LayoutJudgeRectBinding vb = showRect(rect);
92 mList.add(new JudgeCut(i, bitmap, rect, vb)); 97 mList.add(new JudgeCut(i, bitmap, rect, vb));
93 } 98 }
94 99
95 judge(); 100 judge();
96 } 101 }
97 102
98 @SuppressLint("CheckResult") 103 @SuppressLint("CheckResult")
99 private void judge() { 104 private void judge() {
100 showLoadingDialog(""); 105 showLoadingDialog("");
101 Observable.fromIterable(mList) 106 Observable.fromIterable(mList)
102 .map(it -> { 107 .map(it -> {
103 if (it.url != null && !it.url.isEmpty()) return it; 108 if (it.url != null && !it.url.isEmpty()) return it;
104 String base64 = CutUtil.bitmapToBase64(it.bitmap, true); 109 String base64 = CutUtil.bitmapToBase64(it.bitmap, true);
105 it.url = base64; 110 it.url = base64;
106 return it; 111 return it;
107 }) 112 })
108 .flatMap(it -> JudgeRepository.singleJudge(it.url) 113 .flatMap(it -> JudgeRepository.singleJudge(it.url)
109 .map(result -> { 114 .map(result -> {
110 it.correctResult = result; 115 it.correctResult = result;
111 return it; 116 return it;
112 }) 117 })
113 .toObservable() 118 .toObservable()
114 ) 119 )
115 .compose(transform()) 120 .compose(transform())
116 .subscribe(it -> { 121 .subscribe(it -> {
117 if (it.correctResult == 1) { 122 if (it.correctResult == 1) {
118 it.vb.ivResult.setImageResource(R.drawable.png_ic_judge_correct); 123 it.vb.ivResult.setImageResource(R.drawable.png_ic_judge_correct);
119 } else if (it.correctResult == 2) { 124 } else if (it.correctResult == 2) {
120 it.vb.ivResult.setImageResource(R.drawable.png_ic_judge_wrong); 125 it.vb.ivResult.setImageResource(R.drawable.png_ic_judge_wrong);
121 } 126 }
122 it.vb.getRoot().setSelected(it.correctResult != 1); 127 it.vb.getRoot().setSelected(it.correctResult != 1);
123 checkCount(); 128 checkCount();
124 }, th -> { 129 }, th -> {
125 cancelLoadingDialog(); 130 cancelLoadingDialog();
126 Log.e(getClass().getName(), "", th); 131 Log.e(getClass().getName(), "", th);
127 }, this::cancelLoadingDialog) 132 }, this::cancelLoadingDialog)
128 ; 133 ;
129 } 134 }
130 135
131 private LayoutJudgeRectBinding showRect(Rect rect) { 136 private LayoutJudgeRectBinding showRect(Rect rect) {
132 LayoutJudgeRectBinding vb = LayoutJudgeRectBinding.inflate(getLayoutInflater(), binding.flRects, false); 137 LayoutJudgeRectBinding vb = LayoutJudgeRectBinding.inflate(getLayoutInflater(), binding.flRects, false);
133 138
134 vb.getRoot().setMinimumWidth(rect.width()); 139 vb.getRoot().setMinimumWidth(rect.width());
135 vb.getRoot().setMinimumHeight(rect.height()); 140 vb.getRoot().setMinimumHeight(rect.height());
136 vb.getRoot().setTranslationX((float) rect.left); 141 vb.getRoot().setTranslationX((float) rect.left);
137 vb.getRoot().setTranslationY((float) rect.top); 142 vb.getRoot().setTranslationY((float) rect.top);
138 vb.getRoot().setOnClickListener(v -> { 143 vb.getRoot().setOnClickListener(v -> {
139 v.setSelected(!v.isSelected()); 144 v.setSelected(!v.isSelected());
140 checkCount(); 145 checkCount();
141 }); 146 });
142 binding.flRects.addView(vb.getRoot()); 147 binding.flRects.addView(vb.getRoot());
143 148
144 return vb; 149 return vb;
145 } 150 }
146 151
147 @SuppressLint("SetTextI18n") 152 @SuppressLint("SetTextI18n")
148 private void checkCount() { 153 private void checkCount() {
149 int count = (int) mList.stream().filter(it -> it.vb.getRoot().isSelected()).count(); 154 int count = (int) mList.stream().filter(it -> it.vb.getRoot().isSelected()).count();
150 if (count == 0) binding.btnAdd.setText("加入错题"); 155 if (count == 0) binding.btnAdd.setText("加入错题");
151 else binding.btnAdd.setText("加入错题(" + count + ")"); 156 else binding.btnAdd.setText("加入错题(" + count + ")");
152 binding.btnAdd.setEnabled(count > 0); 157 binding.btnAdd.setEnabled(count > 0);
153 } 158 }
154 159
155 /** bitmapRect 转换为 viewRect */ 160 /** bitmapRect 转换为 viewRect */
156 private Rect measureRect(Rect rect, float[] measuredSize) { 161 private Rect measureRect(Rect rect, float[] measuredSize) {
157 float realW = measuredSize[0]; 162 float realW = measuredSize[0];
158 float realH = measuredSize[1]; 163 float realH = measuredSize[1];
159 float offsetX = measuredSize[2]; 164 float offsetX = measuredSize[2];
160 float offsetY = measuredSize[3]; 165 float offsetY = measuredSize[3];
161 float percentX = realW / bitmap.getWidth(); 166 float percentX = realW / bitmap.getWidth();
162 float percentY = realH / bitmap.getHeight(); 167 float percentY = realH / bitmap.getHeight();
163 168
164 float left = rect.left * percentX + offsetX; 169 float left = rect.left * percentX + offsetX;
165 float right = rect.right * percentX + offsetX; 170 float right = rect.right * percentX + offsetX;
166 float top = rect.top * percentY + offsetY; 171 float top = rect.top * percentY + offsetY;
167 float bottom = rect.bottom * percentY + offsetY; 172 float bottom = rect.bottom * percentY + offsetY;
168 return new Rect((int) left, (int) top, (int) right, (int) bottom); 173 return new Rect((int) left, (int) top, (int) right, (int) bottom);
169 } 174 }
170 175
171 @Override 176 @Override
172 protected ActivityJudgeBinding getViewBinding() { 177 protected ActivityJudgeBinding getViewBinding() {
173 return ActivityJudgeBinding.inflate(getLayoutInflater()); 178 return ActivityJudgeBinding.inflate(getLayoutInflater());
174 } 179 }
175 180
176 static class JudgeCut { 181 static class JudgeCut {
177 final int index; 182 final int index;
178 final Bitmap bitmap; 183 final Bitmap bitmap;
179 final Rect rect; 184 final Rect rect;
180 final LayoutJudgeRectBinding vb; 185 final LayoutJudgeRectBinding vb;
181 186
182 String url; 187 String url;
183 188
184 /** 0:未批改;1:正确;2:错误;3:未作答 */ 189 /** 0:未批改;1:正确;2:错误;3:未作答 */
185 int correctResult = 0; 190 int correctResult = 0;
186 191
187 public JudgeCut(int index, Bitmap bitmap, Rect rect, LayoutJudgeRectBinding vb) { 192 public JudgeCut(int index, Bitmap bitmap, Rect rect, LayoutJudgeRectBinding vb) {
188 this.index = index; 193 this.index = index;
189 this.bitmap = bitmap; 194 this.bitmap = bitmap;
190 this.rect = rect; 195 this.rect = rect;
191 this.vb = vb; 196 this.vb = vb;
192 } 197 }
193 198
194 private String path; 199 private String path;
195 200
196 public String getPath() { 201 public String getPath() {
197 if (path != null) return path; 202 if (path != null) return path;
198 path = CutUtil.saveBitmapToCache(bitmap, App.getInstance()); 203 path = CutUtil.saveBitmapToCache(bitmap, App.getInstance());
199 return path; 204 return path;
200 } 205 }
201 } 206 }
202 } 207 }
203 208
app/src/main/res/layout/activity_judge.xml
1 <?xml version="1.0" encoding="utf-8"?> 1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:app="http://schemas.android.com/apk/res-auto" 3 xmlns:app="http://schemas.android.com/apk/res-auto"
4 xmlns:tools="http://schemas.android.com/tools" 4 xmlns:tools="http://schemas.android.com/tools"
5 android:orientation="vertical" 5 android:orientation="vertical"
6 android:layout_width="match_parent" 6 android:layout_width="match_parent"
7 android:layout_height="match_parent" 7 android:layout_height="match_parent"
8 tools:ignore="UseCompoundDrawables,HardcodedText,SmallSp,ContentDescription"> 8 tools:ignore="UseCompoundDrawables,HardcodedText,SmallSp,ContentDescription">
9 9
10 <androidx.appcompat.widget.Toolbar 10 <androidx.appcompat.widget.Toolbar
11 android:background="@color/white" 11 android:background="@color/white"
12 app:contentInsetStart="0dp" 12 app:contentInsetStart="0dp"
13 android:layout_width="match_parent" 13 android:layout_width="match_parent"
14 android:layout_height="40dp"> 14 android:layout_height="40dp">
15 <ImageView 15 <ImageView
16 android:id="@+id/ivBack" 16 android:id="@+id/ivBack"
17 android:layout_width="30dp" 17 android:layout_width="30dp"
18 android:layout_height="36dp" 18 android:layout_height="36dp"
19 android:layout_centerVertical="true" 19 android:layout_centerVertical="true"
20 android:layout_marginStart="5dp" 20 android:layout_marginStart="5dp"
21 android:padding="10dp" 21 android:padding="10dp"
22 android:src="@mipmap/icon_back" /> 22 android:src="@mipmap/icon_back" />
23 </androidx.appcompat.widget.Toolbar> 23 </androidx.appcompat.widget.Toolbar>
24 24
25 <FrameLayout 25 <FrameLayout
26 android:background="@color/white" 26 android:background="@color/white"
27 android:padding="8dp" 27 android:padding="8dp"
28 android:layout_margin="16dp" 28 android:layout_margin="16dp"
29 android:layout_width="match_parent" 29 android:layout_width="match_parent"
30 android:layout_height="0px" 30 android:layout_height="0px"
31 android:layout_weight="1"> 31 android:layout_weight="1">
32 <ImageView 32 <ImageView
33 android:id="@+id/ivPic" 33 android:id="@+id/ivPic"
34 android:layout_width="match_parent" 34 android:layout_width="match_parent"
35 android:layout_height="match_parent"/> 35 android:layout_height="match_parent"/>
36 <FrameLayout 36 <FrameLayout
37 android:id="@+id/flRects" 37 android:id="@+id/flRects"
38 android:layout_width="match_parent" 38 android:layout_width="match_parent"
39 android:layout_height="match_parent" /> 39 android:layout_height="match_parent" />
40 </FrameLayout> 40 </FrameLayout>
41 41
42 <LinearLayout 42 <LinearLayout
43 android:orientation="horizontal" 43 android:orientation="horizontal"
44 android:gravity="center_vertical" 44 android:gravity="center_vertical"
45 android:paddingHorizontal="16dp" 45 android:paddingHorizontal="16dp"
46 android:background="@color/white" 46 android:background="@color/white"
47 android:layout_width="match_parent" 47 android:layout_width="match_parent"
48 android:layout_height="64dp"> 48 android:layout_height="64dp">
49 <androidx.appcompat.widget.AppCompatTextView 49 <androidx.appcompat.widget.AppCompatTextView
50 android:id="@+id/btnSelectAll" 50 android:id="@+id/btnSelectAll"
51 android:text="全选" 51 android:text="全选"
52 android:textSize="16sp" 52 android:textSize="16sp"
53 android:textColor="#333" 53 android:textColor="#333"
54 android:gravity="center_vertical" 54 android:gravity="center_vertical"
55 android:paddingHorizontal="8dp" 55 android:paddingHorizontal="8dp"
56 android:paddingVertical="4dp" 56 android:paddingVertical="4dp"
57 android:layout_width="wrap_content" 57 android:layout_width="wrap_content"
58 android:layout_height="wrap_content"/> 58 android:layout_height="wrap_content"/>
59 <androidx.appcompat.widget.AppCompatTextView
60 android:id="@+id/btnSelectNone"
61 android:text="全不选"
62 android:textSize="16sp"
63 android:textColor="#333"
64 android:gravity="center_vertical"
65 android:paddingHorizontal="8dp"
66 android:paddingVertical="4dp"
67 android:layout_marginStart="8dp"
68 android:layout_width="wrap_content"
69 android:layout_height="wrap_content"/>
59 70
60 <Space style="@style/empty_space"/> 71 <Space style="@style/empty_space"/>
61 <TextView 72 <TextView
62 android:id="@+id/btnAdd" 73 android:id="@+id/btnAdd"
63 android:enabled="false" 74 android:enabled="false"
64 android:text="加入错题" 75 android:text="加入错题"
65 android:textSize="16sp" 76 android:textSize="16sp"
66 android:textColor="@color/white" 77 android:textColor="@color/white"
67 android:gravity="center" 78 android:gravity="center"
68 android:background="@drawable/bg_error_add_enabled" 79 android:background="@drawable/bg_error_add_enabled"
69 android:layout_width="112dp" 80 android:layout_width="112dp"
70 android:layout_height="36dp"/> 81 android:layout_height="36dp"/>
71 </LinearLayout> 82 </LinearLayout>
72 83
73 </LinearLayout> 84 </LinearLayout>
app/src/main/res/layout/dialog_add_error.xml
1 <androidx.core.widget.NestedScrollView 1 <androidx.core.widget.NestedScrollView
2 xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:tools="http://schemas.android.com/tools"
3 android:layout_width="match_parent" 4 android:layout_width="match_parent"
4 android:layout_height="match_parent"> 5 android:layout_height="match_parent">
5 <LinearLayout 6 <LinearLayout
6 android:layout_width="match_parent" 7 android:layout_width="match_parent"
7 android:layout_height="wrap_content" 8 android:layout_height="wrap_content"
8 android:background="@drawable/bg_solid_white_10_top" 9 android:background="@drawable/bg_solid_white_10_top"
9 android:orientation="vertical"> 10 android:orientation="vertical">
10 11
11 <RelativeLayout 12 <RelativeLayout
12 android:layout_width="match_parent" 13 android:layout_width="match_parent"
13 android:layout_height="50dp"> 14 android:layout_height="50dp">
14 15
15 <TextView 16 <TextView
16 android:layout_width="wrap_content" 17 android:layout_width="wrap_content"
17 android:layout_height="wrap_content" 18 android:layout_height="wrap_content"
18 android:layout_centerInParent="true" 19 android:layout_centerInParent="true"
19 android:text="加入错题本" 20 android:text="加入错题本"
20 android:textColor="@color/text_title" 21 android:textColor="@color/text_title"
21 android:textSize="17sp" 22 android:textSize="17sp"
22 android:textStyle="bold" /> 23 android:textStyle="bold" />
23 24
24 <ImageView 25 <ImageView
25 android:id="@+id/iv_back" 26 android:id="@+id/iv_back"
26 android:layout_width="35dp" 27 android:layout_width="35dp"
27 android:layout_height="35dp" 28 android:layout_height="35dp"
28 android:layout_alignParentRight="true" 29 android:layout_alignParentRight="true"
29 android:layout_centerVertical="true" 30 android:layout_centerVertical="true"
30 android:layout_marginRight="10dp" 31 android:layout_marginRight="10dp"
31 android:padding="10dp" 32 android:padding="10dp"
32 android:src="@mipmap/ic_close" /> 33 android:src="@mipmap/ic_close" />
33 </RelativeLayout> 34 </RelativeLayout>
34 35
35 <androidx.recyclerview.widget.RecyclerView 36 <androidx.recyclerview.widget.RecyclerView
36 android:id="@+id/list_item" 37 android:id="@+id/list_item"
37 android:layout_width="match_parent" 38 android:layout_width="match_parent"
38 android:layout_height="30dp" 39 android:layout_height="30dp"
39 android:layout_marginLeft="20dp" 40 android:layout_marginLeft="20dp"
40 android:layout_marginTop="10dp" 41 android:layout_marginTop="10dp"
41 android:layout_marginRight="20dp" /> 42 android:layout_marginRight="20dp" />
42 43
43 <RelativeLayout 44 <RelativeLayout
44 android:layout_width="match_parent" 45 android:layout_width="match_parent"
45 android:layout_height="90dp" 46 android:layout_height="90dp"
46 android:layout_marginLeft="20dp" 47 android:layout_marginLeft="20dp"
47 android:layout_marginTop="20dp" 48 android:layout_marginTop="20dp"
48 android:layout_marginRight="20dp"> 49 android:layout_marginRight="20dp">
49 50
50 <RelativeLayout 51 <RelativeLayout
51 android:layout_width="match_parent" 52 android:layout_width="match_parent"
52 android:layout_height="match_parent" 53 android:layout_height="match_parent"
53 android:background="#F5F5F5"> 54 android:background="#F5F5F5">
54 55
55 <ImageView 56 <ImageView
56 android:id="@+id/iv_topic" 57 android:id="@+id/iv_topic"
57 android:layout_width="wrap_content" 58 android:layout_width="wrap_content"
58 android:layout_height="wrap_content" 59 android:layout_height="wrap_content"
59 android:layout_centerVertical="true" /> 60 android:layout_centerVertical="true" />
60 </RelativeLayout> 61 </RelativeLayout>
61 </RelativeLayout> 62 </RelativeLayout>
62 63
63 <TextView 64 <TextView
64 android:layout_width="wrap_content" 65 android:layout_width="wrap_content"
65 android:layout_height="wrap_content" 66 android:layout_height="wrap_content"
66 android:layout_centerVertical="true" 67 android:layout_centerVertical="true"
67 android:layout_marginLeft="20dp" 68 android:layout_marginLeft="20dp"
68 android:layout_marginTop="20dp" 69 android:layout_marginTop="20dp"
69 android:text="年级" 70 android:text="年级"
70 android:textColor="@color/text_title" 71 android:textColor="@color/text_title"
71 android:textSize="15sp" 72 android:textSize="15sp"
72 android:textStyle="bold" /> 73 android:textStyle="bold" />
73 74
74 <androidx.appcompat.widget.AppCompatSpinner 75 <androidx.appcompat.widget.AppCompatSpinner
75 android:id="@+id/spinner_grade" 76 android:id="@+id/spinner_grade"
76 style="@style/customSpinnerStyle" 77 style="@style/customSpinnerStyle"
77 android:layout_width="match_parent" 78 android:layout_width="match_parent"
78 android:layout_height="40dp" 79 android:layout_height="40dp"
79 android:layout_centerHorizontal="true" 80 android:layout_centerHorizontal="true"
80 android:layout_marginLeft="20dp" 81 android:layout_marginLeft="20dp"
81 android:layout_marginTop="10dp" 82 android:layout_marginTop="10dp"
82 android:layout_marginRight="20dp" 83 android:layout_marginRight="20dp"
83 android:background="@drawable/selector_for_custom_spinner" 84 android:background="@drawable/selector_for_custom_spinner"
84 android:popupBackground="@drawable/shape_for_custom_spinner" 85 android:popupBackground="@drawable/shape_for_custom_spinner"
85 android:scrollbars="none" /> 86 android:scrollbars="none" />
86 87
87 <TextView 88 <TextView
88 android:layout_width="wrap_content" 89 android:layout_width="wrap_content"
89 android:layout_height="wrap_content" 90 android:layout_height="wrap_content"
90 android:layout_centerVertical="true" 91 android:layout_centerVertical="true"
91 android:layout_marginLeft="20dp" 92 android:layout_marginLeft="20dp"
92 android:layout_marginTop="20dp" 93 android:layout_marginTop="20dp"
93 android:text="学期" 94 android:text="学期"
94 android:textColor="@color/text_title" 95 android:textColor="@color/text_title"
95 android:textSize="15sp" 96 android:textSize="15sp"
96 android:textStyle="bold" /> 97 android:textStyle="bold" />
97 98
98 <androidx.appcompat.widget.AppCompatSpinner 99 <androidx.appcompat.widget.AppCompatSpinner
99 android:id="@+id/spinner_grade1" 100 android:id="@+id/spinner_grade1"
100 style="@style/customSpinnerStyle" 101 style="@style/customSpinnerStyle"
101 android:layout_width="match_parent" 102 android:layout_width="match_parent"
102 android:layout_height="40dp" 103 android:layout_height="40dp"
103 android:layout_centerHorizontal="true" 104 android:layout_centerHorizontal="true"
104 android:layout_marginLeft="20dp" 105 android:layout_marginLeft="20dp"
105 android:layout_marginTop="10dp" 106 android:layout_marginTop="10dp"
106 android:layout_marginRight="20dp" 107 android:layout_marginRight="20dp"
107 android:background="@drawable/selector_for_custom_spinner" 108 android:background="@drawable/selector_for_custom_spinner"
108 android:entries="@array/grade_array" 109 android:entries="@array/grade_array"
109 android:popupBackground="@drawable/shape_for_custom_spinner" 110 android:popupBackground="@drawable/shape_for_custom_spinner"
110 android:scrollbars="none" /> 111 android:scrollbars="none" />
111 112
112 <TextView 113 <TextView
113 android:layout_width="wrap_content" 114 android:layout_width="wrap_content"
114 android:layout_height="wrap_content" 115 android:layout_height="wrap_content"
115 android:layout_centerVertical="true" 116 android:layout_centerVertical="true"
116 android:layout_marginLeft="20dp" 117 android:layout_marginLeft="20dp"
117 android:layout_marginTop="20dp" 118 android:layout_marginTop="20dp"
118 android:text="科目" 119 android:text="科目"
119 android:textColor="@color/text_title" 120 android:textColor="@color/text_title"
120 android:textSize="15sp" 121 android:textSize="15sp"
121 android:textStyle="bold" /> 122 android:textStyle="bold" />
122 123
123 <androidx.appcompat.widget.AppCompatSpinner 124 <androidx.appcompat.widget.AppCompatSpinner
124 android:id="@+id/spinner_subject" 125 android:id="@+id/spinner_subject"
125 style="@style/customSpinnerStyle" 126 style="@style/customSpinnerStyle"
126 android:layout_width="match_parent" 127 android:layout_width="match_parent"
127 android:layout_height="40dp" 128 android:layout_height="40dp"
128 android:layout_centerHorizontal="true" 129 android:layout_centerHorizontal="true"
129 android:layout_marginLeft="20dp" 130 android:layout_marginLeft="20dp"
130 android:layout_marginTop="10dp" 131 android:layout_marginTop="10dp"
131 android:layout_marginRight="20dp" 132 android:layout_marginRight="20dp"
132 android:background="@drawable/selector_for_custom_spinner" 133 android:background="@drawable/selector_for_custom_spinner"
133 android:entries="@array/filter_subject" 134 android:entries="@array/filter_subject"
134 android:popupBackground="@drawable/shape_for_custom_spinner" 135 android:popupBackground="@drawable/shape_for_custom_spinner"
135 android:scrollbars="none" /> 136 android:scrollbars="none" />
136 137
137 <TextView 138 <TextView
138 android:layout_width="wrap_content" 139 android:layout_width="wrap_content"
139 android:layout_height="wrap_content" 140 android:layout_height="wrap_content"
140 android:layout_centerVertical="true" 141 android:layout_centerVertical="true"
141 android:layout_marginLeft="20dp" 142 android:layout_marginLeft="20dp"
142 android:layout_marginTop="20dp" 143 android:layout_marginTop="20dp"
143 android:text="错误原因" 144 android:text="错误原因"
144 android:textColor="@color/text_title" 145 android:textColor="@color/text_title"
145 android:textSize="15sp" 146 android:textSize="15sp"
146 android:textStyle="bold" /> 147 android:textStyle="bold" />
147 148
148 <androidx.appcompat.widget.AppCompatSpinner 149 <androidx.appcompat.widget.AppCompatSpinner
149 android:id="@+id/spinner_reason" 150 android:id="@+id/spinner_reason"
150 style="@style/customSpinnerStyle" 151 style="@style/customSpinnerStyle"
151 android:layout_width="match_parent" 152 android:layout_width="match_parent"
152 android:layout_height="40dp" 153 android:layout_height="40dp"
153 android:layout_centerHorizontal="true" 154 android:layout_centerHorizontal="true"
154 android:layout_marginLeft="20dp" 155 android:layout_marginLeft="20dp"
155 android:layout_marginTop="10dp" 156 android:layout_marginTop="10dp"
156 android:layout_marginRight="20dp" 157 android:layout_marginRight="20dp"
157 android:background="@drawable/selector_for_custom_spinner" 158 android:background="@drawable/selector_for_custom_spinner"
158 android:entries="@array/filter_subject" 159 android:entries="@array/filter_subject"
159 android:popupBackground="@drawable/shape_for_custom_spinner" 160 android:popupBackground="@drawable/shape_for_custom_spinner"
160 android:scrollbars="none" /> 161 android:scrollbars="none" />
161 162
162 <TextView 163 <TextView
163 android:id="@+id/tv_student" 164 android:id="@+id/tv_student"
164 android:layout_width="wrap_content" 165 android:layout_width="wrap_content"
165 android:layout_height="wrap_content" 166 android:layout_height="wrap_content"
166 android:layout_centerVertical="true" 167 android:layout_centerVertical="true"
167 android:layout_marginLeft="20dp" 168 android:layout_marginLeft="20dp"
168 android:layout_marginTop="20dp" 169 android:layout_marginTop="20dp"
169 android:text="学生" 170 android:text="学生"
170 android:textColor="@color/text_title" 171 android:textColor="@color/text_title"
171 android:visibility="gone" 172 android:visibility="gone"
172 android:textSize="15sp" 173 android:textSize="15sp"
173 android:textStyle="bold" /> 174 android:textStyle="bold" />
174 175
175 <androidx.appcompat.widget.AppCompatSpinner 176 <androidx.appcompat.widget.AppCompatSpinner
176 android:id="@+id/spinner_student" 177 android:id="@+id/spinner_student"
177 style="@style/customSpinnerStyle" 178 style="@style/customSpinnerStyle"
178 android:layout_width="match_parent" 179 android:layout_width="match_parent"
179 android:layout_height="40dp" 180 android:layout_height="40dp"
180 android:layout_centerHorizontal="true" 181 android:layout_centerHorizontal="true"
181 android:layout_marginLeft="20dp" 182 android:layout_marginLeft="20dp"
182 android:layout_marginTop="10dp" 183 android:layout_marginTop="10dp"
183 android:layout_marginRight="20dp" 184 android:layout_marginRight="20dp"
184 android:visibility="gone" 185 android:visibility="gone"
185 android:background="@drawable/selector_for_custom_spinner" 186 android:background="@drawable/selector_for_custom_spinner"
186 android:entries="@array/filter_subject" 187 android:entries="@array/filter_subject"
187 android:popupBackground="@drawable/shape_for_custom_spinner" 188 android:popupBackground="@drawable/shape_for_custom_spinner"
188 android:scrollbars="none" /> 189 android:scrollbars="none" />
189 190
190 <TextView 191 <TextView
191 android:layout_width="wrap_content" 192 android:layout_width="wrap_content"
192 android:layout_height="wrap_content" 193 android:layout_height="wrap_content"
193 android:layout_centerVertical="true" 194 android:layout_centerVertical="true"
194 android:layout_marginLeft="20dp" 195 android:layout_marginLeft="20dp"
195 android:layout_marginTop="20dp" 196 android:layout_marginTop="20dp"
196 android:text="来源" 197 android:text="来源"
197 android:textColor="@color/text_title" 198 android:textColor="@color/text_title"
198 android:textSize="15sp" 199 android:textSize="15sp"
199 android:textStyle="bold" /> 200 android:textStyle="bold" />
200 201
201 <RadioGroup 202 <RadioGroup
202 android:id="@+id/type_radio" 203 android:id="@+id/type_radio"
203 android:layout_width="match_parent" 204 android:layout_width="match_parent"
204 android:layout_height="40dp" 205 android:layout_height="40dp"
205 android:layout_marginLeft="20dp" 206 android:layout_marginLeft="20dp"
206 android:layout_marginTop="10dp" 207 android:layout_marginTop="10dp"
207 android:orientation="horizontal"> 208 android:orientation="horizontal">
208 209
209 <RadioButton 210 <RadioButton
210 android:layout_width="65dp" 211 android:layout_width="65dp"
211 android:layout_height="match_parent" 212 android:layout_height="match_parent"
212 android:layout_marginRight="20dp" 213 android:layout_marginRight="20dp"
213 android:background="@drawable/radio_button_selector" 214 android:background="@drawable/radio_button_selector"
214 android:button="@null" 215 android:button="@null"
215 android:gravity="center" 216 android:gravity="center"
216 android:text="课内" 217 android:text="课内"
217 android:textColor="@drawable/radio_text_selector" 218 android:textColor="@drawable/radio_text_selector"
218 android:textSize="14sp" /> 219 android:textSize="14sp" />
219 220
220 <RadioButton 221 <RadioButton
221 android:layout_width="65dp" 222 android:layout_width="65dp"
222 android:layout_height="match_parent" 223 android:layout_height="match_parent"
223 android:layout_marginRight="20dp" 224 android:layout_marginRight="20dp"
224 android:background="@drawable/radio_button_selector" 225 android:background="@drawable/radio_button_selector"
225 android:button="@null" 226 android:button="@null"
226 android:gravity="center" 227 android:gravity="center"
227 android:text="课外" 228 android:text="课外"
228 android:textColor="@drawable/radio_text_selector" 229 android:textColor="@drawable/radio_text_selector"
229 android:textSize="14sp" /> 230 android:textSize="14sp" />
230 </RadioGroup> 231 </RadioGroup>
231 232
232 233
233 <RelativeLayout 234 <LinearLayout
234 android:layout_width="match_parent" 235 android:orientation="horizontal"
235 android:layout_height="40dp" 236 android:gravity="center_vertical"
236 android:layout_marginLeft="20dp" 237 android:layout_marginHorizontal="20dp"
237 android:layout_marginTop="20dp" 238 android:layout_marginTop="20dp"
238 android:layout_marginRight="20dp" 239 android:layout_marginBottom="15dp"
239 android:layout_marginBottom="15dp"> 240 android:layout_width="match_parent"
240 241 android:layout_height="40dp">
241 <TextView
242 android:id="@+id/add_topic"
243 android:layout_width="250dp"
244 android:layout_height="match_parent"
245 android:layout_alignParentRight="true"
246 android:background="@drawable/bg_soild_blue_5"
247 android:gravity="center"
248 android:textColor="@color/white"
249 android:textSize="17sp" />
250
251 <CheckBox 242 <CheckBox
252 android:id="@+id/checkbox" 243 android:id="@+id/checkbox"
253 android:layout_width="wrap_content" 244 android:layout_width="wrap_content"
254 android:layout_height="30dp" 245 android:layout_height="30dp"
255 android:layout_centerVertical="true"
256 android:button="@drawable/checkbox_selector" 246 android:button="@drawable/checkbox_selector"
257 android:text="批量设置" 247 android:text="批量设置"
258 android:paddingLeft="8dp" 248 android:paddingStart="8dp"
249 android:paddingEnd="0dp"
259 android:textColor="@color/text_title" 250 android:textColor="@color/text_title"
260 android:textSize="14sp" /> 251 android:textSize="14sp"
252 tools:ignore="HardcodedText" />
261 253
262 </RelativeLayout> 254 <Space style="@style/empty_space"/>
255
256 <TextView
257 android:id="@+id/add_topic"
258 tools:text="全部加入错题"