Commit 36364a3420312f092f3395f7fa5ab613ec9dc67f
1 parent
eb171a0634
Exists in
master
布局
Showing
4 changed files
with
60 additions
and
3 deletions
Show diff stats
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.graphics.Bitmap; | 4 | import android.graphics.Bitmap; |
5 | import android.graphics.Rect; | 5 | import android.graphics.Rect; |
6 | import android.os.Bundle; | 6 | import android.os.Bundle; |
7 | import android.util.Log; | 7 | import android.util.Log; |
8 | 8 | ||
9 | import com.bumptech.glide.Glide; | 9 | import com.bumptech.glide.Glide; |
10 | import com.hjx.parent.api.JudgeRepository; | 10 | import com.hjx.parent.api.JudgeRepository; |
11 | import com.hjx.parent.databinding.ActivityJudgeBinding; | 11 | import com.hjx.parent.databinding.ActivityJudgeBinding; |
12 | import com.hjx.parent.databinding.LayoutJudgeRectBinding; | 12 | import com.hjx.parent.databinding.LayoutJudgeRectBinding; |
13 | import com.hjx.parent.rx.BaseRxActivity; | 13 | import com.hjx.parent.rx.BaseRxActivity; |
14 | import com.hjx.parent.utils.CutUtil; | 14 | import com.hjx.parent.utils.CutUtil; |
15 | 15 | ||
16 | import java.io.File; | 16 | import java.io.File; |
17 | import java.util.ArrayList; | 17 | import java.util.ArrayList; |
18 | import java.util.List; | 18 | import java.util.List; |
19 | 19 | ||
20 | import io.reactivex.Observable; | 20 | import io.reactivex.Observable; |
21 | import io.reactivex.Single; | 21 | import io.reactivex.Single; |
22 | import top.zibin.luban.Luban; | 22 | import top.zibin.luban.Luban; |
23 | 23 | ||
24 | public class JudgeActivity extends BaseRxActivity<ActivityJudgeBinding> { | 24 | public class JudgeActivity extends BaseRxActivity<ActivityJudgeBinding> { |
25 | 25 | ||
26 | private Bitmap bitmap; | 26 | private Bitmap bitmap; |
27 | 27 | ||
28 | private final List<JudgeCut> mList = new ArrayList<>(); | 28 | private final List<JudgeCut> mList = new ArrayList<>(); |
29 | 29 | ||
30 | @SuppressLint("CheckResult") | 30 | @SuppressLint("CheckResult") |
31 | @Override | 31 | @Override |
32 | public void initView(Bundle savedInstanceState) { | 32 | public void initView(Bundle savedInstanceState) { |
33 | binding.ivBack.setOnClickListener(v -> { | 33 | binding.ivBack.setOnClickListener(v -> { |
34 | onBackPressed(); | 34 | onBackPressed(); |
35 | }); | 35 | }); |
36 | String path = getIntent().getStringExtra("path"); | 36 | String path = getIntent().getStringExtra("path"); |
37 | if (path == null) return; | 37 | if (path == null) return; |
38 | final ArrayList<Rect> rects = getIntent().getParcelableArrayListExtra("rects"); | 38 | final ArrayList<Rect> rects = getIntent().getParcelableArrayListExtra("rects"); |
39 | if (rects == null) return; | 39 | if (rects == null) return; |
40 | 40 | ||
41 | Single.just(path) | 41 | Single.just(path) |
42 | .map(origin -> Luban.with(this).load(origin).ignoreBy(300).get().get(0)) | 42 | .map(origin -> Luban.with(this).load(origin).ignoreBy(300).get().get(0)) |
43 | .map(file -> Glide.with(this).asBitmap().load(file).submit().get()) | 43 | .map(file -> Glide.with(this).asBitmap().load(file).submit().get()) |
44 | .compose(transformSingle()) | 44 | .compose(transformSingle()) |
45 | .subscribe((bitmap, th) -> { | 45 | .subscribe((bitmap, th) -> { |
46 | if (th != null) th.printStackTrace(); | 46 | if (th != null) th.printStackTrace(); |
47 | if (bitmap == null) return; | 47 | if (bitmap == null) return; |
48 | this.bitmap = bitmap; | 48 | this.bitmap = bitmap; |
49 | 49 | ||
50 | binding.ivPic.setImageBitmap(bitmap); | 50 | binding.ivPic.setImageBitmap(bitmap); |
51 | CutUtil.onLayoutReady(binding.ivPic, v -> { | 51 | CutUtil.onLayoutReady(binding.ivPic, v -> { |
52 | prepareRects(rects); | 52 | prepareRects(rects); |
53 | }); | 53 | }); |
54 | }); | 54 | }); |
55 | binding.btnSelectAll.setOnClickListener(v -> { | ||
56 | if (mList.isEmpty()) return; | ||
57 | mList.forEach(it -> it.vb.getRoot().setSelected(true)); | ||
58 | checkCount(); | ||
59 | }); | ||
55 | } | 60 | } |
56 | 61 | ||
57 | private void prepareRects(List<Rect> rects) { | 62 | private void prepareRects(List<Rect> rects) { |
58 | mList.clear(); | 63 | mList.clear(); |
59 | binding.flRects.removeAllViews(); | 64 | binding.flRects.removeAllViews(); |
60 | float[] measuredSize = CutUtil.measureBitmap(binding.ivPic, bitmap); | 65 | float[] measuredSize = CutUtil.measureBitmap(binding.ivPic, bitmap); |
61 | for (int i = 0; i < rects.size(); i++) { | 66 | for (int i = 0; i < rects.size(); i++) { |
62 | Rect it = rects.get(i); | 67 | Rect it = rects.get(i); |
63 | Bitmap bitmap = CutUtil.cut(this.bitmap, it.left, it.top, it.width(), it.height(), this); | 68 | Bitmap bitmap = CutUtil.cut(this.bitmap, it.left, it.top, it.width(), it.height(), this); |
64 | Rect rect = measureRect(it, measuredSize); | 69 | Rect rect = measureRect(it, measuredSize); |
65 | LayoutJudgeRectBinding vb = showRect(rect); | 70 | LayoutJudgeRectBinding vb = showRect(rect); |
66 | mList.add(new JudgeCut(i, bitmap, rect, vb)); | 71 | mList.add(new JudgeCut(i, bitmap, rect, vb)); |
67 | } | 72 | } |
68 | 73 | ||
69 | judge(); | 74 | judge(); |
70 | } | 75 | } |
71 | 76 | ||
72 | @SuppressLint("CheckResult") | 77 | @SuppressLint("CheckResult") |
73 | private void judge() { | 78 | private void judge() { |
74 | showLoadingDialog(""); | 79 | showLoadingDialog(""); |
75 | Observable.fromIterable(mList) | 80 | Observable.fromIterable(mList) |
76 | .map(it -> { | 81 | .map(it -> { |
77 | if (it.url != null && !it.url.isEmpty()) return it; | 82 | if (it.url != null && !it.url.isEmpty()) return it; |
78 | String base64 = CutUtil.bitmapToBase64(it.bitmap, true); | 83 | String base64 = CutUtil.bitmapToBase64(it.bitmap, true); |
79 | it.url = base64; | 84 | it.url = base64; |
80 | return it; | 85 | return it; |
81 | }) | 86 | }) |
82 | .flatMap(it -> JudgeRepository.singleJudge(it.url) | 87 | .flatMap(it -> JudgeRepository.singleJudge(it.url) |
83 | .map(result -> { | 88 | .map(result -> { |
84 | it.correctResult = result; | 89 | it.correctResult = result; |
85 | return it; | 90 | return it; |
86 | }) | 91 | }) |
87 | .toObservable() | 92 | .toObservable() |
88 | ) | 93 | ) |
89 | .compose(transform()) | 94 | .compose(transform()) |
90 | .subscribe(it -> { | 95 | .subscribe(it -> { |
91 | if (it.correctResult == 1) { | 96 | if (it.correctResult == 1) { |
92 | it.vb.ivResult.setImageResource(R.drawable.png_ic_judge_correct); | 97 | it.vb.ivResult.setImageResource(R.drawable.png_ic_judge_correct); |
93 | it.vb.getRoot().setSelected(false); | ||
94 | } else if (it.correctResult == 2) { | 98 | } else if (it.correctResult == 2) { |
95 | it.vb.ivResult.setImageResource(R.drawable.png_ic_judge_wrong); | 99 | it.vb.ivResult.setImageResource(R.drawable.png_ic_judge_wrong); |
96 | it.vb.getRoot().setSelected(true); | ||
97 | } | 100 | } |
101 | it.vb.getRoot().setSelected(it.correctResult != 1); | ||
102 | checkCount(); | ||
98 | }, th -> { | 103 | }, th -> { |
99 | cancelLoadingDialog(); | 104 | cancelLoadingDialog(); |
100 | Log.e(getClass().getName(), "", th); | 105 | Log.e(getClass().getName(), "", th); |
101 | }, this::cancelLoadingDialog) | 106 | }, this::cancelLoadingDialog) |
102 | ; | 107 | ; |
103 | } | 108 | } |
104 | 109 | ||
105 | private LayoutJudgeRectBinding showRect(Rect rect) { | 110 | private LayoutJudgeRectBinding showRect(Rect rect) { |
106 | LayoutJudgeRectBinding vb = LayoutJudgeRectBinding.inflate(getLayoutInflater(), binding.flRects, false); | 111 | LayoutJudgeRectBinding vb = LayoutJudgeRectBinding.inflate(getLayoutInflater(), binding.flRects, false); |
107 | 112 | ||
108 | vb.getRoot().setMinimumWidth(rect.width()); | 113 | vb.getRoot().setMinimumWidth(rect.width()); |
109 | vb.getRoot().setMinimumHeight(rect.height()); | 114 | vb.getRoot().setMinimumHeight(rect.height()); |
110 | vb.getRoot().setTranslationX((float) rect.left); | 115 | vb.getRoot().setTranslationX((float) rect.left); |
111 | vb.getRoot().setTranslationY((float) rect.top); | 116 | vb.getRoot().setTranslationY((float) rect.top); |
112 | vb.getRoot().setOnClickListener(v -> { | 117 | vb.getRoot().setOnClickListener(v -> { |
113 | v.setSelected(!v.isSelected()); | 118 | v.setSelected(!v.isSelected()); |
114 | checkCount(); | 119 | checkCount(); |
115 | }); | 120 | }); |
116 | binding.flRects.addView(vb.getRoot()); | 121 | binding.flRects.addView(vb.getRoot()); |
117 | 122 | ||
118 | return vb; | 123 | return vb; |
119 | } | 124 | } |
120 | 125 | ||
126 | @SuppressLint("SetTextI18n") | ||
121 | private void checkCount() { | 127 | private void checkCount() { |
122 | // | 128 | int count = (int) mList.stream().filter(it -> it.vb.getRoot().isSelected()).count(); |
129 | if (count == 0) binding.btnAdd.setText("加入错题"); | ||
130 | else binding.btnAdd.setText("加入错题(" + count + ")"); | ||
131 | binding.btnAdd.setEnabled(count > 0); | ||
123 | } | 132 | } |
124 | 133 | ||
125 | /** bitmapRect 转换为 viewRect */ | 134 | /** bitmapRect 转换为 viewRect */ |
126 | private Rect measureRect(Rect rect, float[] measuredSize) { | 135 | private Rect measureRect(Rect rect, float[] measuredSize) { |
127 | float realW = measuredSize[0]; | 136 | float realW = measuredSize[0]; |
128 | float realH = measuredSize[1]; | 137 | float realH = measuredSize[1]; |
129 | float offsetX = measuredSize[2]; | 138 | float offsetX = measuredSize[2]; |
130 | float offsetY = measuredSize[3]; | 139 | float offsetY = measuredSize[3]; |
131 | float percentX = realW / bitmap.getWidth(); | 140 | float percentX = realW / bitmap.getWidth(); |
132 | float percentY = realH / bitmap.getHeight(); | 141 | float percentY = realH / bitmap.getHeight(); |
133 | 142 | ||
134 | float left = rect.left * percentX + offsetX; | 143 | float left = rect.left * percentX + offsetX; |
135 | float right = rect.right * percentX + offsetX; | 144 | float right = rect.right * percentX + offsetX; |
136 | float top = rect.top * percentY + offsetY; | 145 | float top = rect.top * percentY + offsetY; |
137 | float bottom = rect.bottom * percentY + offsetY; | 146 | float bottom = rect.bottom * percentY + offsetY; |
138 | return new Rect((int) left, (int) top, (int) right, (int) bottom); | 147 | return new Rect((int) left, (int) top, (int) right, (int) bottom); |
139 | } | 148 | } |
140 | 149 | ||
141 | @Override | 150 | @Override |
142 | protected ActivityJudgeBinding getViewBinding() { | 151 | protected ActivityJudgeBinding getViewBinding() { |
143 | return ActivityJudgeBinding.inflate(getLayoutInflater()); | 152 | return ActivityJudgeBinding.inflate(getLayoutInflater()); |
144 | } | 153 | } |
145 | 154 | ||
146 | static class JudgeCut { | 155 | static class JudgeCut { |
147 | final int index; | 156 | final int index; |
148 | final Bitmap bitmap; | 157 | final Bitmap bitmap; |
149 | final Rect rect; | 158 | final Rect rect; |
150 | final LayoutJudgeRectBinding vb; | 159 | final LayoutJudgeRectBinding vb; |
151 | 160 | ||
152 | String url; | 161 | String url; |
162 | |||
163 | /** 0:未批改;1:正确;2:错误;3:未作答 */ | ||
153 | int correctResult = 0; | 164 | int correctResult = 0; |
154 | 165 | ||
155 | public JudgeCut(int index, Bitmap bitmap, Rect rect, LayoutJudgeRectBinding vb) { | 166 | public JudgeCut(int index, Bitmap bitmap, Rect rect, LayoutJudgeRectBinding vb) { |
156 | this.index = index; | 167 | this.index = index; |
157 | this.bitmap = bitmap; | 168 | this.bitmap = bitmap; |
158 | this.rect = rect; | 169 | this.rect = rect; |
159 | this.vb = vb; | 170 | this.vb = vb; |
160 | } | 171 | } |
161 | } | 172 | } |
app/src/main/res/drawable/check_circle_12.xml
File was created | 1 | <?xml version="1.0" encoding="utf-8"?> | |
2 | <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | ||
3 | <item android:width="12dp" android:height="12dp"> | ||
4 | <selector> | ||
5 | <item android:state_checked="true" | ||
6 | android:drawable="@drawable/png_ic_check_circle"/> | ||
7 | <item> | ||
8 | <shape> | ||
9 | <corners android:radius="20dp"/> | ||
10 | <stroke android:width="1.5dp" android:color="#333"/> | ||
11 | </shape> | ||
12 | </item> | ||
13 | </selector> | ||
14 | </item> | ||
15 | </layer-list> |
app/src/main/res/drawable/png_ic_check_circle.png
1.05 KB
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 | ||
43 | android:orientation="horizontal" | ||
44 | android:gravity="center_vertical" | ||
45 | android:paddingHorizontal="16dp" | ||
46 | android:background="@color/white" | ||
47 | android:layout_width="match_parent" | ||
48 | android:layout_height="64dp"> | ||
49 | <androidx.appcompat.widget.AppCompatTextView | ||
50 | android:id="@+id/btnSelectAll" | ||
51 | android:text="全选" | ||
52 | android:textSize="16sp" | ||
53 | android:textColor="#333" | ||
54 | android:gravity="center_vertical" | ||
55 | android:paddingHorizontal="8dp" | ||
56 | android:paddingVertical="4dp" | ||
57 | android:layout_width="wrap_content" | ||
58 | android:layout_height="wrap_content"/> | ||
59 | |||
60 | <Space style="@style/empty_space"/> | ||
61 | <TextView | ||
62 | android:id="@+id/btnAdd" | ||
63 | android:text="加入错题" | ||
64 | android:textSize="16sp" | ||
65 | android:textColor="@color/white" | ||
66 | android:gravity="center" | ||
67 | android:background="@drawable/shape_radius_5" | ||
68 | android:backgroundTint="#1C90F3" | ||
69 | android:layout_width="112dp" | ||
70 | android:layout_height="36dp"/> | ||
71 | </LinearLayout> | ||
72 | |||
42 | </LinearLayout> | 73 | </LinearLayout> |