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> |