Commit c694ab53aacd2776649e37019ef596f067822f87
1 parent
ea57c8d609
Exists in
master
周报详情展示
Showing
41 changed files
with
4343 additions
and
2 deletions
Show diff stats
app/build.gradle
app/src/main/AndroidManifest.xml
... | ... | @@ -157,6 +157,7 @@ |
157 | 157 | <activity android:name=".HomeworkFeedbackActivity" /> |
158 | 158 | <activity android:name=".HomeworkTopicActivity" /> |
159 | 159 | <activity android:name=".HomeworkShareActivity" /> |
160 | + <activity android:name=".HuyouDetailActivity" /> | |
160 | 161 | |
161 | 162 | <provider |
162 | 163 | android:name="androidx.core.content.FileProvider" | ... | ... |
app/src/main/java/com/hjx/parent/HuyouDetailActivity.java
... | ... | @@ -0,0 +1,421 @@ |
1 | +package com.hjx.parent; | |
2 | + | |
3 | + | |
4 | +import android.annotation.SuppressLint; | |
5 | +import android.content.Intent; | |
6 | +import android.content.res.ColorStateList; | |
7 | +import android.graphics.Bitmap; | |
8 | +import android.net.Uri; | |
9 | +import android.os.Bundle; | |
10 | +import android.text.Html; | |
11 | +import android.view.View; | |
12 | +import android.widget.TextView; | |
13 | + | |
14 | +import androidx.annotation.NonNull; | |
15 | +import androidx.annotation.Nullable; | |
16 | +import androidx.core.content.res.ResourcesCompat; | |
17 | + | |
18 | +import com.bumptech.glide.Glide; | |
19 | +import com.chad.library.adapter.base.BaseQuickAdapter; | |
20 | +import com.chad.library.adapter.base.BaseViewHolder; | |
21 | +import com.github.mikephil.charting.components.Legend; | |
22 | +import com.github.mikephil.charting.components.XAxis; | |
23 | +import com.github.mikephil.charting.components.YAxis; | |
24 | +import com.github.mikephil.charting.data.Entry; | |
25 | +import com.github.mikephil.charting.data.LineData; | |
26 | +import com.github.mikephil.charting.data.LineDataSet; | |
27 | +import com.github.mikephil.charting.formatter.ValueFormatter; | |
28 | +import com.hjx.parent.databinding.ActivityHuyouDetailBinding; | |
29 | +import com.hjx.parent.rx.BaseRxActivity; | |
30 | +import com.prws.common.bean.Student; | |
31 | +import com.prws.common.bean.homework.StDetail; | |
32 | +import com.prws.common.net.NetWorks; | |
33 | +import com.prws.common.utils.BitmapUtils; | |
34 | +import com.prws.common.utils.ContentUtil; | |
35 | +import com.trello.rxlifecycle2.android.RxLifecycleAndroid; | |
36 | + | |
37 | +import java.text.DecimalFormat; | |
38 | +import java.text.SimpleDateFormat; | |
39 | +import java.util.ArrayList; | |
40 | +import java.util.Date; | |
41 | +import java.util.List; | |
42 | +import java.util.Locale; | |
43 | +import java.util.TimeZone; | |
44 | + | |
45 | +import io.reactivex.android.schedulers.AndroidSchedulers; | |
46 | +import io.reactivex.schedulers.Schedulers; | |
47 | + | |
48 | +public class HuyouDetailActivity extends BaseRxActivity<ActivityHuyouDetailBinding> { | |
49 | + | |
50 | + private String id; | |
51 | + private int type; // 0:周 1:阶段 | |
52 | + private Student student; | |
53 | + | |
54 | + private StDetail mData; | |
55 | + | |
56 | + final String indent = " "; | |
57 | + | |
58 | + private boolean a4 = false; | |
59 | + | |
60 | + @Override | |
61 | + protected void onResume() { | |
62 | + super.onResume(); | |
63 | + binding.root.postDelayed(() -> { | |
64 | + float scale = 1f * binding.getRoot().getWidth() / binding.root.getWidth(); | |
65 | + if (scale >= 1) return; | |
66 | + binding.root.setScaleX(scale); | |
67 | + binding.root.setScaleY(scale); | |
68 | + }, 100); | |
69 | + } | |
70 | + | |
71 | + @SuppressLint("CheckResult") | |
72 | + @Override | |
73 | + public void initView(Bundle savedInstanceState) { | |
74 | + id = getIntent().getStringExtra("id"); | |
75 | + type = getIntent().getIntExtra("type", 0); | |
76 | + student = (Student) getIntent().getSerializableExtra("student"); | |
77 | + | |
78 | + if (type == 1) binding.tvTitle.setText("阶段作业学习总结"); | |
79 | + | |
80 | + Glide.with(this).load(student.photo).into(binding.ivAvatar); | |
81 | + binding.tvStuName.setText(student.stuName); | |
82 | + | |
83 | + setupChart(); | |
84 | + NetWorks.service_url.getHuyouDetail(NetWorks.getHeader(), id) | |
85 | + .subscribeOn(Schedulers.io()) | |
86 | + .map(response -> response.getData()) | |
87 | + .map(data -> { | |
88 | + if (type == 1) data.formatCollection(); | |
89 | + return data; | |
90 | + }) | |
91 | + .observeOn(AndroidSchedulers.mainThread()) | |
92 | + .compose(RxLifecycleAndroid.bindActivity(getRxLifecycle())) | |
93 | + .subscribe((data, th) -> { | |
94 | + mData = data; | |
95 | + if (th != null) th.printStackTrace(); | |
96 | + if (data != null) showData(data); | |
97 | + }); | |
98 | + | |
99 | + binding.btnShare.setOnClickListener(v -> { | |
100 | + Uri shareUri = prepareShare(); | |
101 | + if (shareUri != null) { | |
102 | + Intent shareIntent = new Intent(Intent.ACTION_SEND); | |
103 | + shareIntent.setType("image/jpeg"); | |
104 | + shareIntent.putExtra(Intent.EXTRA_STREAM, shareUri); | |
105 | + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); | |
106 | + | |
107 | + startActivity(shareIntent); | |
108 | + } | |
109 | + }); | |
110 | + | |
111 | + binding.btnSwitch.setOnClickListener(v -> { | |
112 | + switchPage(); | |
113 | + }); | |
114 | + | |
115 | + } | |
116 | + | |
117 | + private SimpleDateFormat getFormatWithGmt8(String pattern) { | |
118 | + SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.CHINA); | |
119 | + format.setTimeZone(TimeZone.getTimeZone("GMT+16")); | |
120 | + return format; | |
121 | + } | |
122 | + | |
123 | + @SuppressLint("SetTextI18n") | |
124 | + private void showData(StDetail data) { | |
125 | + binding.tvGrade.setText(data.grade); | |
126 | + binding.tvSubject.setText(data.homeworkSubject); | |
127 | + String start = getFormatWithGmt8("yyyy.M.d").format(data.startTime); | |
128 | + String end = new SimpleDateFormat(" - M.d", Locale.CHINA).format(data.endTime); | |
129 | + binding.tvDate.setText(start + end); | |
130 | + | |
131 | + if (data.points == null) data.points = new ArrayList<>(); | |
132 | + if (data.points.size() == 0) { | |
133 | + binding.cpBefore.setValue(0); | |
134 | + binding.cpAfter.setValue(0); | |
135 | + binding.pgBefore.setText("0"); | |
136 | + binding.pgAfter.setText("0"); | |
137 | + } else { | |
138 | + float before = 0; | |
139 | + float after = 0; | |
140 | + for (StDetail.Point point: data.points) { | |
141 | + before += point.beforeState; | |
142 | + after += point.afterState; | |
143 | + } | |
144 | + before = (int) (100f * before / data.points.size() + 0.5f); | |
145 | + after = (int) (100f * after / data.points.size() + 0.5f); | |
146 | + binding.cpBefore.setValue(before); | |
147 | + binding.cpAfter.setValue(after); | |
148 | + DecimalFormat format = new DecimalFormat("0"); | |
149 | + binding.pgBefore.setText(format.format(before)); | |
150 | + binding.pgAfter.setText(format.format(after)); | |
151 | + | |
152 | + String comment; | |
153 | + if (after >= 90) { | |
154 | + comment = "知识点掌握的比较扎实,多练习多巩固掌握一般的知识点会有很大帮助。"; | |
155 | + } else if (after >= 80) { | |
156 | + comment = "知识点掌握程度有进步,还要再继续学习,多练习,不断巩固。"; | |
157 | + } else if (after >= 60) { | |
158 | + comment = "薄弱知识点还有进步空间,再多做一些类似题目来巩固知识点,继续努力。"; | |
159 | + } else { | |
160 | + comment = "你的薄弱知识点还需要再深入了解,有不清楚的地方及时问老师,继续加油。"; | |
161 | + } | |
162 | + String percent = new DecimalFormat("0%").format(after / 100); | |
163 | + String temp = indent + "通过学习,你的薄弱知识点掌握程度为 %s," + comment; | |
164 | + temp = String.format(temp, fromColor(percent, "#F24E38")); | |
165 | + binding.tvWeakRate.setText(Html.fromHtml(temp, Html.FROM_HTML_MODE_COMPACT)); | |
166 | + } | |
167 | + | |
168 | + binding.tvTotalRate.setText(new DecimalFormat("0").format(100f * data.correct / data.total)); | |
169 | + binding.tvTotalCorrect.setText(String.valueOf(data.correct)); | |
170 | + binding.tvTotalError.setText(String.valueOf(data.total - data.correct)); | |
171 | + if (data.total == 0) { | |
172 | + binding.tvRating.setText(""); | |
173 | + } else { | |
174 | + float rate = 100f * data.correct / data.total; | |
175 | + String comment; | |
176 | + if (rate >= 90) { | |
177 | + comment = "掌握程度比较优秀,你对知识的理解和运用能力非常强,这是你努力的结果。请继续保持这份优秀,在未来的学习中,可以继续挑战更难的题目,勇攀高峰。"; | |
178 | + } else if (rate >= 80) { | |
179 | + comment = "掌握良好。接下来,跟随老师的学习规划,针对薄弱环节重点突破。加油,只要持之以恒,坚持下去,你一定会更加出色。"; | |
180 | + } else if (rate >= 60) { | |
181 | + comment = "掌握程度一般。不过别灰心,你有提升的潜力。跟随老师的步伐,制定合理的学习计划,多做一些练习题来巩固知识。老师相信你一定可以做到。"; | |
182 | + } else { | |
183 | + comment = "掌握程度较为薄弱。但不要放弃,这正是你奋起直追的好时机。认真分析自己的问题,从基础开始逐步提升。老师会一直支持你,只要你有决心,就没有克服不了的困难。"; | |
184 | + } | |
185 | + String rateStr = new DecimalFormat("0%").format(rate / 100f); | |
186 | + String temp; | |
187 | + if (type == 0) { | |
188 | + temp = indent + "在本周作业中,你的综合正确率是 %s," + comment; | |
189 | + } else { | |
190 | + temp = indent + "你的综合正确率是 %s," + comment; | |
191 | + } | |
192 | + temp = String.format(temp, fromColor(rateStr, "#3BC3B6")); | |
193 | + binding.tvRating.setText(Html.fromHtml(temp, Html.FROM_HTML_MODE_COMPACT)); | |
194 | + } | |
195 | + | |
196 | + List<Entry> entries = new ArrayList<>(); | |
197 | + if (type == 0) { | |
198 | + entries.add(new Entry(1, data.mondayCorrection)); | |
199 | + entries.add(new Entry(2, data.tuesdayCorrection)); | |
200 | + entries.add(new Entry(3, data.wednesdayCorrection)); | |
201 | + entries.add(new Entry(4, data.thursdayCorrection)); | |
202 | + entries.add(new Entry(5, data.fridayCorrection)); | |
203 | + } else { | |
204 | + for (int i = 0; i < data.correctionList.size(); i ++) { | |
205 | + StDetail.Correction c = data.correctionList.get(i); | |
206 | + entries.add(new Entry(i, c.correction)); | |
207 | + } | |
208 | + XAxis xAxis = binding.lineChart.getXAxis(); | |
209 | + xAxis.setLabelCount(Math.min(entries.size(), 5), true); | |
210 | + xAxis.setValueFormatter(new ValueFormatter() { | |
211 | + SimpleDateFormat format = new SimpleDateFormat("M.d", Locale.CHINA); | |
212 | + @Override | |
213 | + public String getFormattedValue(float value) { | |
214 | + int index = (int) value; | |
215 | + if (index < 0 || index >= data.correctionList.size()) return ""; | |
216 | + Date date = data.correctionList.get(index).date; | |
217 | + return format.format(date); | |
218 | + } | |
219 | + }); | |
220 | + } | |
221 | + | |
222 | + LineDataSet set = new LineDataSet(entries, ""); | |
223 | + set.setColor(0xFF3BC3B6); | |
224 | + set.setCircleColor(0xFF3BC3B6); | |
225 | + set.setDrawFilled(true); | |
226 | + set.setDrawCircles(type == 0 || entries.size() == 1); | |
227 | + set.setDrawValues(false); | |
228 | + set.setHighlightEnabled(false); | |
229 | + set.setDrawHighlightIndicators(false); | |
230 | + set.setFillDrawable(ResourcesCompat.getDrawable(getResources(), R.drawable.bg_line_chart_fill2, null)); | |
231 | + binding.lineChart.setData(new LineData(set)); | |
232 | + binding.lineChart.invalidate(); | |
233 | + | |
234 | + if (!data.points.isEmpty()) { | |
235 | + int exNo = 0, goodNo = 0, normalNo = 0, weakNo = 0; | |
236 | + float total = 0; | |
237 | + for (StDetail.Point point: data.points) { | |
238 | + total += point.afterState; | |
239 | + if (point.afterState >= 0.9) { | |
240 | + exNo ++; | |
241 | + } else if (point.afterState >= 0.8) { | |
242 | + goodNo ++; | |
243 | + } else if (point.afterState >= 0.6) { | |
244 | + normalNo ++; | |
245 | + } else { | |
246 | + weakNo ++; | |
247 | + } | |
248 | + } | |
249 | + binding.tvExcellent.setText(String.valueOf(exNo)); | |
250 | + binding.tvGood.setText(String.valueOf(goodNo)); | |
251 | + binding.tvNormal.setText(String.valueOf(normalNo)); | |
252 | + binding.tvWeak.setText(String.valueOf(weakNo)); | |
253 | + | |
254 | + float exRate = 100f * exNo / data.points.size(); | |
255 | + float goodRate = 100f * goodNo / data.points.size(); | |
256 | + float normalRate = 100f * normalNo / data.points.size(); | |
257 | + float weakRate = 100f * weakNo / data.points.size(); | |
258 | + binding.cpGood.setValue(goodRate + normalRate + weakRate); | |
259 | + binding.cpNormal.setValue(normalRate + weakRate); | |
260 | + binding.cpWeak.setValue(weakRate); | |
261 | + binding.tvAvePoint.setText(new DecimalFormat("0").format(100f * total / data.points.size())); | |
262 | + } | |
263 | + | |
264 | + List<StDetail.Point> points = new ArrayList<>(); | |
265 | + for (StDetail.Point point: data.points) { | |
266 | + if (point.beforeState < 1) points.add(point); | |
267 | + } | |
268 | + binding.tableRoot.setClipToOutline(true); | |
269 | + binding.rvPoint.setAdapter(new Adapter(points)); | |
270 | + binding.tableRoot.setVisibility(points.isEmpty() ? View.GONE : View.VISIBLE); | |
271 | + binding.flPointDesc.setVisibility(points.isEmpty() ? View.GONE : View.VISIBLE); | |
272 | + binding.flEmptyPoints.setVisibility(points.isEmpty() ? View.VISIBLE : View.GONE); | |
273 | + } | |
274 | + | |
275 | + private void setupChart() { | |
276 | + binding.lineChart.getLegend().setForm(Legend.LegendForm.NONE); | |
277 | + binding.lineChart.setScaleEnabled(false); | |
278 | + binding.lineChart.setTouchEnabled(false); | |
279 | + binding.lineChart.setDescription(null); | |
280 | + binding.lineChart.getAxisRight().setEnabled(false); | |
281 | + YAxis yAxis = binding.lineChart.getAxisLeft(); | |
282 | + yAxis.setDrawAxisLine(false); | |
283 | + yAxis.setDrawGridLines(true); | |
284 | + yAxis.setGridColor(0xFFDDDDDD); | |
285 | + yAxis.setTextColor(0xFF333333); | |
286 | + if (type == 0) { | |
287 | + yAxis.setTextSize(16); | |
288 | + yAxis.setXOffset(16); | |
289 | + } else { | |
290 | + yAxis.setTextSize(13); | |
291 | + } | |
292 | + yAxis.setAxisMinimum(0); | |
293 | + yAxis.setAxisMaximum(1); | |
294 | + yAxis.setLabelCount(5, true); | |
295 | + yAxis.setValueFormatter(new ValueFormatter() { | |
296 | + @Override | |
297 | + public String getFormattedValue(float value) { | |
298 | + return new DecimalFormat("0%").format(value); | |
299 | + } | |
300 | + }); | |
301 | + | |
302 | + XAxis xAxis = binding.lineChart.getXAxis(); | |
303 | + xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); | |
304 | + xAxis.setDrawAxisLine(false); | |
305 | + xAxis.setDrawGridLines(false); | |
306 | + xAxis.setTextColor(0xFF333333); | |
307 | + xAxis.setTextSize(16); | |
308 | + xAxis.setYOffset(16); | |
309 | + if (type == 0) { | |
310 | + xAxis.setAxisMinimum(0.5f); | |
311 | + xAxis.setAxisMaximum(5.5f); | |
312 | + xAxis.setLabelCount(11, true); | |
313 | + xAxis.setValueFormatter(new ValueFormatter() { | |
314 | + @Override | |
315 | + public String getFormattedValue(float value) { | |
316 | + if (value == 1) { | |
317 | + return "周一"; | |
318 | + } else if (value == 2) { | |
319 | + return "周二"; | |
320 | + } else if (value == 3) { | |
321 | + return "周三"; | |
322 | + } else if (value == 4) { | |
323 | + return "周四"; | |
324 | + } else if (value == 5) { | |
325 | + return "周五"; | |
326 | + } | |
327 | + return ""; | |
328 | + } | |
329 | + }); | |
330 | + } else { | |
331 | + xAxis.setTextSize(13); | |
332 | + } | |
333 | + } | |
334 | + | |
335 | + private String fromColor(String str, String color) { | |
336 | + return String.format("<font color='%s'><b>%s</b></font>", color, str); | |
337 | + } | |
338 | + | |
339 | + private void switchPage() { | |
340 | + Intent intent = new Intent(getIntent()); | |
341 | + intent.putExtra("a4", !a4); | |
342 | + startActivity(intent); | |
343 | + finish(); | |
344 | + } | |
345 | + | |
346 | + private Uri prepareShare() { | |
347 | + try { | |
348 | + binding.toolbar.setVisibility(View.INVISIBLE); | |
349 | + Bitmap bitmap = BitmapUtils.shotView(binding.root); | |
350 | + binding.toolbar.setVisibility(View.VISIBLE); | |
351 | + | |
352 | + String fileName = student.stuName + "_周作业学习报告_" + System.currentTimeMillis(); | |
353 | + return ContentUtil.saveBitmapToGallery(this, bitmap, fileName); | |
354 | + } catch (Exception e) { | |
355 | + e.printStackTrace(); | |
356 | + } | |
357 | + return null; | |
358 | + } | |
359 | + | |
360 | + @Override | |
361 | + protected ActivityHuyouDetailBinding getViewBinding() { | |
362 | + a4 = getIntent().getBooleanExtra("a4", false); | |
363 | + View view; | |
364 | + if (a4) view = getLayoutInflater().inflate(R.layout.activity_huyou_detail_a4, null); | |
365 | + else view = getLayoutInflater().inflate(R.layout.activity_huyou_detail, null); | |
366 | + return ActivityHuyouDetailBinding.bind(view); | |
367 | + } | |
368 | + | |
369 | + public static class Adapter extends BaseQuickAdapter<StDetail.Point, BaseViewHolder> { | |
370 | + | |
371 | + public Adapter(@Nullable List<StDetail.Point> data) { | |
372 | + super(R.layout.item_huyou_point, data); | |
373 | + } | |
374 | + | |
375 | + @Override | |
376 | + protected void convert(@NonNull BaseViewHolder holder, StDetail.Point point) { | |
377 | + DecimalFormat format1 = new DecimalFormat("0%"); | |
378 | + DecimalFormat format2 = new DecimalFormat("0"); | |
379 | + holder.setText(R.id.tvName, point.pointName); | |
380 | + holder.setText(R.id.tvBefore, format1.format(point.beforeState)); | |
381 | + holder.setText(R.id.tvAfter, format1.format(point.afterState)); | |
382 | + holder.setText(R.id.tvGap, format2.format(point.gap * 100)); | |
383 | + holder.setGone(R.id.ivFlag, getData().indexOf(point) == 0); | |
384 | + holder.<TextView>getView(R.id.tvName).setTooltipText(point.pointName); | |
385 | + | |
386 | + TextView before = holder.getView(R.id.tvBeforeState); | |
387 | + TextView after = holder.getView(R.id.tvAfterState); | |
388 | + | |
389 | + if (point.beforeState >= 0.9) { | |
390 | + before.setText("掌握优秀"); | |
391 | + before.setBackgroundTintList(ColorStateList.valueOf(0xFF4FBB7A)); | |
392 | + } else if (point.beforeState >= 0.8) { | |
393 | + before.setText("掌握良好"); | |
394 | + before.setBackgroundTintList(ColorStateList.valueOf(0xFF489AFA)); | |
395 | + } else if (point.beforeState >= 0.6) { | |
396 | + before.setText("掌握一般"); | |
397 | + before.setBackgroundTintList(ColorStateList.valueOf(0xFFF58725)); | |
398 | + } else { | |
399 | + before.setText("掌握薄弱"); | |
400 | + before.setBackgroundTintList(ColorStateList.valueOf(0xFFEA5127)); | |
401 | + } | |
402 | + if (point.afterState >= 0.9) { | |
403 | + after.setText("掌握优秀"); | |
404 | + after.setBackgroundTintList(ColorStateList.valueOf(0xFF4FBB7A)); | |
405 | + } else if (point.afterState >= 0.8) { | |
406 | + after.setText("掌握良好"); | |
407 | + after.setBackgroundTintList(ColorStateList.valueOf(0xFF489AFA)); | |
408 | + } else if (point.afterState >= 0.6) { | |
409 | + after.setText("掌握一般"); | |
410 | + after.setBackgroundTintList(ColorStateList.valueOf(0xFFF58725)); | |
411 | + } else { | |
412 | + after.setText("掌握薄弱"); | |
413 | + after.setBackgroundTintList(ColorStateList.valueOf(0xFFEA5127)); | |
414 | + } | |
415 | + | |
416 | + holder.setText(R.id.tvHuyou, format1.format(point.correctness)); | |
417 | + } | |
418 | + | |
419 | + } | |
420 | + | |
421 | +} | ... | ... |
app/src/main/java/com/hjx/parent/StuHomeworkActivity.java
... | ... | @@ -131,10 +131,21 @@ public class StuHomeworkActivity extends BaseRxActivity<ActivityStudentHomeworkB |
131 | 131 | stageHuyouDialog.show(this::generalStage); |
132 | 132 | }); |
133 | 133 | |
134 | + weekAdapter.detailCall = data -> goHuyou(data, 0); | |
135 | + stageAdapter.detailCall = data -> goHuyou(data, 1); | |
136 | + | |
134 | 137 | getWeekHuyou(); |
135 | 138 | getStageHuyou(); |
136 | 139 | } |
137 | 140 | |
141 | + private void goHuyou(StDetail data, int type) { | |
142 | + Intent intent = new Intent(this, HuyouDetailActivity.class); | |
143 | + intent.putExtra("id", data.id); | |
144 | + intent.putExtra("type", type); | |
145 | + intent.putExtra("student", state.student); | |
146 | + startActivity(intent); | |
147 | + } | |
148 | + | |
138 | 149 | @Override |
139 | 150 | protected void onStart() { |
140 | 151 | super.onStart(); |
... | ... | @@ -422,6 +433,7 @@ public class StuHomeworkActivity extends BaseRxActivity<ActivityStudentHomeworkB |
422 | 433 | |
423 | 434 | static class HuyouAdapter extends BaseQuickAdapter<StDetail, BaseViewHolder> { |
424 | 435 | public Function1<StDetail> deleteCall; |
436 | + public Function1<StDetail> detailCall; | |
425 | 437 | public Student student; |
426 | 438 | |
427 | 439 | public HuyouAdapter(@Nullable List<StDetail> data) { |
... | ... | @@ -458,6 +470,14 @@ public class StuHomeworkActivity extends BaseRxActivity<ActivityStudentHomeworkB |
458 | 470 | String title = startStr + endStr + data.homeworkSubject + typeStr; |
459 | 471 | holder.setText(R.id.tvName, title); |
460 | 472 | holder.setText(R.id.tvGrade, data.grade); |
473 | + View btnDelete = holder.getView(R.id.btnDelete); | |
474 | + View btnDetail = holder.getView(R.id.btnDetail); | |
475 | + btnDelete.setOnClickListener(v -> { | |
476 | + if (deleteCall != null) deleteCall.invoke(data); | |
477 | + }); | |
478 | + btnDetail.setOnClickListener(v -> { | |
479 | + if (detailCall != null) detailCall.invoke(data); | |
480 | + }); | |
461 | 481 | } |
462 | 482 | |
463 | 483 | private SimpleDateFormat getFormatWithGmt8(String pattern) { | ... | ... |
app/src/main/res/drawable/bg_circle.xml
app/src/main/res/drawable/bg_huyou_a4.xml
... | ... | @@ -0,0 +1,12 @@ |
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | |
3 | + | |
4 | + <item> | |
5 | + <color android:color="#CEF1EC"/> | |
6 | + </item> | |
7 | + | |
8 | + <item android:width="104dp" android:height="66dp" | |
9 | + android:start="30dp" android:top="-16dp" | |
10 | + android:drawable="@drawable/png_huyou_logo"/> | |
11 | + | |
12 | +</layer-list> | |
0 | 13 | \ No newline at end of file | ... | ... |
app/src/main/res/drawable/bg_huyou_table_bg.xml
app/src/main/res/drawable/bg_hy_analyse_title.xml
... | ... | @@ -0,0 +1,17 @@ |
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | |
3 | + | |
4 | + <item android:height="5dp" | |
5 | + android:gravity="bottom"> | |
6 | + <shape> | |
7 | + <corners android:radius="8dp"/> | |
8 | + <solid android:color="#50CEC2"/> | |
9 | + </shape> | |
10 | + </item> | |
11 | + | |
12 | + <item android:drawable="@drawable/png_hy_analyse_title" | |
13 | + android:gravity="bottom" android:bottom="1dp" android:start="4dp" | |
14 | + android:width="18dp" android:height="22dp" /> | |
15 | + | |
16 | + | |
17 | +</layer-list> | |
0 | 18 | \ No newline at end of file | ... | ... |
app/src/main/res/drawable/bg_hy_point_title.xml
... | ... | @@ -0,0 +1,17 @@ |
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | |
3 | + | |
4 | + <item android:height="5dp" | |
5 | + android:gravity="bottom"> | |
6 | + <shape> | |
7 | + <corners android:radius="8dp"/> | |
8 | + <solid android:color="#50CEC2"/> | |
9 | + </shape> | |
10 | + </item> | |
11 | + | |
12 | + <item android:drawable="@drawable/png_hy_point_title" | |
13 | + android:gravity="bottom" android:start="2dp" android:bottom="4dp" | |
14 | + android:width="21dp" android:height="15dp" /> | |
15 | + | |
16 | + | |
17 | +</layer-list> | |
0 | 18 | \ No newline at end of file | ... | ... |
app/src/main/res/drawable/bg_hy_summary_title.xml
... | ... | @@ -0,0 +1,17 @@ |
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | |
3 | + | |
4 | + <item android:height="5dp" | |
5 | + android:gravity="bottom"> | |
6 | + <shape> | |
7 | + <corners android:radius="8dp"/> | |
8 | + <solid android:color="#50CEC2"/> | |
9 | + </shape> | |
10 | + </item> | |
11 | + | |
12 | + <item android:drawable="@drawable/png_hy_summary_title" | |
13 | + android:gravity="bottom" android:start="2dp" android:bottom="3dp" | |
14 | + android:width="22dp" android:height="16dp" /> | |
15 | + | |
16 | + | |
17 | +</layer-list> | |
0 | 18 | \ No newline at end of file | ... | ... |
app/src/main/res/drawable/bg_hy_weak_title.xml
... | ... | @@ -0,0 +1,17 @@ |
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> | |
3 | + | |
4 | + <item android:height="5dp" | |
5 | + android:gravity="bottom"> | |
6 | + <shape> | |
7 | + <corners android:radius="8dp"/> | |
8 | + <solid android:color="#50CEC2"/> | |
9 | + </shape> | |
10 | + </item> | |
11 | + | |
12 | + <item android:drawable="@drawable/png_hy_weak_title" | |
13 | + android:gravity="bottom" android:bottom="2dp" | |
14 | + android:width="16dp" android:height="18dp" /> | |
15 | + | |
16 | + | |
17 | +</layer-list> | |
0 | 18 | \ No newline at end of file | ... | ... |
app/src/main/res/drawable/bg_line_chart_fill2.xml
... | ... | @@ -0,0 +1,9 @@ |
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<shape xmlns:android="http://schemas.android.com/apk/res/android"> | |
3 | + | |
4 | + <gradient | |
5 | + android:startColor="#AA3BC3B6" | |
6 | + android:endColor="#00FFFFFF" | |
7 | + android:angle="-90"/> | |
8 | + | |
9 | +</shape> | |
0 | 10 | \ No newline at end of file | ... | ... |
app/src/main/res/drawable/png_huyou_logo.png
25.9 KB
app/src/main/res/drawable/png_huyou_points_empty.png
65.2 KB
app/src/main/res/drawable/png_huyou_progress_bg.png
19.4 KB
app/src/main/res/drawable/png_huyou_top_bg.png
41.1 KB
app/src/main/res/drawable/png_hy_analyse_title.png
3.88 KB
app/src/main/res/drawable/png_hy_point_title.png
3.22 KB
app/src/main/res/drawable/png_hy_summary_comment.png
3.63 KB
app/src/main/res/drawable/png_hy_summary_title.png
3.33 KB
app/src/main/res/drawable/png_hy_weak_comment.png
3.25 KB
app/src/main/res/drawable/png_hy_weak_title.png
3.18 KB
app/src/main/res/drawable/png_ic_during.png
2.33 KB
app/src/main/res/drawable/png_ic_excellent.png
7.66 KB
app/src/main/res/drawable/png_ic_good.png
9.47 KB
app/src/main/res/drawable/png_ic_normal.png
9.43 KB
app/src/main/res/drawable/png_ic_weak.png
8.71 KB
app/src/main/res/drawable/png_info_bg.png
11.7 KB
app/src/main/res/drawable/png_iv_subject.png
2.45 KB
app/src/main/res/drawable/png_up.png
664 Bytes
app/src/main/res/drawable/shape_radius_2.xml
app/src/main/res/layout/activity_huyou_detail.xml
... | ... | @@ -0,0 +1,1074 @@ |
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<FrameLayout | |
3 | + xmlns:android="http://schemas.android.com/apk/res/android" | |
4 | + xmlns:tools="http://schemas.android.com/tools" | |
5 | + xmlns:app="http://schemas.android.com/apk/res-auto" | |
6 | + android:layout_width="match_parent" | |
7 | + android:layout_height="match_parent" | |
8 | + tools:ignore="HardcodedText,ContentDescription,SmallSp,UseCompoundDrawables,RtlSymmetry"> | |
9 | +<androidx.core.widget.NestedScrollView | |
10 | + android:layout_gravity="center_horizontal" | |
11 | + android:layout_width="wrap_content" | |
12 | + android:layout_height="match_parent"> | |
13 | + | |
14 | + <LinearLayout | |
15 | + android:id="@+id/root" | |
16 | + android:orientation="vertical" | |
17 | + android:background="#CEF1EC" | |
18 | + android:layout_width="378dp" | |
19 | + android:layout_height="match_parent"> | |
20 | + | |
21 | + <FrameLayout | |
22 | + android:orientation="horizontal" | |
23 | + android:paddingHorizontal="16dp" | |
24 | + android:layout_marginTop="34dp" | |
25 | + android:layout_width="match_parent" | |
26 | + android:layout_height="wrap_content"> | |
27 | + <FrameLayout | |
28 | + android:id="@+id/toolbar" | |
29 | + android:layout_gravity="center_vertical" | |
30 | + android:layout_width="match_parent" | |
31 | + android:layout_height="wrap_content"> | |
32 | + <TextView | |
33 | + android:id="@+id/btnSwitch" | |
34 | + android:text="A4版" | |
35 | + android:textSize="16sp" | |
36 | + android:textColor="#333" | |
37 | + android:layout_marginStart="48dp" | |
38 | + android:layout_width="wrap_content" | |
39 | + android:layout_height="wrap_content"/> | |
40 | + <TextView | |
41 | + android:id="@+id/btnShare" | |
42 | + android:text="分享" | |
43 | + android:textSize="16sp" | |
44 | + android:textColor="#333" | |
45 | + android:layout_width="wrap_content" | |
46 | + android:layout_height="wrap_content"/> | |
47 | + <TextView | |
48 | + android:id="@+id/btnSame" | |
49 | + android:visibility="gone" | |
50 | + android:text="举一反三" | |
51 | + android:textSize="16sp" | |
52 | + android:textColor="#333" | |
53 | + android:layout_gravity="center_vertical|end" | |
54 | + android:layout_width="wrap_content" | |
55 | + android:layout_height="wrap_content"/> | |
56 | + </FrameLayout> | |
57 | + <TextView | |
58 | + android:id="@+id/tvTitle" | |
59 | + android:text="周作业学习报告" | |
60 | + android:textSize="18sp" | |
61 | + android:textColor="#333" | |
62 | + android:textStyle="bold" | |
63 | + android:layout_gravity="center_horizontal" | |
64 | + android:layout_width="wrap_content" | |
65 | + android:layout_height="wrap_content" /> | |
66 | + </FrameLayout> | |
67 | + | |
68 | + | |
69 | + <ImageView | |
70 | + android:src="@drawable/png_huyou_top_bg" | |
71 | + android:elevation="1dp" | |
72 | + android:layout_gravity="end" | |
73 | + android:layout_marginHorizontal="16dp" | |
74 | + android:layout_width="102dp" | |
75 | + android:layout_height="90dp"/> | |
76 | + | |
77 | + <LinearLayout | |
78 | + android:orientation="vertical" | |
79 | + android:background="@drawable/png_info_bg" | |
80 | + android:padding="16dp" | |
81 | + android:layout_marginHorizontal="16dp" | |
82 | + android:layout_marginTop="-60dp" | |
83 | + android:layout_width="match_parent" | |
84 | + android:layout_height="144dp"> | |
85 | + <LinearLayout | |
86 | + android:orientation="horizontal" | |
87 | + android:layout_width="match_parent" | |
88 | + android:layout_height="wrap_content"> | |
89 | + <androidx.constraintlayout.utils.widget.ImageFilterView | |
90 | + android:id="@+id/ivAvatar" | |
91 | + tools:background="#2491FF" | |
92 | + app:round="40dp" | |
93 | + android:layout_width="40dp" | |
94 | + android:layout_height="40dp"/> | |
95 | + <LinearLayout | |
96 | + android:orientation="vertical" | |
97 | + android:layout_gravity="center_vertical" | |
98 | + android:layout_marginStart="10dp" | |
99 | + android:layout_width="wrap_content" | |
100 | + android:layout_height="wrap_content"> | |
101 | + <TextView | |
102 | + android:id="@+id/tvStuName" | |
103 | + tools:text="杨同学 " | |
104 | + android:textSize="14sp" | |
105 | + android:textColor="#333" | |
106 | + android:textStyle="bold" | |
107 | + android:layout_width="wrap_content" | |
108 | + android:layout_height="wrap_content"/> | |
109 | + <TextView | |
110 | + android:id="@+id/tvGrade" | |
111 | + tools:text="七年级" | |
112 | + android:textSize="13sp" | |
113 | + android:textColor="#666" | |
114 | + android:textStyle="bold" | |
115 | + android:layout_width="wrap_content" | |
116 | + android:layout_height="wrap_content"/> | |
117 | + </LinearLayout> | |
118 | + </LinearLayout> | |
119 | + <LinearLayout | |
120 | + android:orientation="horizontal" | |
121 | + android:background="@drawable/shape_radius_10" | |
122 | + android:backgroundTint="#F4FAFF" | |
123 | + android:layout_marginTop="12dp" | |
124 | + android:layout_width="match_parent" | |
125 | + android:layout_height="60dp"> | |
126 | + <LinearLayout | |
127 | + android:orientation="vertical" | |
128 | + android:gravity="center" | |
129 | + android:layout_width="0dp" | |
130 | + android:layout_height="match_parent" | |
131 | + android:layout_weight="1"> | |
132 | + <LinearLayout | |
133 | + android:paddingEnd="20dp" | |
134 | + android:gravity="center_vertical" | |
135 | + android:layout_width="wrap_content" | |
136 | + android:layout_height="wrap_content"> | |
137 | + <ImageView | |
138 | + android:src="@drawable/png_iv_subject" | |
139 | + android:layout_marginEnd="5dp" | |
140 | + android:layout_width="16dp" | |
141 | + android:layout_height="14dp"/> | |
142 | + <TextView | |
143 | + android:text="学科" | |
144 | + android:textSize="12sp" | |
145 | + android:textColor="#333" | |
146 | + android:textStyle="bold" | |
147 | + android:layout_width="wrap_content" | |
148 | + android:layout_height="wrap_content"/> | |
149 | + </LinearLayout> | |
150 | + <TextView | |
151 | + android:id="@+id/tvSubject" | |
152 | + tools:text="数学" | |
153 | + android:textSize="12sp" | |
154 | + android:textColor="#3BC3B6" | |
155 | + android:textStyle="bold" | |
156 | + android:layout_marginTop="8dp" | |
157 | + android:layout_width="wrap_content" | |
158 | + android:layout_height="wrap_content"/> | |
159 | + </LinearLayout> | |
160 | + <LinearLayout | |
161 | + android:orientation="vertical" | |
162 | + android:gravity="center" | |
163 | + android:layout_width="0dp" | |
164 | + android:layout_height="match_parent" | |
165 | + android:layout_weight="1"> | |
166 | + <LinearLayout | |
167 | + android:paddingEnd="20dp" | |
168 | + android:gravity="center_vertical" | |
169 | + android:layout_width="wrap_content" | |
170 | + android:layout_height="wrap_content"> | |
171 | + <ImageView | |
172 | + android:src="@drawable/png_ic_during" | |
173 | + android:layout_marginEnd="5dp" | |
174 | + android:layout_width="14dp" | |
175 | + android:layout_height="13dp"/> | |
176 | + <TextView | |
177 | + android:text="周期" | |
178 | + android:textSize="12sp" | |
179 | + android:textColor="#333" | |
180 | + android:textStyle="bold" | |
181 | + android:layout_width="wrap_content" | |
182 | + android:layout_height="wrap_content"/> | |
183 | + </LinearLayout> | |
184 | + <TextView | |
185 | + android:id="@+id/tvDate" | |
186 | + tools:text="2024.09.01-2024.09.30" | |
187 | + android:textSize="12sp" | |
188 | + android:textColor="#3BC3B6" | |
189 | + android:textStyle="bold" | |
190 | + android:layout_marginTop="8dp" | |
191 | + android:layout_width="wrap_content" | |
192 | + android:layout_height="wrap_content"/> | |
193 | + </LinearLayout> | |
194 | + </LinearLayout> | |
195 | + </LinearLayout> | |
196 | + | |
197 | + <LinearLayout | |
198 | + android:orientation="vertical" | |
199 | + android:background="@drawable/shape_radius_10" | |
200 | + android:backgroundTint="@color/white" | |
201 | + android:padding="16dp" | |
202 | + android:layout_marginHorizontal="16dp" | |
203 | + android:layout_marginTop="12dp" | |
204 | + android:layout_width="match_parent" | |
205 | + android:layout_height="wrap_content"> | |
206 | + <TextView | |
207 | + android:text="薄弱知识点总评" | |
208 | + android:textSize="16sp" | |
209 | + android:textColor="#333333" | |
210 | + android:textStyle="bold" | |
211 | + android:background="@drawable/bg_hy_weak_title" | |
212 | + android:paddingStart="20dp" | |
213 | + android:paddingEnd="4dp" | |
214 | + android:layout_gravity="center_horizontal" | |
215 | + android:layout_width="wrap_content" | |
216 | + android:layout_height="wrap_content"/> | |
217 | + <LinearLayout | |
218 | + android:orientation="horizontal" | |
219 | + android:layout_marginTop="28dp" | |
220 | + android:layout_width="match_parent" | |
221 | + android:layout_height="wrap_content"> | |
222 | + <LinearLayout | |
223 | + android:orientation="vertical" | |
224 | + android:layout_width="0dp" | |
225 | + android:layout_height="wrap_content" | |
226 | + android:layout_weight="1"> | |
227 | + <TextView | |
228 | + android:text="学习前" | |
229 | + android:textSize="12sp" | |
230 | + android:textColor="#333" | |
231 | + android:layout_gravity="center_horizontal" | |
232 | + android:layout_width="wrap_content" | |
233 | + android:layout_height="wrap_content"/> | |
234 | + <FrameLayout | |
235 | + android:background="@drawable/png_huyou_progress_bg" | |
236 | + android:padding="8dp" | |
237 | + android:layout_gravity="center_horizontal" | |
238 | + android:layout_marginTop="16dp" | |
239 | + android:layout_width="126dp" | |
240 | + android:layout_height="126dp"> | |
241 | + <com.littlejie.circleprogress.CircleProgress | |
242 | + android:id="@+id/cpBefore" | |
243 | + app:arcWidth="15dp" | |
244 | + app:bgArcWidth="15dp" | |
245 | + app:arcColors="#F36A27" | |
246 | + app:bgArcColor="#FFF1EA" | |
247 | + app:startAngle="-90" | |
248 | + app:sweepAngle="360" | |
249 | + app:maxValue="100" | |
250 | + app:value="0" | |
251 | + app:hintColor="@color/transparent" | |
252 | + app:unitColor="@color/transparent" | |
253 | + app:valueColor="@color/transparent" | |
254 | + android:layout_width="match_parent" | |
255 | + android:layout_height="match_parent"/> | |
256 | + <LinearLayout | |
257 | + android:orientation="vertical" | |
258 | + android:gravity="center_horizontal" | |
259 | + android:layout_gravity="center" | |
260 | + android:layout_width="wrap_content" | |
261 | + android:layout_height="wrap_content"> | |
262 | + <LinearLayout | |
263 | + android:layout_width="wrap_content" | |
264 | + android:layout_height="wrap_content"> | |
265 | + <TextView | |
266 | + android:id="@+id/pgBefore" | |
267 | + tools:text="88" | |
268 | + android:textSize="25sp" | |
269 | + android:textColor="#EA5127" | |
270 | + android:textStyle="bold" | |
271 | + android:layout_width="wrap_content" | |
272 | + android:layout_height="wrap_content"/> | |
273 | + <TextView | |
274 | + android:text="%" | |
275 | + android:textSize="12sp" | |
276 | + android:textColor="#EA5127" | |
277 | + android:layout_width="wrap_content" | |
278 | + android:layout_height="wrap_content"/> | |
279 | + </LinearLayout> | |
280 | + <TextView | |
281 | + android:text="整体掌握程度" | |
282 | + android:textSize="10sp" | |
283 | + android:textColor="#333" | |
284 | + android:textStyle="bold" | |
285 | + android:layout_marginTop="-2dp" | |
286 | + android:layout_width="wrap_content" | |
287 | + android:layout_height="wrap_content"/> | |
288 | + </LinearLayout> | |
289 | + </FrameLayout> | |
290 | + </LinearLayout> | |
291 | + <LinearLayout | |
292 | + android:orientation="vertical" | |
293 | + android:layout_width="0dp" | |
294 | + android:layout_height="wrap_content" | |
295 | + android:layout_weight="1"> | |
296 | + <TextView | |
297 | + android:text="学习后" | |
298 | + android:textSize="12sp" | |
299 | + android:textColor="#333" | |
300 | + android:layout_gravity="center_horizontal" | |
301 | + android:layout_width="wrap_content" | |
302 | + android:layout_height="wrap_content"/> | |
303 | + <FrameLayout | |
304 | + android:background="@drawable/png_huyou_progress_bg" | |
305 | + android:padding="8dp" | |
306 | + android:layout_gravity="center_horizontal" | |
307 | + android:layout_marginTop="16dp" | |
308 | + android:layout_width="126dp" | |
309 | + android:layout_height="126dp"> | |
310 | + <com.littlejie.circleprogress.CircleProgress | |
311 | + android:id="@+id/cpAfter" | |
312 | + app:arcWidth="15dp" | |
313 | + app:bgArcWidth="15dp" | |
314 | + app:arcColors="#3BC3B6" | |
315 | + app:bgArcColor="#C2FCF6" | |
316 | + app:startAngle="-90" | |
317 | + app:sweepAngle="360" | |
318 | + app:maxValue="100" | |
319 | + app:value="0" | |
320 | + app:hintColor="@color/transparent" | |
321 | + app:unitColor="@color/transparent" | |
322 | + app:valueColor="@color/transparent" | |
323 | + android:layout_width="match_parent" | |
324 | + android:layout_height="match_parent"/> | |
325 | + <LinearLayout | |
326 | + android:orientation="vertical" | |
327 | + android:gravity="center_horizontal" | |
328 | + android:layout_gravity="center" | |
329 | + android:layout_width="wrap_content" | |
330 | + android:layout_height="wrap_content"> | |
331 | + <LinearLayout | |
332 | + android:layout_width="wrap_content" | |
333 | + android:layout_height="wrap_content"> | |
334 | + <TextView | |
335 | + android:id="@+id/pgAfter" | |
336 | + tools:text="88" | |
337 | + android:textSize="25sp" | |
338 | + android:textColor="#3BC3B6" | |
339 | + android:textStyle="bold" | |
340 | + android:layout_width="wrap_content" | |
341 | + android:layout_height="wrap_content"/> | |
342 | + <TextView | |
343 | + android:text="%" | |
344 | + android:textSize="12sp" | |
345 | + android:textColor="#3BC3B6" | |
346 | + android:layout_width="wrap_content" | |
347 | + android:layout_height="wrap_content"/> | |
348 | + </LinearLayout> | |
349 | + <TextView | |
350 | + android:text="整体掌握程度" | |
351 | + android:textSize="10sp" | |
352 | + android:textColor="#333" | |
353 | + android:textStyle="bold" | |
354 | + android:layout_marginTop="-2dp" | |
355 | + android:layout_width="wrap_content" | |
356 | + android:layout_height="wrap_content"/> | |
357 | + </LinearLayout> | |
358 | + </FrameLayout> | |
359 | + </LinearLayout> | |
360 | + </LinearLayout> | |
361 | + | |
362 | + <FrameLayout | |
363 | + android:layout_marginTop="20dp" | |
364 | + android:layout_width="match_parent" | |
365 | + android:layout_height="wrap_content"> | |
366 | + <ImageView | |
367 | + android:src="@drawable/png_hy_weak_comment" | |
368 | + android:layout_width="16dp" | |
369 | + android:layout_height="18dp"/> | |
370 | + <TextView | |
371 | + android:id="@+id/tvWeakRate" | |
372 | + android:textSize="16sp" | |
373 | + android:textColor="#333" | |
374 | + android:lineSpacingMultiplier="1.3" | |
375 | + android:layout_width="wrap_content" | |
376 | + android:layout_height="wrap_content"/> | |
377 | + </FrameLayout> | |
378 | + </LinearLayout> | |
379 | + | |
380 | + <LinearLayout | |
381 | + android:orientation="vertical" | |
382 | + android:background="@drawable/shape_radius_10" | |
383 | + android:backgroundTint="@color/white" | |
384 | + android:padding="16dp" | |
385 | + android:layout_marginHorizontal="16dp" | |
386 | + android:layout_marginTop="12dp" | |
387 | + android:layout_width="match_parent" | |
388 | + android:layout_height="wrap_content"> | |
389 | + | |
390 | + <TextView | |
391 | + android:text="作业概括" | |
392 | + android:textSize="16sp" | |
393 | + android:textColor="#333333" | |
394 | + android:textStyle="bold" | |
395 | + android:background="@drawable/bg_hy_summary_title" | |
396 | + android:paddingStart="28dp" | |
397 | + android:paddingEnd="4dp" | |
398 | + android:layout_gravity="center_horizontal" | |
399 | + android:layout_width="wrap_content" | |
400 | + android:layout_height="wrap_content"/> | |
401 | + <LinearLayout | |
402 | + android:orientation="horizontal" | |
403 | + android:background="@drawable/shape_radius_5" | |
404 | + android:backgroundTint="#F4FAFF" | |
405 | + android:layout_width="match_parent" | |
406 | + android:layout_height="80dp" | |
407 | + android:layout_marginTop="16dp"> | |
408 | + <LinearLayout | |
409 | + android:orientation="vertical" | |
410 | + android:gravity="center" | |
411 | + android:layout_width="0dp" | |
412 | + android:layout_height="match_parent" | |
413 | + android:layout_weight="1"> | |
414 | + <LinearLayout | |
415 | + android:orientation="horizontal" | |
416 | + android:gravity="center_vertical" | |
417 | + android:layout_width="wrap_content" | |
418 | + android:layout_height="wrap_content"> | |
419 | + <ImageView | |
420 | + android:src="@drawable/png_icon_statistical_accuracy" | |
421 | + android:layout_width="12dp" | |
422 | + android:layout_height="13dp"/> | |
423 | + <TextView | |
424 | + android:text="作业正确率" | |
425 | + android:textSize="11sp" | |
426 | + android:textColor="#333" | |
427 | + android:textStyle="bold" | |
428 | + android:layout_marginStart="5dp" | |
429 | + android:layout_width="wrap_content" | |
430 | + android:layout_height="wrap_content"/> | |
431 | + </LinearLayout> | |
432 | + <LinearLayout | |
433 | + android:orientation="horizontal" | |
434 | + android:layout_marginTop="8dp" | |
435 | + android:layout_width="wrap_content" | |
436 | + android:layout_height="wrap_content"> | |
437 | + <TextView | |
438 | + android:id="@+id/tvTotalRate" | |
439 | + tools:text="88" | |
440 | + android:textSize="14sp" | |
441 | + android:textColor="#3BC3B6" | |
442 | + android:textStyle="bold" | |
443 | + android:layout_width="wrap_content" | |
444 | + android:layout_height="wrap_content"/> | |
445 | + <TextView | |
446 | + android:text="%" | |
447 | + android:textSize="9sp" | |
448 | + android:textColor="#3BC3B6" | |
449 | + android:textStyle="bold" | |
450 | + android:layout_width="wrap_content" | |
451 | + android:layout_height="wrap_content"/> | |
452 | + </LinearLayout> | |
453 | + </LinearLayout> | |
454 | + <View | |
455 | + android:background="#9ECAFC" | |
456 | + android:layout_marginVertical="8dp" | |
457 | + android:layout_width="1dp" | |
458 | + android:layout_height="match_parent"/> | |
459 | + <LinearLayout | |
460 | + android:orientation="vertical" | |
461 | + android:gravity="center" | |
462 | + android:layout_width="0dp" | |
463 | + android:layout_height="match_parent" | |
464 | + android:layout_weight="1"> | |
465 | + <LinearLayout | |
466 | + android:orientation="horizontal" | |
467 | + android:gravity="center_vertical" | |
468 | + android:layout_width="wrap_content" | |
469 | + android:layout_height="wrap_content"> | |
470 | + <ImageView | |
471 | + android:src="@drawable/png_icon_statistical_accuracy" | |
472 | + android:layout_width="12dp" | |
473 | + android:layout_height="13dp"/> | |
474 | + <TextView | |
475 | + android:text="答对题数" | |
476 | + android:textSize="11sp" | |
477 | + android:textColor="#333" | |
478 | + android:textStyle="bold" | |
479 | + android:layout_marginStart="5dp" | |
480 | + android:layout_width="wrap_content" | |
481 | + android:layout_height="wrap_content"/> | |
482 | + </LinearLayout> | |
483 | + <LinearLayout | |
484 | + android:orientation="horizontal" | |
485 | + android:layout_marginTop="8dp" | |
486 | + android:layout_width="wrap_content" | |
487 | + android:layout_height="wrap_content"> | |
488 | + <TextView | |
489 | + android:id="@+id/tvTotalCorrect" | |
490 | + tools:text="88" | |
491 | + android:textSize="14sp" | |
492 | + android:textColor="#3BC3B6" | |
493 | + android:textStyle="bold" | |
494 | + android:layout_width="wrap_content" | |
495 | + android:layout_height="wrap_content"/> | |
496 | + <TextView | |
497 | + android:text="道" | |
498 | + android:textSize="9sp" | |
499 | + android:textColor="#3BC3B6" | |
500 | + android:textStyle="bold" | |
501 | + android:layout_width="wrap_content" | |
502 | + android:layout_height="wrap_content"/> | |
503 | + </LinearLayout> | |
504 | + </LinearLayout> | |
505 | + <View | |
506 | + android:background="#9ECAFC" | |
507 | + android:layout_marginVertical="8dp" | |
508 | + android:layout_width="1dp" | |
509 | + android:layout_height="match_parent"/> | |
510 | + <LinearLayout | |
511 | + android:orientation="vertical" | |
512 | + android:gravity="center" | |
513 | + android:layout_width="0dp" | |
514 | + android:layout_height="match_parent" | |
515 | + android:layout_weight="1"> | |
516 | + <LinearLayout | |
517 | + android:orientation="horizontal" | |
518 | + android:gravity="center_vertical" | |
519 | + android:layout_width="wrap_content" | |
520 | + android:layout_height="wrap_content"> | |
521 | + <ImageView | |
522 | + android:src="@drawable/png_icon_statistical_accuracy" | |
523 | + android:layout_width="12dp" | |
524 | + android:layout_height="13dp"/> | |
525 | + <TextView | |
526 | + android:text="答错题数" | |
527 | + android:textSize="11sp" | |
528 | + android:textColor="#333" | |
529 | + android:textStyle="bold" | |
530 | + android:layout_marginStart="5dp" | |
531 | + android:layout_width="wrap_content" | |
532 | + android:layout_height="wrap_content"/> | |
533 | + </LinearLayout> | |
534 | + <LinearLayout | |
535 | + android:orientation="horizontal" | |
536 | + android:layout_marginTop="8dp" | |
537 | + android:layout_width="wrap_content" | |
538 | + android:layout_height="wrap_content"> | |
539 | + <TextView | |
540 | + android:id="@+id/tvTotalError" | |
541 | + tools:text="88" | |
542 | + android:textSize="14sp" | |
543 | + android:textColor="#3BC3B6" | |
544 | + android:textStyle="bold" | |
545 | + android:layout_width="wrap_content" | |
546 | + android:layout_height="wrap_content"/> | |
547 | + <TextView | |
548 | + android:text="道" | |
549 | + android:textSize="9sp" | |
550 | + android:textColor="#3BC3B6" | |
551 | + android:textStyle="bold" | |
552 | + android:layout_width="wrap_content" | |
553 | + android:layout_height="wrap_content"/> | |
554 | + </LinearLayout> | |
555 | + </LinearLayout> | |
556 | + </LinearLayout> | |
557 | + | |
558 | + <TextView | |
559 | + android:text="每日作业正确率" | |
560 | + android:textSize="13sp" | |
561 | + android:textColor="#333" | |
562 | + android:textStyle="bold" | |
563 | + android:layout_gravity="center_horizontal" | |
564 | + android:layout_marginTop="16dp" | |
565 | + android:layout_width="wrap_content" | |
566 | + android:layout_height="wrap_content"/> | |
567 | + <com.github.mikephil.charting.charts.LineChart | |
568 | + android:id="@+id/lineChart" | |
569 | + android:layout_marginStart="-8dp" | |
570 | + android:layout_width="match_parent" | |
571 | + android:layout_height="220dp"/> | |
572 | + <FrameLayout | |
573 | + android:layout_marginVertical="20dp" | |
574 | + android:layout_width="match_parent" | |
575 | + android:layout_height="wrap_content"> | |
576 | + <ImageView | |
577 | + android:src="@drawable/png_hy_summary_comment" | |
578 | + android:layout_width="22dp" | |
579 | + android:layout_height="22dp"/> | |
580 | + <TextView | |
581 | + android:id="@+id/tvRating" | |
582 | + android:textSize="16sp" | |
583 | + android:textColor="#333" | |
584 | + android:lineSpacingMultiplier="1.3" | |
585 | + android:layout_marginTop="2dp" | |
586 | + android:layout_width="match_parent" | |
587 | + android:layout_height="wrap_content"/> | |
588 | + </FrameLayout> | |
589 | + </LinearLayout> | |
590 | + | |
591 | + <Space | |
592 | + android:id="@+id/splitLine" | |
593 | + android:layout_marginTop="6dp" | |
594 | + android:layout_width="match_parent" | |
595 | + android:layout_height="0dp"/> | |
596 | + | |
597 | + <LinearLayout | |
598 | + android:orientation="vertical" | |
599 | + android:background="@drawable/shape_radius_10" | |
600 | + android:backgroundTint="@color/white" | |
601 | + android:padding="16dp" | |
602 | + android:layout_marginHorizontal="16dp" | |
603 | + android:layout_marginTop="6dp" | |
604 | + android:layout_width="match_parent" | |
605 | + android:layout_height="wrap_content"> | |
606 | + <TextView | |
607 | + android:text="知识点掌握情况" | |
608 | + android:textSize="16sp" | |
609 | + android:textColor="#333333" | |
610 | + android:textStyle="bold" | |
611 | + android:background="@drawable/bg_hy_point_title" | |
612 | + android:paddingStart="28dp" | |
613 | + android:paddingEnd="4dp" | |
614 | + android:layout_gravity="center_horizontal" | |
615 | + android:layout_width="wrap_content" | |
616 | + android:layout_height="wrap_content"/> | |
617 | + | |
618 | + <LinearLayout | |
619 | + android:orientation="horizontal" | |
620 | + android:layout_width="match_parent" | |
621 | + android:layout_height="120dp" | |
622 | + android:layout_marginTop="20dp"> | |
623 | + <LinearLayout | |
624 | + android:orientation="vertical" | |
625 | + android:background="@drawable/shape_radius_10" | |
626 | + android:backgroundTint="#F4FAFF" | |
627 | + android:gravity="center_horizontal" | |
628 | + android:paddingTop="10dp" | |
629 | + android:layout_width="0dp" | |
630 | + android:layout_height="match_parent" | |
631 | + android:layout_weight="1"> | |
632 | + <ImageView | |
633 | + android:src="@drawable/png_ic_excellent" | |
634 | + android:backgroundTint="#3BC3B6" | |
635 | + android:background="@drawable/bg_circle" | |
636 | + android:padding="8dp" | |
637 | + android:layout_width="40dp" | |
638 | + android:layout_height="40dp"/> | |
639 | + <TextView | |
640 | + android:id="@+id/tvExcellent" | |
641 | + android:text="-" | |
642 | + android:textColor="#3BC3B6" | |
643 | + android:textSize="25sp" | |
644 | + android:textStyle="bold" | |
645 | + android:layout_marginTop="4dp" | |
646 | + android:layout_width="wrap_content" | |
647 | + android:layout_height="wrap_content"/> | |
648 | + <TextView | |
649 | + android:text="掌握优秀" | |
650 | + android:textSize="15sp" | |
651 | + android:textColor="#333" | |
652 | + android:textStyle="bold" | |
653 | + android:layout_width="wrap_content" | |
654 | + android:layout_height="wrap_content"/> | |
655 | + </LinearLayout> | |
656 | + <LinearLayout | |
657 | + android:orientation="vertical" | |
658 | + android:background="@drawable/shape_radius_10" | |
659 | + android:backgroundTint="#F4FAFF" | |
660 | + android:gravity="center_horizontal" | |
661 | + android:paddingTop="10dp" | |
662 | + android:layout_marginStart="14dp" | |
663 | + android:layout_width="0dp" | |
664 | + android:layout_height="match_parent" | |
665 | + android:layout_weight="1"> | |
666 | + <ImageView | |
667 | + android:src="@drawable/png_ic_good" | |
668 | + android:backgroundTint="#489AFA" | |
669 | + android:background="@drawable/bg_circle" | |
670 | + android:padding="8dp" | |
671 | + android:layout_width="40dp" | |
672 | + android:layout_height="40dp"/> | |
673 | + <TextView | |
674 | + android:id="@+id/tvGood" | |
675 | + android:text="-" | |
676 | + android:textColor="#489AFA" | |
677 | + android:textSize="25sp" | |
678 | + android:textStyle="bold" | |
679 | + android:layout_marginTop="4dp" | |
680 | + android:layout_width="wrap_content" | |
681 | + android:layout_height="wrap_content"/> | |
682 | + <TextView | |
683 | + android:text="掌握良好" | |
684 | + android:textSize="15sp" | |
685 | + android:textColor="#333" | |
686 | + android:textStyle="bold" | |
687 | + android:layout_width="wrap_content" | |
688 | + android:layout_height="wrap_content"/> | |
689 | + </LinearLayout> | |
690 | + <LinearLayout | |
691 | + android:orientation="vertical" | |
692 | + android:background="@drawable/shape_radius_10" | |
693 | + android:backgroundTint="#F4FAFF" | |
694 | + android:gravity="center_horizontal" | |
695 | + android:paddingTop="10dp" | |
696 | + android:layout_marginStart="14dp" | |
697 | + android:layout_width="0dp" | |
698 | + android:layout_height="match_parent" | |
699 | + android:layout_weight="1"> | |
700 | + <ImageView | |
701 | + android:src="@drawable/png_ic_normal" | |
702 | + android:backgroundTint="#F58725" | |
703 | + android:background="@drawable/bg_circle" | |
704 | + android:padding="8dp" | |
705 | + android:layout_width="40dp" | |
706 | + android:layout_height="40dp"/> | |
707 | + <TextView | |
708 | + android:id="@+id/tvNormal" | |
709 | + android:text="-" | |
710 | + android:textColor="#F58725" | |
711 | + android:textSize="25sp" | |
712 | + android:textStyle="bold" | |
713 | + android:layout_marginTop="4dp" | |
714 | + android:layout_width="wrap_content" | |
715 | + android:layout_height="wrap_content"/> | |
716 | + <TextView | |
717 | + android:text="掌握一般" | |
718 | + android:textSize="15sp" | |
719 | + android:textColor="#333" | |
720 | + android:textStyle="bold" | |
721 | + android:layout_width="wrap_content" | |
722 | + android:layout_height="wrap_content"/> | |
723 | + </LinearLayout> | |
724 | + <LinearLayout | |
725 | + android:orientation="vertical" | |
726 | + android:background="@drawable/shape_radius_10" | |
727 | + android:backgroundTint="#F4FAFF" | |
728 | + android:gravity="center_horizontal" | |
729 | + android:paddingTop="10dp" | |
730 | + android:layout_marginStart="14dp" | |
731 | + android:layout_width="0dp" | |
732 | + android:layout_height="match_parent" | |
733 | + android:layout_weight="1"> | |
734 | + <ImageView | |
735 | + android:src="@drawable/png_ic_weak" | |
736 | + android:backgroundTint="#EA5127" | |
737 | + android:background="@drawable/bg_circle" | |
738 | + android:padding="8dp" | |
739 | + android:layout_width="40dp" | |
740 | + android:layout_height="40dp"/> | |
741 | + <TextView | |
742 | + android:id="@+id/tvWeak" | |
743 | + android:text="-" | |
744 | + android:textColor="#EA5127" | |
745 | + android:textSize="25sp" | |
746 | + android:textStyle="bold" | |
747 | + android:layout_marginTop="4dp" | |
748 | + android:layout_width="wrap_content" | |
749 | + android:layout_height="wrap_content"/> | |
750 | + <TextView | |
751 | + android:text="掌握薄弱" | |
752 | + android:textSize="15sp" | |
753 | + android:textColor="#333" | |
754 | + android:textStyle="bold" | |
755 | + android:layout_width="wrap_content" | |
756 | + android:layout_height="wrap_content"/> | |
757 | + </LinearLayout> | |
758 | + </LinearLayout> | |
759 | + | |
760 | + <FrameLayout | |
761 | + android:layout_gravity="center_horizontal" | |
762 | + android:layout_marginTop="20dp" | |
763 | + android:layout_width="180dp" | |
764 | + android:layout_height="180dp"> | |
765 | + <com.littlejie.circleprogress.CircleProgress | |
766 | + android:id="@+id/cpBase" | |
767 | + app:value="0" | |
768 | + app:arcWidth="35dp" | |
769 | + app:bgArcWidth="35dp" | |
770 | + app:bgArcColor="#3BC3B6" | |
771 | + app:startAngle="0" | |
772 | + app:sweepAngle="360" | |
773 | + app:hintColor="@color/transparent" | |
774 | + app:unitColor="@color/transparent" | |
775 | + app:valueColor="@color/transparent" | |
776 | + android:layout_width="match_parent" | |
777 | + android:layout_height="match_parent"/> | |
778 | + <com.littlejie.circleprogress.CircleProgress | |
779 | + android:id="@+id/cpGood" | |
780 | + app:value="0" | |
781 | + app:arcWidth="35dp" | |
782 | + app:bgArcWidth="35dp" | |
783 | + app:arcColors="#489AFA" | |
784 | + app:bgArcColor="@color/transparent" | |
785 | + app:startAngle="0" | |
786 | + app:sweepAngle="360" | |
787 | + app:hintColor="@color/transparent" | |
788 | + app:unitColor="@color/transparent" | |
789 | + app:valueColor="@color/transparent" | |
790 | + android:layout_width="match_parent" | |
791 | + android:layout_height="match_parent"/> | |
792 | + <com.littlejie.circleprogress.CircleProgress | |
793 | + android:id="@+id/cpNormal" | |
794 | + app:value="0" | |
795 | + app:arcWidth="35dp" | |
796 | + app:bgArcWidth="35dp" | |
797 | + app:arcColors="#F58725" | |
798 | + app:bgArcColor="@color/transparent" | |
799 | + app:startAngle="0" | |
800 | + app:sweepAngle="360" | |
801 | + app:hintColor="@color/transparent" | |
802 | + app:unitColor="@color/transparent" | |
803 | + app:valueColor="@color/transparent" | |
804 | + android:layout_width="match_parent" | |
805 | + android:layout_height="match_parent"/> | |
806 | + <com.littlejie.circleprogress.CircleProgress | |
807 | + android:id="@+id/cpWeak" | |
808 | + app:value="0" | |
809 | + app:arcWidth="35dp" | |
810 | + app:bgArcWidth="35dp" | |
811 | + app:arcColors="#EA5127" | |
812 | + app:bgArcColor="@color/transparent" | |
813 | + app:startAngle="0" | |
814 | + app:sweepAngle="360" | |
815 | + app:hintColor="@color/transparent" | |
816 | + app:unitColor="@color/transparent" | |
817 | + app:valueColor="@color/transparent" | |
818 | + android:layout_width="match_parent" | |
819 | + android:layout_height="match_parent"/> | |
820 | + | |
821 | + <LinearLayout | |
822 | + android:orientation="vertical" | |
823 | + android:gravity="center_horizontal" | |
824 | + android:layout_gravity="center" | |
825 | + android:layout_width="wrap_content" | |
826 | + android:layout_height="wrap_content"> | |
827 | + <LinearLayout | |
828 | + android:layout_width="wrap_content" | |
829 | + android:layout_height="wrap_content"> | |
830 | + <TextView | |
831 | + android:id="@+id/tvAvePoint" | |
832 | + tools:text="88" | |
833 | + android:textSize="25sp" | |
834 | + android:textColor="#3BC3B6" | |
835 | + android:textStyle="bold" | |
836 | + android:layout_width="wrap_content" | |
837 | + android:layout_height="wrap_content"/> | |
838 | + <TextView | |
839 | + android:text="%" | |
840 | + android:textSize="12sp" | |
841 | + android:textColor="#3BC3B6" | |
842 | + android:layout_width="wrap_content" | |
843 | + android:layout_height="wrap_content"/> | |
844 | + </LinearLayout> | |
845 | + <TextView | |
846 | + android:text="综合掌握程度" | |
847 | + android:textSize="10sp" | |
848 | + android:textColor="#333" | |
849 | + android:textStyle="bold" | |
850 | + android:layout_marginTop="-2dp" | |
851 | + android:layout_width="wrap_content" | |
852 | + android:layout_height="wrap_content"/> | |
853 | + </LinearLayout> | |
854 | + </FrameLayout> | |
855 | + </LinearLayout> | |
856 | + | |
857 | + <LinearLayout | |
858 | + android:orientation="vertical" | |
859 | + android:background="@drawable/shape_radius_10" | |
860 | + android:backgroundTint="@color/white" | |
861 | + android:padding="16dp" | |
862 | + android:layout_marginHorizontal="16dp" | |
863 | + android:layout_marginTop="12dp" | |
864 | + android:layout_width="match_parent" | |
865 | + android:layout_height="wrap_content"> | |
866 | + <TextView | |
867 | + android:text="学习效果分析" | |
868 | + android:textSize="16sp" | |
869 | + android:textColor="#333333" | |
870 | + android:textStyle="bold" | |
871 | + android:background="@drawable/bg_hy_analyse_title" | |
872 | + android:paddingStart="24dp" | |
873 | + android:paddingEnd="4dp" | |
874 | + android:layout_gravity="center_horizontal" | |
875 | + android:layout_width="wrap_content" | |
876 | + android:layout_height="wrap_content"/> | |
877 | + | |
878 | + <LinearLayout | |
879 | + android:id="@+id/flEmptyPoints" | |
880 | + android:visibility="gone" | |
881 | + android:orientation="vertical" | |
882 | + android:gravity="center_horizontal" | |
883 | + android:layout_marginTop="50dp" | |
884 | + android:layout_width="match_parent" | |
885 | + android:layout_height="wrap_content"> | |
886 | + <ImageView | |
887 | + android:src="@drawable/png_huyou_points_empty" | |
888 | + android:layout_width="195dp" | |
889 | + android:layout_height="145dp"/> | |
890 | + <TextView | |
891 | + android:text="你太棒了!" | |
892 | + android:textSize="20sp" | |
893 | + android:textColor="#999" | |
894 | + android:layout_marginVertical="16dp" | |
895 | + android:layout_width="wrap_content" | |
896 | + android:layout_height="wrap_content"/> | |
897 | + </LinearLayout> | |
898 | + | |
899 | + <LinearLayout | |
900 | + android:id="@+id/tableRoot" | |
901 | + android:orientation="vertical" | |
902 | + android:background="@drawable/bg_huyou_table_bg" | |
903 | + android:layout_marginTop="16dp" | |
904 | + android:layout_width="match_parent" | |
905 | + android:layout_height="wrap_content"> | |
906 | + <LinearLayout | |
907 | + android:orientation="horizontal" | |
908 | + android:background="#50CEC2" | |
909 | + android:layout_width="match_parent" | |
910 | + android:layout_height="60dp"> | |
911 | + <TextView | |
912 | + android:text="知识点名称" | |
913 | + android:textSize="13sp" | |
914 | + android:textColor="@color/white" | |
915 | + android:gravity="center" | |
916 | + android:layout_weight="82" | |
917 | + android:layout_width="0dp" | |
918 | + android:layout_height="match_parent"/> | |
919 | + <View | |
920 | + android:background="#38B3A7" | |
921 | + android:layout_width="1dp" | |
922 | + android:layout_height="match_parent"/> | |
923 | + | |
924 | + <LinearLayout | |
925 | + android:orientation="vertical" | |
926 | + android:layout_weight="72" | |
927 | + android:layout_width="0dp" | |
928 | + android:layout_height="match_parent"> | |
929 | + <TextView | |
930 | + android:text="学前" | |
931 | + android:textSize="13sp" | |
932 | + android:textColor="@color/white" | |
933 | + android:gravity="center" | |
934 | + android:layout_width="match_parent" | |
935 | + android:layout_height="24dp"/> | |
936 | + <View | |
937 | + android:background="#38B3A7" | |
938 | + android:layout_width="match_parent" | |
939 | + android:layout_height="1dp"/> | |
940 | + <LinearLayout | |
941 | + android:orientation="horizontal" | |
942 | + android:layout_width="match_parent" | |
943 | + android:layout_height="match_parent"> | |
944 | + <TextView | |
945 | + android:text="程\n度" | |
946 | + android:textSize="13sp" | |
947 | + android:textColor="@color/white" | |
948 | + android:gravity="center" | |
949 | + android:layout_weight="1" | |
950 | + android:layout_width="0dp" | |
951 | + android:layout_height="wrap_content"/> | |
952 | + <View | |
953 | + android:background="#38B3A7" | |
954 | + android:layout_width="1dp" | |
955 | + android:layout_height="match_parent"/> | |
956 | + <TextView | |
957 | + android:text="状\n态" | |
958 | + android:textSize="13sp" | |
959 | + android:textColor="@color/white" | |
960 | + android:gravity="center" | |
961 | + android:layout_weight="1" | |
962 | + android:layout_width="0dp" | |
963 | + android:layout_height="wrap_content"/> | |
964 | + </LinearLayout> | |
965 | + </LinearLayout> | |
966 | + | |
967 | + <View | |
968 | + android:background="#38B3A7" | |
969 | + android:layout_width="1dp" | |
970 | + android:layout_height="match_parent"/> | |
971 | + | |
972 | + <LinearLayout | |
973 | + android:orientation="vertical" | |
974 | + android:layout_weight="72" | |
975 | + android:layout_width="0dp" | |
976 | + android:layout_height="match_parent"> | |
977 | + <TextView | |
978 | + android:text="学后" | |
979 | + android:textSize="13sp" | |
980 | + android:textColor="@color/white" | |
981 | + android:gravity="center" | |
982 | + android:layout_width="match_parent" | |
983 | + android:layout_height="24dp"/> | |
984 | + <View | |
985 | + android:background="#38B3A7" | |
986 | + android:layout_width="match_parent" | |
987 | + android:layout_height="1dp"/> | |
988 | + <LinearLayout | |
989 | + android:orientation="horizontal" | |
990 | + android:layout_width="match_parent" | |
991 | + android:layout_height="match_parent"> | |
992 | + <TextView | |
993 | + android:text="程\n度" | |
994 | + android:textSize="13sp" | |
995 | + android:textColor="@color/white" | |
996 | + android:gravity="center" | |
997 | + android:layout_weight="1" | |
998 | + android:layout_width="0dp" | |
999 | + android:layout_height="wrap_content"/> | |
1000 | + <View | |
1001 | + android:background="#38B3A7" | |
1002 | + android:layout_width="1dp" | |
1003 | + android:layout_height="match_parent"/> | |
1004 | + <TextView | |
1005 | + android:text="状\n态" | |
1006 | + android:textSize="13sp" | |
1007 | + android:textColor="@color/white" | |
1008 | + android:gravity="center" | |
1009 | + android:layout_weight="1" | |
1010 | + android:layout_width="0dp" | |
1011 | + android:layout_height="wrap_content"/> | |
1012 | + </LinearLayout> | |
1013 | + | |
1014 | + </LinearLayout> | |
1015 | + | |
1016 | + <View | |
1017 | + android:background="#38B3A7" | |
1018 | + android:layout_width="1dp" | |
1019 | + android:layout_height="match_parent"/> | |
1020 | + <TextView | |
1021 | + android:text="进步\n幅度" | |
1022 | + android:textSize="13sp" | |
1023 | + android:textColor="@color/white" | |
1024 | + android:gravity="center" | |
1025 | + android:layout_weight="50" | |
1026 | + android:layout_width="0dp" | |
1027 | + android:layout_height="match_parent"/> | |
1028 | + <View | |
1029 | + android:background="#38B3A7" | |
1030 | + android:layout_width="1dp" | |
1031 | + android:layout_height="match_parent"/> | |
1032 | + <TextView | |
1033 | + android:text="正答\n率" | |
1034 | + android:textSize="13sp" | |
1035 | + android:textColor="@color/white" | |
1036 | + android:gravity="center" | |
1037 | + android:layout_weight="38" | |
1038 | + android:layout_width="0dp" | |
1039 | + android:layout_height="match_parent"/> | |
1040 | + </LinearLayout> | |
1041 | + <androidx.recyclerview.widget.RecyclerView | |
1042 | + android:id="@+id/rvPoint" | |
1043 | + android:orientation="vertical" | |
1044 | + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" | |
1045 | + app:reverseLayout="false" | |
1046 | + android:layout_width="match_parent" | |
1047 | + android:layout_height="wrap_content"/> | |
1048 | + </LinearLayout> | |
1049 | + | |
1050 | + <LinearLayout | |
1051 | + android:id="@+id/flPointDesc" | |
1052 | + android:orientation="horizontal" | |
1053 | + android:gravity="center_vertical" | |
1054 | + android:layout_marginTop="10dp" | |
1055 | + android:layout_width="match_parent" | |
1056 | + android:layout_height="wrap_content"> | |
1057 | + <ImageView | |
1058 | + android:src="@drawable/png_up" | |
1059 | + android:layout_width="12dp" | |
1060 | + android:layout_height="12dp"/> | |
1061 | + <TextView | |
1062 | + android:text="代表进步幅度最大的知识点" | |
1063 | + android:textSize="12sp" | |
1064 | + android:textColor="#666" | |
1065 | + android:layout_marginStart="8dp" | |
1066 | + android:layout_width="wrap_content" | |
1067 | + android:layout_height="wrap_content"/> | |
1068 | + </LinearLayout> | |
1069 | + | |
1070 | + </LinearLayout> | |
1071 | + </LinearLayout> | |
1072 | + | |
1073 | +</androidx.core.widget.NestedScrollView> | |
1074 | +</FrameLayout> | |
0 | 1075 | \ No newline at end of file | ... | ... |
app/src/main/res/layout/activity_huyou_detail_a4.xml
... | ... | @@ -0,0 +1,1079 @@ |
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<FrameLayout | |
3 | + xmlns:android="http://schemas.android.com/apk/res/android" | |
4 | + xmlns:tools="http://schemas.android.com/tools" | |
5 | + xmlns:app="http://schemas.android.com/apk/res-auto" | |
6 | + tools:ignore="HardcodedText,ContentDescription,SmallSp,UseCompoundDrawables,RtlSymmetry" | |
7 | + android:layout_width="match_parent" | |
8 | + android:layout_height="match_parent"> | |
9 | + <LinearLayout | |
10 | + android:id="@+id/root" | |
11 | + android:transformPivotX="0px" | |
12 | + android:transformPivotY="0px" | |
13 | + android:orientation="vertical" | |
14 | + android:background="@drawable/bg_huyou_a4" | |
15 | + android:layout_width="756dp" | |
16 | + android:layout_height="1069dp" | |
17 | + tools:ignore="UselessParent"> | |
18 | + | |
19 | + | |
20 | + <FrameLayout | |
21 | + android:orientation="horizontal" | |
22 | + android:elevation="2dp" | |
23 | + android:paddingHorizontal="30dp" | |
24 | + android:layout_marginTop="60dp" | |
25 | + android:layout_width="match_parent" | |
26 | + android:layout_height="wrap_content"> | |
27 | + <FrameLayout | |
28 | + android:id="@+id/toolbar" | |
29 | + android:layout_gravity="center_vertical" | |
30 | + android:layout_width="match_parent" | |
31 | + android:layout_height="wrap_content"> | |
32 | + <TextView | |
33 | + android:id="@+id/btnSwitch" | |
34 | + android:text="看长图" | |
35 | + android:textSize="20sp" | |
36 | + android:textColor="#333" | |
37 | + android:layout_marginStart="48dp" | |
38 | + android:layout_width="wrap_content" | |
39 | + android:layout_height="wrap_content"/> | |
40 | + <TextView | |
41 | + android:id="@+id/btnShare" | |
42 | + android:text="分享" | |
43 | + android:textSize="20sp" | |
44 | + android:textColor="#333" | |
45 | + android:layout_width="wrap_content" | |
46 | + android:layout_height="wrap_content"/> | |
47 | + <TextView | |
48 | + android:id="@+id/btnSame" | |
49 | + android:visibility="gone" | |
50 | + android:text="举一反三" | |
51 | + android:textSize="20sp" | |
52 | + android:textColor="#333" | |
53 | + android:layout_gravity="end" | |
54 | + android:layout_width="wrap_content" | |
55 | + android:layout_height="wrap_content"/> | |
56 | + </FrameLayout> | |
57 | + <TextView | |
58 | + android:id="@+id/tvTitle" | |
59 | + android:text="周作业学习报告" | |
60 | + android:textSize="37sp" | |
61 | + android:textColor="#333" | |
62 | + android:textStyle="bold" | |
63 | + android:layout_gravity="center_horizontal" | |
64 | + android:layout_width="wrap_content" | |
65 | + android:layout_height="wrap_content" /> | |
66 | + </FrameLayout> | |
67 | + | |
68 | + | |
69 | + <ImageView | |
70 | + android:src="@drawable/png_huyou_top_bg" | |
71 | + android:elevation="1dp" | |
72 | + android:layout_gravity="end" | |
73 | + android:layout_marginHorizontal="30dp" | |
74 | + android:layout_marginTop="-40dp" | |
75 | + android:layout_width="206dp" | |
76 | + android:layout_height="180dp"/> | |
77 | + | |
78 | + <LinearLayout | |
79 | + android:orientation="vertical" | |
80 | + android:background="@drawable/png_info_bg" | |
81 | + android:padding="30dp" | |
82 | + android:layout_marginHorizontal="30dp" | |
83 | + android:layout_marginTop="-120dp" | |
84 | + android:layout_width="match_parent" | |
85 | + android:layout_height="267dp"> | |
86 | + <LinearLayout | |
87 | + android:orientation="horizontal" | |
88 | + android:layout_width="match_parent" | |
89 | + android:layout_height="wrap_content"> | |
90 | + <androidx.constraintlayout.utils.widget.ImageFilterView | |
91 | + android:id="@+id/ivAvatar" | |
92 | + tools:background="#2491FF" | |
93 | + app:round="40dp" | |
94 | + android:layout_width="80dp" | |
95 | + android:layout_height="80dp"/> | |
96 | + <LinearLayout | |
97 | + android:orientation="vertical" | |
98 | + android:layout_gravity="center_vertical" | |
99 | + android:layout_marginStart="10dp" | |
100 | + android:layout_width="wrap_content" | |
101 | + android:layout_height="wrap_content"> | |
102 | + <TextView | |
103 | + android:id="@+id/tvStuName" | |
104 | + tools:text="杨同学 " | |
105 | + android:textSize="28sp" | |
106 | + android:textColor="#333" | |
107 | + android:textStyle="bold" | |
108 | + android:layout_width="wrap_content" | |
109 | + android:layout_height="wrap_content"/> | |
110 | + <TextView | |
111 | + android:id="@+id/tvGrade" | |
112 | + tools:text="七年级" | |
113 | + android:textSize="26sp" | |
114 | + android:textColor="#666" | |
115 | + android:textStyle="bold" | |
116 | + android:layout_width="wrap_content" | |
117 | + android:layout_height="wrap_content"/> | |
118 | + </LinearLayout> | |
119 | + </LinearLayout> | |
120 | + <LinearLayout | |
121 | + android:orientation="horizontal" | |
122 | + android:background="@drawable/shape_radius_10" | |
123 | + android:backgroundTint="#F4FAFF" | |
124 | + android:layout_marginTop="16dp" | |
125 | + android:layout_width="match_parent" | |
126 | + android:layout_height="120dp"> | |
127 | + <LinearLayout | |
128 | + android:orientation="vertical" | |
129 | + android:gravity="center" | |
130 | + android:layout_width="0dp" | |
131 | + android:layout_height="match_parent" | |
132 | + android:layout_weight="1"> | |
133 | + <LinearLayout | |
134 | + android:paddingEnd="40dp" | |
135 | + android:gravity="center_vertical" | |
136 | + android:layout_width="wrap_content" | |
137 | + android:layout_height="wrap_content"> | |
138 | + <ImageView | |
139 | + android:src="@drawable/png_iv_subject" | |
140 | + android:layout_marginEnd="10dp" | |
141 | + android:layout_width="32dp" | |
142 | + android:layout_height="28dp"/> | |
143 | + <TextView | |
144 | + android:text="学科" | |
145 | + android:textSize="24sp" | |
146 | + android:textColor="#333" | |
147 | + android:textStyle="bold" | |
148 | + android:layout_width="wrap_content" | |
149 | + android:layout_height="wrap_content"/> | |
150 | + </LinearLayout> | |
151 | + <TextView | |
152 | + android:id="@+id/tvSubject" | |
153 | + tools:text="数学" | |
154 | + android:textSize="24sp" | |
155 | + android:textColor="#3BC3B6" | |
156 | + android:textStyle="bold" | |
157 | + android:layout_marginTop="8dp" | |
158 | + android:layout_width="wrap_content" | |
159 | + android:layout_height="wrap_content"/> | |
160 | + </LinearLayout> | |
161 | + <LinearLayout | |
162 | + android:orientation="vertical" | |
163 | + android:gravity="center" | |
164 | + android:layout_width="0dp" | |
165 | + android:layout_height="match_parent" | |
166 | + android:layout_weight="1"> | |
167 | + <LinearLayout | |
168 | + android:paddingEnd="40dp" | |
169 | + android:gravity="center_vertical" | |
170 | + android:layout_width="wrap_content" | |
171 | + android:layout_height="wrap_content"> | |
172 | + <ImageView | |
173 | + android:src="@drawable/png_ic_during" | |
174 | + android:layout_marginEnd="10dp" | |
175 | + android:layout_width="14dp" | |
176 | + android:layout_height="13dp"/> | |
177 | + <TextView | |
178 | + android:text="周期" | |
179 | + android:textSize="24sp" | |
180 | + android:textColor="#333" | |
181 | + android:textStyle="bold" | |
182 | + android:layout_width="wrap_content" | |
183 | + android:layout_height="wrap_content"/> | |
184 | + </LinearLayout> | |
185 | + <TextView | |
186 | + android:id="@+id/tvDate" | |
187 | + tools:text="2024.09.01-2024.09.30" | |
188 | + android:textSize="24sp" | |
189 | + android:textColor="#3BC3B6" | |
190 | + android:textStyle="bold" | |
191 | + android:layout_marginTop="8dp" | |
192 | + android:layout_width="wrap_content" | |
193 | + android:layout_height="wrap_content"/> | |
194 | + </LinearLayout> | |
195 | + </LinearLayout> | |
196 | + </LinearLayout> | |
197 | + <Space | |
198 | + android:id="@+id/splitLine" | |
199 | + android:layout_width="match_parent" | |
200 | + android:layout_height="0dp"/> | |
201 | + | |
202 | + <HorizontalScrollView | |
203 | + android:scrollbars="none" | |
204 | + android:layout_marginTop="25dp" | |
205 | + android:layout_marginHorizontal="16dp" | |
206 | + android:layout_width="match_parent" | |
207 | + android:layout_height="match_parent"> | |
208 | + <LinearLayout | |
209 | + android:orientation="horizontal" | |
210 | + android:layout_width="wrap_content" | |
211 | + android:layout_height="match_parent"> | |
212 | + <LinearLayout | |
213 | + android:orientation="vertical" | |
214 | + android:background="@drawable/shape_radius_10" | |
215 | + android:backgroundTint="@color/white" | |
216 | + android:padding="12dp" | |
217 | + android:layout_marginHorizontal="14dp" | |
218 | + android:layout_width="335dp" | |
219 | + android:layout_height="613dp"> | |
220 | + <TextView | |
221 | + android:text="薄弱知识点总评" | |
222 | + android:textSize="16sp" | |
223 | + android:textColor="#333333" | |
224 | + android:textStyle="bold" | |
225 | + android:background="@drawable/bg_hy_weak_title" | |
226 | + android:paddingStart="20dp" | |
227 | + android:paddingEnd="4dp" | |
228 | + android:layout_marginTop="8dp" | |
229 | + android:layout_gravity="center_horizontal" | |
230 | + android:layout_width="wrap_content" | |
231 | + android:layout_height="wrap_content"/> | |
232 | + <LinearLayout | |
233 | + android:orientation="vertical" | |
234 | + android:layout_marginTop="40dp" | |
235 | + android:layout_width="match_parent" | |
236 | + android:layout_height="wrap_content"> | |
237 | + <TextView | |
238 | + android:text="学习前" | |
239 | + android:textSize="12sp" | |
240 | + android:textColor="#333" | |
241 | + android:layout_gravity="center_horizontal" | |
242 | + android:layout_width="wrap_content" | |
243 | + android:layout_height="wrap_content"/> | |
244 | + <FrameLayout | |
245 | + android:background="@drawable/png_huyou_progress_bg" | |
246 | + android:padding="10dp" | |
247 | + android:layout_gravity="center_horizontal" | |
248 | + android:layout_marginTop="16dp" | |
249 | + android:layout_width="172dp" | |
250 | + android:layout_height="172dp"> | |
251 | + <com.littlejie.circleprogress.CircleProgress | |
252 | + android:id="@+id/cpBefore" | |
253 | + app:arcWidth="20dp" | |
254 | + app:bgArcWidth="20dp" | |
255 | + app:arcColors="#F36A27" | |
256 | + app:bgArcColor="#FFF1EA" | |
257 | + app:startAngle="-90" | |
258 | + app:sweepAngle="360" | |
259 | + app:maxValue="100" | |
260 | + app:value="0" | |
261 | + app:hintColor="@color/transparent" | |
262 | + app:unitColor="@color/transparent" | |
263 | + app:valueColor="@color/transparent" | |
264 | + android:layout_width="match_parent" | |
265 | + android:layout_height="match_parent"/> | |
266 | + <LinearLayout | |
267 | + android:orientation="vertical" | |
268 | + android:gravity="center_horizontal" | |
269 | + android:layout_gravity="center" | |
270 | + android:layout_width="wrap_content" | |
271 | + android:layout_height="wrap_content"> | |
272 | + <LinearLayout | |
273 | + android:layout_width="wrap_content" | |
274 | + android:layout_height="wrap_content"> | |
275 | + <TextView | |
276 | + android:id="@+id/pgBefore" | |
277 | + tools:text="88" | |
278 | + android:textSize="34sp" | |
279 | + android:textColor="#EA5127" | |
280 | + android:textStyle="bold" | |
281 | + android:layout_width="wrap_content" | |
282 | + android:layout_height="wrap_content"/> | |
283 | + <TextView | |
284 | + android:text="%" | |
285 | + android:textSize="16sp" | |
286 | + android:textColor="#EA5127" | |
287 | + android:layout_width="wrap_content" | |
288 | + android:layout_height="wrap_content"/> | |
289 | + </LinearLayout> | |
290 | + <TextView | |
291 | + android:text="整体掌握程度" | |
292 | + android:textSize="14sp" | |
293 | + android:textColor="#333" | |
294 | + android:textStyle="bold" | |
295 | + android:layout_marginTop="-2dp" | |
296 | + android:layout_width="wrap_content" | |
297 | + android:layout_height="wrap_content"/> | |
298 | + </LinearLayout> | |
299 | + </FrameLayout> | |
300 | + </LinearLayout> | |
301 | + <LinearLayout | |
302 | + android:orientation="vertical" | |
303 | + android:layout_marginTop="20dp" | |
304 | + android:layout_width="match_parent" | |
305 | + android:layout_height="wrap_content"> | |
306 | + <TextView | |
307 | + android:text="学习后" | |
308 | + android:textSize="12sp" | |
309 | + android:textColor="#333" | |
310 | + android:layout_gravity="center_horizontal" | |
311 | + android:layout_width="wrap_content" | |
312 | + android:layout_height="wrap_content"/> | |
313 | + <FrameLayout | |
314 | + android:background="@drawable/png_huyou_progress_bg" | |
315 | + android:padding="10dp" | |
316 | + android:layout_gravity="center_horizontal" | |
317 | + android:layout_marginTop="16dp" | |
318 | + android:layout_width="172dp" | |
319 | + android:layout_height="172dp"> | |
320 | + <com.littlejie.circleprogress.CircleProgress | |
321 | + android:id="@+id/cpAfter" | |
322 | + app:arcWidth="20dp" | |
323 | + app:bgArcWidth="20dp" | |
324 | + app:arcColors="#3BC3B6" | |
325 | + app:bgArcColor="#C2FCF6" | |
326 | + app:startAngle="-90" | |
327 | + app:sweepAngle="360" | |
328 | + app:maxValue="100" | |
329 | + app:value="0" | |
330 | + app:hintColor="@color/transparent" | |
331 | + app:unitColor="@color/transparent" | |
332 | + app:valueColor="@color/transparent" | |
333 | + android:layout_width="match_parent" | |
334 | + android:layout_height="match_parent"/> | |
335 | + <LinearLayout | |
336 | + android:orientation="vertical" | |
337 | + android:gravity="center_horizontal" | |
338 | + android:layout_gravity="center" | |
339 | + android:layout_width="wrap_content" | |
340 | + android:layout_height="wrap_content"> | |
341 | + <LinearLayout | |
342 | + android:layout_width="wrap_content" | |
343 | + android:layout_height="wrap_content"> | |
344 | + <TextView | |
345 | + android:id="@+id/pgAfter" | |
346 | + tools:text="88" | |
347 | + android:textSize="34sp" | |
348 | + android:textColor="#3BC3B6" | |
349 | + android:textStyle="bold" | |
350 | + android:layout_width="wrap_content" | |
351 | + android:layout_height="wrap_content"/> | |
352 | + <TextView | |
353 | + android:text="%" | |
354 | + android:textSize="16sp" | |
355 | + android:textColor="#3BC3B6" | |
356 | + android:layout_width="wrap_content" | |
357 | + android:layout_height="wrap_content"/> | |
358 | + </LinearLayout> | |
359 | + <TextView | |
360 | + android:text="整体掌握程度" | |
361 | + android:textSize="14sp" | |
362 | + android:textColor="#333" | |
363 | + android:textStyle="bold" | |
364 | + android:layout_marginTop="-2dp" | |
365 | + android:layout_width="wrap_content" | |
366 | + android:layout_height="wrap_content"/> | |
367 | + </LinearLayout> | |
368 | + </FrameLayout> | |
369 | + </LinearLayout> | |
370 | + | |
371 | + <FrameLayout | |
372 | + android:layout_marginTop="10dp" | |
373 | + android:layout_width="match_parent" | |
374 | + android:layout_height="wrap_content"> | |
375 | + <ImageView | |
376 | + android:src="@drawable/png_hy_weak_comment" | |
377 | + android:layout_width="16dp" | |
378 | + android:layout_height="18dp"/> | |
379 | + <TextView | |
380 | + android:id="@+id/tvWeakRate" | |
381 | + android:textSize="14sp" | |
382 | + android:textColor="#333" | |
383 | + android:layout_marginTop="1dp" | |
384 | + android:lineSpacingMultiplier="1.3" | |
385 | + android:layout_width="wrap_content" | |
386 | + android:layout_height="wrap_content"/> | |
387 | + </FrameLayout> | |
388 | + </LinearLayout> | |
389 | + | |
390 | + <LinearLayout | |
391 | + android:orientation="vertical" | |
392 | + android:background="@drawable/shape_radius_10" | |
393 | + android:backgroundTint="@color/white" | |
394 | + android:padding="12dp" | |
395 | + android:layout_marginHorizontal="14dp" | |
396 | + android:layout_width="335dp" | |
397 | + android:layout_height="613dp"> | |
398 | + | |
399 | + <TextView | |
400 | + android:text="作业概括" | |
401 | + android:textSize="16sp" | |
402 | + android:textColor="#333333" | |
403 | + android:textStyle="bold" | |
404 | + android:background="@drawable/bg_hy_summary_title" | |
405 | + android:paddingStart="28dp" | |
406 | + android:paddingEnd="4dp" | |
407 | + android:layout_marginTop="8dp" | |
408 | + android:layout_gravity="center_horizontal" | |
409 | + android:layout_width="wrap_content" | |
410 | + android:layout_height="wrap_content"/> | |
411 | + <LinearLayout | |
412 | + android:orientation="horizontal" | |
413 | + android:background="@drawable/shape_radius_5" | |
414 | + android:backgroundTint="#F4FAFF" | |
415 | + android:layout_width="match_parent" | |
416 | + android:layout_height="58dp" | |
417 | + android:layout_marginTop="40dp"> | |
418 | + <LinearLayout | |
419 | + android:orientation="vertical" | |
420 | + android:gravity="center" | |
421 | + android:layout_width="0dp" | |
422 | + android:layout_height="match_parent" | |
423 | + android:layout_weight="1"> | |
424 | + <LinearLayout | |
425 | + android:orientation="horizontal" | |
426 | + android:gravity="center_vertical" | |
427 | + android:layout_width="wrap_content" | |
428 | + android:layout_height="wrap_content"> | |
429 | + <ImageView | |
430 | + android:src="@drawable/png_icon_statistical_accuracy" | |
431 | + android:layout_width="12dp" | |
432 | + android:layout_height="13dp"/> | |
433 | + <TextView | |
434 | + android:text="作业正确率" | |
435 | + android:textSize="11sp" | |
436 | + android:textColor="#333" | |
437 | + android:textStyle="bold" | |
438 | + android:layout_marginStart="5dp" | |
439 | + android:layout_width="wrap_content" | |
440 | + android:layout_height="wrap_content"/> | |
441 | + </LinearLayout> | |
442 | + <LinearLayout | |
443 | + android:orientation="horizontal" | |
444 | + android:layout_marginTop="8dp" | |
445 | + android:layout_width="wrap_content" | |
446 | + android:layout_height="wrap_content"> | |
447 | + <TextView | |
448 | + android:id="@+id/tvTotalRate" | |
449 | + tools:text="88" | |
450 | + android:textSize="14sp" | |
451 | + android:textColor="#3BC3B6" | |
452 | + android:textStyle="bold" | |
453 | + android:layout_width="wrap_content" | |
454 | + android:layout_height="wrap_content"/> | |
455 | + <TextView | |
456 | + android:text="%" | |
457 | + android:textSize="9sp" | |
458 | + android:textColor="#3BC3B6" | |
459 | + android:textStyle="bold" | |
460 | + android:layout_width="wrap_content" | |
461 | + android:layout_height="wrap_content"/> | |
462 | + </LinearLayout> | |
463 | + </LinearLayout> | |
464 | + <View | |
465 | + android:background="#9ECAFC" | |
466 | + android:layout_marginVertical="8dp" | |
467 | + android:layout_width="1dp" | |
468 | + android:layout_height="match_parent"/> | |
469 | + <LinearLayout | |
470 | + android:orientation="vertical" | |
471 | + android:gravity="center" | |
472 | + android:layout_width="0dp" | |
473 | + android:layout_height="match_parent" | |
474 | + android:layout_weight="1"> | |
475 | + <LinearLayout | |
476 | + android:orientation="horizontal" | |
477 | + android:gravity="center_vertical" | |
478 | + android:layout_width="wrap_content" | |
479 | + android:layout_height="wrap_content"> | |
480 | + <ImageView | |
481 | + android:src="@drawable/png_icon_statistical_accuracy" | |
482 | + android:layout_width="12dp" | |
483 | + android:layout_height="13dp"/> | |
484 | + <TextView | |
485 | + android:text="答对题数" | |
486 | + android:textSize="11sp" | |
487 | + android:textColor="#333" | |
488 | + android:textStyle="bold" | |
489 | + android:layout_marginStart="5dp" | |
490 | + android:layout_width="wrap_content" | |
491 | + android:layout_height="wrap_content"/> | |
492 | + </LinearLayout> | |
493 | + <LinearLayout | |
494 | + android:orientation="horizontal" | |
495 | + android:layout_marginTop="8dp" | |
496 | + android:layout_width="wrap_content" | |
497 | + android:layout_height="wrap_content"> | |
498 | + <TextView | |
499 | + android:id="@+id/tvTotalCorrect" | |
500 | + tools:text="88" | |
501 | + android:textSize="14sp" | |
502 | + android:textColor="#3BC3B6" | |
503 | + android:textStyle="bold" | |
504 | + android:layout_width="wrap_content" | |
505 | + android:layout_height="wrap_content"/> | |
506 | + <TextView | |
507 | + android:text="道" | |
508 | + android:textSize="9sp" | |
509 | + android:textColor="#3BC3B6" | |
510 | + android:textStyle="bold" | |
511 | + android:layout_width="wrap_content" | |
512 | + android:layout_height="wrap_content"/> | |
513 | + </LinearLayout> | |
514 | + </LinearLayout> | |
515 | + <View | |
516 | + android:background="#9ECAFC" | |
517 | + android:layout_marginVertical="8dp" | |
518 | + android:layout_width="1dp" | |
519 | + android:layout_height="match_parent"/> | |
520 | + <LinearLayout | |
521 | + android:orientation="vertical" | |
522 | + android:gravity="center" | |
523 | + android:layout_width="0dp" | |
524 | + android:layout_height="match_parent" | |
525 | + android:layout_weight="1"> | |
526 | + <LinearLayout | |
527 | + android:orientation="horizontal" | |
528 | + android:gravity="center_vertical" | |
529 | + android:layout_width="wrap_content" | |
530 | + android:layout_height="wrap_content"> | |
531 | + <ImageView | |
532 | + android:src="@drawable/png_icon_statistical_accuracy" | |
533 | + android:layout_width="12dp" | |
534 | + android:layout_height="13dp"/> | |
535 | + <TextView | |
536 | + android:text="答错题数" | |
537 | + android:textSize="11sp" | |
538 | + android:textColor="#333" | |
539 | + android:textStyle="bold" | |
540 | + android:layout_marginStart="5dp" | |
541 | + android:layout_width="wrap_content" | |
542 | + android:layout_height="wrap_content"/> | |
543 | + </LinearLayout> | |
544 | + <LinearLayout | |
545 | + android:orientation="horizontal" | |
546 | + android:layout_marginTop="8dp" | |
547 | + android:layout_width="wrap_content" | |
548 | + android:layout_height="wrap_content"> | |
549 | + <TextView | |
550 | + android:id="@+id/tvTotalError" | |
551 | + tools:text="88" | |
552 | + android:textSize="14sp" | |
553 | + android:textColor="#3BC3B6" | |
554 | + android:textStyle="bold" | |
555 | + android:layout_width="wrap_content" | |
556 | + android:layout_height="wrap_content"/> | |
557 | + <TextView | |
558 | + android:text="道" | |
559 | + android:textSize="9sp" | |
560 | + android:textColor="#3BC3B6" | |
561 | + android:textStyle="bold" | |
562 | + android:layout_width="wrap_content" | |
563 | + android:layout_height="wrap_content"/> | |
564 | + </LinearLayout> | |
565 | + </LinearLayout> | |
566 | + </LinearLayout> | |
567 | + | |
568 | + <TextView | |
569 | + android:text="每日作业正确率" | |
570 | + android:textSize="13sp" | |
571 | + android:textColor="#333" | |
572 | + android:textStyle="bold" | |
573 | + android:layout_gravity="center_horizontal" | |
574 | + android:layout_marginTop="68dp" | |
575 | + android:layout_width="wrap_content" | |
576 | + android:layout_height="wrap_content"/> | |
577 | + <com.github.mikephil.charting.charts.LineChart | |
578 | + android:id="@+id/lineChart" | |
579 | + android:layout_width="match_parent" | |
580 | + android:layout_height="220dp"/> | |
581 | + <Space style="@style/empty_space"/> | |
582 | + <FrameLayout | |
583 | + android:layout_width="match_parent" | |
584 | + android:layout_height="wrap_content"> | |
585 | + <ImageView | |
586 | + android:src="@drawable/png_hy_summary_comment" | |
587 | + android:layout_width="16dp" | |
588 | + android:layout_height="20dp"/> | |
589 | + <TextView | |
590 | + android:id="@+id/tvRating" | |
591 | + android:textSize="14sp" | |
592 | + android:textColor="#333" | |
593 | + android:lineSpacingMultiplier="1.3" | |
594 | + android:layout_marginTop="2dp" | |
595 | + android:layout_width="match_parent" | |
596 | + android:layout_height="wrap_content"/> | |
597 | + </FrameLayout> | |
598 | + </LinearLayout> | |
599 | + | |
600 | + <LinearLayout | |
601 | + android:orientation="vertical" | |
602 | + android:background="@drawable/shape_radius_10" | |
603 | + android:backgroundTint="@color/white" | |
604 | + android:padding="12dp" | |
605 | + android:layout_marginHorizontal="14dp" | |
606 | + android:layout_width="335dp" | |
607 | + android:layout_height="472dp"> | |
608 | + <TextView | |
609 | + android:text="知识点掌握情况" | |
610 | + android:textSize="16sp" | |
611 | + android:textColor="#333333" | |
612 | + android:textStyle="bold" | |
613 | + android:background="@drawable/bg_hy_point_title" | |
614 | + android:paddingStart="28dp" | |
615 | + android:paddingEnd="4dp" | |
616 | + android:layout_marginTop="8dp" | |
617 | + android:layout_gravity="center_horizontal" | |
618 | + android:layout_width="wrap_content" | |
619 | + android:layout_height="wrap_content"/> | |
620 | + | |
621 | + <LinearLayout | |
622 | + android:orientation="horizontal" | |
623 | + android:layout_width="match_parent" | |
624 | + android:layout_height="70dp" | |
625 | + android:layout_marginTop="48dp"> | |
626 | + <LinearLayout | |
627 | + android:orientation="vertical" | |
628 | + android:background="@drawable/shape_radius_10" | |
629 | + android:backgroundTint="#F4FAFF" | |
630 | + android:gravity="center_horizontal" | |
631 | + android:paddingTop="8dp" | |
632 | + android:layout_width="0dp" | |
633 | + android:layout_height="match_parent" | |
634 | + android:layout_weight="1"> | |
635 | + <ImageView | |
636 | + android:src="@drawable/png_ic_excellent" | |
637 | + android:backgroundTint="#3BC3B6" | |
638 | + android:background="@drawable/bg_circle" | |
639 | + android:padding="4dp" | |
640 | + android:layout_width="20dp" | |
641 | + android:layout_height="20dp"/> | |
642 | + <TextView | |
643 | + android:id="@+id/tvExcellent" | |
644 | + android:text="-" | |
645 | + android:textColor="#3BC3B6" | |
646 | + android:textSize="13sp" | |
647 | + android:textStyle="bold" | |
648 | + android:layout_marginTop="4dp" | |
649 | + android:layout_width="wrap_content" | |
650 | + android:layout_height="wrap_content"/> | |
651 | + <TextView | |
652 | + android:text="掌握优秀" | |
653 | + android:textSize="10sp" | |
654 | + android:textColor="#333" | |
655 | + android:textStyle="bold" | |
656 | + android:layout_width="wrap_content" | |
657 | + android:layout_height="wrap_content"/> | |
658 | + </LinearLayout> | |
659 | + <LinearLayout | |
660 | + android:orientation="vertical" | |
661 | + android:background="@drawable/shape_radius_10" | |
662 | + android:backgroundTint="#F4FAFF" | |
663 | + android:gravity="center_horizontal" | |
664 | + android:paddingTop="8dp" | |
665 | + android:layout_marginStart="14dp" | |
666 | + android:layout_width="0dp" | |
667 | + android:layout_height="match_parent" | |
668 | + android:layout_weight="1"> | |
669 | + <ImageView | |
670 | + android:src="@drawable/png_ic_good" | |
671 | + android:backgroundTint="#489AFA" | |
672 | + android:background="@drawable/bg_circle" | |
673 | + android:padding="4dp" | |
674 | + android:layout_width="20dp" | |
675 | + android:layout_height="20dp"/> | |
676 | + <TextView | |
677 | + android:id="@+id/tvGood" | |
678 | + android:text="-" | |
679 | + android:textColor="#489AFA" | |
680 | + android:textSize="13sp" | |
681 | + android:textStyle="bold" | |
682 | + android:layout_marginTop="4dp" | |
683 | + android:layout_width="wrap_content" | |
684 | + android:layout_height="wrap_content"/> | |
685 | + <TextView | |
686 | + android:text="掌握良好" | |
687 | + android:textSize="10sp" | |
688 | + android:textColor="#333" | |
689 | + android:textStyle="bold" | |
690 | + android:layout_width="wrap_content" | |
691 | + android:layout_height="wrap_content"/> | |
692 | + </LinearLayout> | |
693 | + <LinearLayout | |
694 | + android:orientation="vertical" | |
695 | + android:background="@drawable/shape_radius_10" | |
696 | + android:backgroundTint="#F4FAFF" | |
697 | + android:gravity="center_horizontal" | |
698 | + android:paddingTop="8dp" | |
699 | + android:layout_marginStart="14dp" | |
700 | + android:layout_width="0dp" | |
701 | + android:layout_height="match_parent" | |
702 | + android:layout_weight="1"> | |
703 | + <ImageView | |
704 | + android:src="@drawable/png_ic_normal" | |
705 | + android:backgroundTint="#F58725" | |
706 | + android:background="@drawable/bg_circle" | |
707 | + android:padding="4dp" | |
708 | + android:layout_width="20dp" | |
709 | + android:layout_height="20dp"/> | |
710 | + <TextView | |
711 | + android:id="@+id/tvNormal" | |
712 | + android:text="-" | |
713 | + android:textColor="#F58725" | |
714 | + android:textSize="13sp" | |
715 | + android:textStyle="bold" | |
716 | + android:layout_marginTop="4dp" | |
717 | + android:layout_width="wrap_content" | |
718 | + android:layout_height="wrap_content"/> | |
719 | + <TextView | |
720 | + android:text="掌握一般" | |
721 | + android:textSize="10sp" | |
722 | + android:textColor="#333" | |
723 | + android:textStyle="bold" | |
724 | + android:layout_width="wrap_content" | |
725 | + android:layout_height="wrap_content"/> | |
726 | + </LinearLayout> | |
727 | + <LinearLayout | |
728 | + android:orientation="vertical" | |
729 | + android:background="@drawable/shape_radius_10" | |
730 | + android:backgroundTint="#F4FAFF" | |
731 | + android:gravity="center_horizontal" | |
732 | + android:paddingTop="8dp" | |
733 | + android:layout_marginStart="14dp" | |
734 | + android:layout_width="0dp" | |
735 | + android:layout_height="match_parent" | |
736 | + android:layout_weight="1"> | |
737 | + <ImageView | |
738 | + android:src="@drawable/png_ic_weak" | |
739 | + android:backgroundTint="#EA5127" | |
740 | + android:background="@drawable/bg_circle" | |
741 | + android:padding="4dp" | |
742 | + android:layout_width="20dp" | |
743 | + android:layout_height="20dp"/> | |
744 | + <TextView | |
745 | + android:id="@+id/tvWeak" | |
746 | + android:text="-" | |
747 | + android:textColor="#EA5127" | |
748 | + android:textSize="13sp" | |
749 | + android:textStyle="bold" | |
750 | + android:layout_marginTop="4dp" | |
751 | + android:layout_width="wrap_content" | |
752 | + android:layout_height="wrap_content"/> | |
753 | + <TextView | |
754 | + android:text="掌握薄弱" | |
755 | + android:textSize="10sp" | |
756 | + android:textColor="#333" | |
757 | + android:textStyle="bold" | |
758 | + android:layout_width="wrap_content" | |
759 | + android:layout_height="wrap_content"/> | |
760 | + </LinearLayout> | |
761 | + </LinearLayout> | |
762 | + | |
763 | + <FrameLayout | |
764 | + android:layout_gravity="center_horizontal" | |
765 | + android:layout_marginTop="36dp" | |
766 | + android:layout_width="238dp" | |
767 | + android:layout_height="238dp"> | |
768 | + <com.littlejie.circleprogress.CircleProgress | |
769 | + android:id="@+id/cpBase" | |
770 | + app:value="0" | |
771 | + app:arcWidth="48dp" | |
772 | + app:bgArcWidth="48dp" | |
773 | + app:bgArcColor="#3BC3B6" | |
774 | + app:startAngle="0" | |
775 | + app:sweepAngle="360" | |
776 | + app:hintColor="@color/transparent" | |
777 | + app:unitColor="@color/transparent" | |
778 | + app:valueColor="@color/transparent" | |
779 | + android:layout_width="match_parent" | |
780 | + android:layout_height="match_parent"/> | |
781 | + <com.littlejie.circleprogress.CircleProgress | |
782 | + android:id="@+id/cpGood" | |
783 | + app:value="0" | |
784 | + app:arcWidth="48dp" | |
785 | + app:bgArcWidth="48dp" | |
786 | + app:arcColors="#489AFA" | |
787 | + app:bgArcColor="@color/transparent" | |
788 | + app:startAngle="0" | |
789 | + app:sweepAngle="360" | |
790 | + app:hintColor="@color/transparent" | |
791 | + app:unitColor="@color/transparent" | |
792 | + app:valueColor="@color/transparent" | |
793 | + android:layout_width="match_parent" | |
794 | + android:layout_height="match_parent"/> | |
795 | + <com.littlejie.circleprogress.CircleProgress | |
796 | + android:id="@+id/cpNormal" | |
797 | + app:value="0" | |
798 | + app:arcWidth="48dp" | |
799 | + app:bgArcWidth="48dp" | |
800 | + app:arcColors="#F58725" | |
801 | + app:bgArcColor="@color/transparent" | |
802 | + app:startAngle="0" | |
803 | + app:sweepAngle="360" | |
804 | + app:hintColor="@color/transparent" | |
805 | + app:unitColor="@color/transparent" | |
806 | + app:valueColor="@color/transparent" | |
807 | + android:layout_width="match_parent" | |
808 | + android:layout_height="match_parent"/> | |
809 | + <com.littlejie.circleprogress.CircleProgress | |
810 | + android:id="@+id/cpWeak" | |
811 | + app:value="0" | |
812 | + app:arcWidth="48dp" | |
813 | + app:bgArcWidth="48dp" | |
814 | + app:arcColors="#EA5127" | |
815 | + app:bgArcColor="@color/transparent" | |
816 | + app:startAngle="0" | |
817 | + app:sweepAngle="360" | |
818 | + app:hintColor="@color/transparent" | |
819 | + app:unitColor="@color/transparent" | |
820 | + app:valueColor="@color/transparent" | |
821 | + android:layout_width="match_parent" | |
822 | + android:layout_height="match_parent"/> | |
823 | + | |
824 | + <LinearLayout | |
825 | + android:orientation="vertical" | |
826 | + android:gravity="center_horizontal" | |
827 | + android:layout_gravity="center" | |
828 | + android:layout_width="wrap_content" | |
829 | + android:layout_height="wrap_content"> | |
830 | + <LinearLayout | |
831 | + android:layout_width="wrap_content" | |
832 | + android:layout_height="wrap_content"> | |
833 | + <TextView | |
834 | + android:id="@+id/tvAvePoint" | |
835 | + tools:text="88" | |
836 | + android:textSize="34sp" | |
837 | + android:textColor="#3BC3B6" | |
838 | + android:textStyle="bold" | |
839 | + android:layout_width="wrap_content" | |
840 | + android:layout_height="wrap_content"/> | |
841 | + <TextView | |
842 | + android:text="%" | |
843 | + android:textSize="16sp" | |
844 | + android:textColor="#3BC3B6" | |
845 | + android:layout_width="wrap_content" | |
846 | + android:layout_height="wrap_content"/> | |
847 | + </LinearLayout> | |
848 | + <TextView | |
849 | + android:text="综合掌握程度" | |
850 | + android:textSize="16sp" | |
851 | + android:textColor="#333" | |
852 | + android:textStyle="bold" | |
853 | + android:layout_marginTop="-2dp" | |
854 | + android:layout_width="wrap_content" | |
855 | + android:layout_height="wrap_content"/> | |
856 | + </LinearLayout> | |
857 | + </FrameLayout> | |
858 | + </LinearLayout> | |
859 | + | |
860 | + <LinearLayout | |
861 | + android:orientation="vertical" | |
862 | + android:background="@drawable/shape_radius_10" | |
863 | + android:backgroundTint="@color/white" | |
864 | + android:padding="16dp" | |
865 | + android:layout_marginHorizontal="14dp" | |
866 | + android:layout_width="335dp" | |
867 | + android:layout_height="472dp"> | |
868 | + <TextView | |
869 | + android:text="学习效果分析" | |
870 | + android:textSize="16sp" | |
871 | + android:textColor="#333333" | |
872 | + android:textStyle="bold" | |
873 | + android:background="@drawable/bg_hy_analyse_title" | |
874 | + android:paddingStart="24dp" | |
875 | + android:paddingEnd="4dp" | |
876 | + android:layout_marginTop="4dp" | |
877 | + android:layout_gravity="center_horizontal" | |
878 | + android:layout_width="wrap_content" | |
879 | + android:layout_height="wrap_content"/> | |
880 | + | |
881 | + <LinearLayout | |
882 | + android:id="@+id/flEmptyPoints" | |
883 | + android:visibility="gone" | |
884 | + android:orientation="vertical" | |
885 | + android:gravity="center_horizontal" | |
886 | + android:layout_marginTop="80dp" | |
887 | + android:layout_width="match_parent" | |
888 | + android:layout_height="wrap_content"> | |
889 | + <ImageView | |
890 | + android:src="@drawable/png_huyou_points_empty" | |
891 | + android:layout_width="195dp" | |
892 | + android:layout_height="145dp"/> | |
893 | + <TextView | |
894 | + android:text="你太棒了!" | |
895 | + android:textSize="20sp" | |
896 | + android:textColor="#999" | |
897 | + android:layout_marginVertical="16dp" | |
898 | + android:layout_width="wrap_content" | |
899 | + android:layout_height="wrap_content"/> | |
900 | + </LinearLayout> | |
901 | + | |
902 | + | |
903 | + <LinearLayout | |
904 | + android:id="@+id/tableRoot" | |
905 | + android:orientation="vertical" | |
906 | + android:background="@drawable/bg_huyou_table_bg" | |
907 | + android:layout_marginTop="16dp" | |
908 | + android:layout_width="match_parent" | |
909 | + android:layout_height="wrap_content"> | |
910 | + <LinearLayout | |
911 | + android:orientation="horizontal" | |
912 | + android:background="#50CEC2" | |
913 | + android:layout_width="match_parent" | |
914 | + android:layout_height="60dp"> | |
915 | + <TextView | |
916 | + android:text="知识点名称" | |
917 | + android:textSize="13sp" | |
918 | + android:textColor="@color/white" | |
919 | + android:gravity="center" | |
920 | + android:layout_weight="82" | |
921 | + android:layout_width="0dp" | |
922 | + android:layout_height="match_parent"/> | |
923 | + <View | |
924 | + android:background="#38B3A7" | |
925 | + android:layout_width="1dp" | |
926 | + android:layout_height="match_parent"/> | |
927 | + | |
928 | + <LinearLayout | |
929 | + android:orientation="vertical" | |
930 | + android:layout_weight="72" | |
931 | + android:layout_width="0dp" | |
932 | + android:layout_height="match_parent"> | |
933 | + <TextView | |
934 | + android:text="学前" | |
935 | + android:textSize="13sp" | |
936 | + android:textColor="@color/white" | |
937 | + android:gravity="center" | |
938 | + android:layout_width="match_parent" | |
939 | + android:layout_height="24dp"/> | |
940 | + <View | |
941 | + android:background="#38B3A7" | |
942 | + android:layout_width="match_parent" | |
943 | + android:layout_height="1dp"/> | |
944 | + <LinearLayout | |
945 | + android:orientation="horizontal" | |
946 | + android:layout_width="match_parent" | |
947 | + android:layout_height="match_parent"> | |
948 | + <TextView | |
949 | + android:text="程\n度" | |
950 | + android:textSize="13sp" | |
951 | + android:textColor="@color/white" | |
952 | + android:gravity="center" | |
953 | + android:layout_weight="1" | |
954 | + android:layout_width="0dp" | |
955 | + android:layout_height="wrap_content"/> | |
956 | + <View | |
957 | + android:background="#38B3A7" | |
958 | + android:layout_width="1dp" | |
959 | + android:layout_height="match_parent"/> | |
960 | + <TextView | |
961 | + android:text="状\n态" | |
962 | + android:textSize="13sp" | |
963 | + android:textColor="@color/white" | |
964 | + android:gravity="center" | |
965 | + android:layout_weight="1" | |
966 | + android:layout_width="0dp" | |
967 | + android:layout_height="wrap_content"/> | |
968 | + </LinearLayout> | |
969 | + </LinearLayout> | |
970 | + | |
971 | + <View | |
972 | + android:background="#38B3A7" | |
973 | + android:layout_width="1dp" | |
974 | + android:layout_height="match_parent"/> | |
975 | + | |
976 | + <LinearLayout | |
977 | + android:orientation="vertical" | |
978 | + android:layout_weight="72" | |
979 | + android:layout_width="0dp" | |
980 | + android:layout_height="match_parent"> | |
981 | + <TextView | |
982 | + android:text="学后" | |
983 | + android:textSize="13sp" | |
984 | + android:textColor="@color/white" | |
985 | + android:gravity="center" | |
986 | + android:layout_width="match_parent" | |
987 | + android:layout_height="24dp"/> | |
988 | + <View | |
989 | + android:background="#38B3A7" | |
990 | + android:layout_width="match_parent" | |
991 | + android:layout_height="1dp"/> | |
992 | + <LinearLayout | |
993 | + android:orientation="horizontal" | |
994 | + android:layout_width="match_parent" | |
995 | + android:layout_height="match_parent"> | |
996 | + <TextView | |
997 | + android:text="程\n度" | |
998 | + android:textSize="13sp" | |
999 | + android:textColor="@color/white" | |
1000 | + android:gravity="center" | |
1001 | + android:layout_weight="1" | |
1002 | + android:layout_width="0dp" | |
1003 | + android:layout_height="wrap_content"/> | |
1004 | + <View | |
1005 | + android:background="#38B3A7" | |
1006 | + android:layout_width="1dp" | |
1007 | + android:layout_height="match_parent"/> | |
1008 | + <TextView | |
1009 | + android:text="状\n态" | |
1010 | + android:textSize="13sp" | |
1011 | + android:textColor="@color/white" | |
1012 | + android:gravity="center" | |
1013 | + android:layout_weight="1" | |
1014 | + android:layout_width="0dp" | |
1015 | + android:layout_height="wrap_content"/> | |
1016 | + </LinearLayout> | |
1017 | + | |
1018 | + </LinearLayout> | |
1019 | + | |
1020 | + <View | |
1021 | + android:background="#38B3A7" | |
1022 | + android:layout_width="1dp" | |
1023 | + android:layout_height="match_parent"/> | |
1024 | + <TextView | |
1025 | + android:text="进步\n幅度" | |
1026 | + android:textSize="13sp" | |
1027 | + android:textColor="@color/white" | |
1028 | + android:gravity="center" | |
1029 | + android:layout_weight="50" | |
1030 | + android:layout_width="0dp" | |
1031 | + android:layout_height="match_parent"/> | |
1032 | + <View | |
1033 | + android:background="#38B3A7" | |
1034 | + android:layout_width="1dp" | |
1035 | + android:layout_height="match_parent"/> | |
1036 | + <TextView | |
1037 | + android:text="正答\n率" | |
1038 | + android:textSize="13sp" | |
1039 | + android:textColor="@color/white" | |
1040 | + android:gravity="center" | |
1041 | + android:layout_weight="38" | |
1042 | + android:layout_width="0dp" | |
1043 | + android:layout_height="match_parent"/> | |
1044 | + </LinearLayout> | |
1045 | + <androidx.recyclerview.widget.RecyclerView | |
1046 | + android:id="@+id/rvPoint" | |
1047 | + android:orientation="vertical" | |
1048 | + app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" | |
1049 | + app:reverseLayout="false" | |
1050 | + android:layout_width="match_parent" | |
1051 | + android:layout_height="wrap_content"/> | |
1052 | + </LinearLayout> | |
1053 | + | |
1054 | + <LinearLayout | |
1055 | + android:id="@+id/flPointDesc" | |
1056 | + android:alpha="0" | |
1057 | + android:orientation="horizontal" | |
1058 | + android:gravity="center_vertical" | |
1059 | + android:layout_marginTop="10dp" | |
1060 | + android:layout_width="match_parent" | |
1061 | + android:layout_height="wrap_content"> | |
1062 | + <ImageView | |
1063 | + android:src="@drawable/png_up" | |
1064 | + android:layout_width="12dp" | |
1065 | + android:layout_height="12dp"/> | |
1066 | + <TextView | |
1067 | + android:text="代表进步幅度最大的知识点" | |
1068 | + android:textSize="12sp" | |
1069 | + android:textColor="#666" | |
1070 | + android:layout_marginStart="8dp" | |
1071 | + android:layout_width="wrap_content" | |
1072 | + android:layout_height="wrap_content"/> | |
1073 | + </LinearLayout> | |
1074 | + </LinearLayout> | |
1075 | + </LinearLayout> | |
1076 | + </HorizontalScrollView> | |
1077 | + | |
1078 | + </LinearLayout> | |
1079 | +</FrameLayout> | |
0 | 1080 | \ No newline at end of file | ... | ... |
app/src/main/res/layout/item_huyou_point.xml
... | ... | @@ -0,0 +1,136 @@ |
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
3 | + xmlns:tools="http://schemas.android.com/tools" | |
4 | + android:orientation="vertical" | |
5 | + android:layout_width="match_parent" | |
6 | + android:layout_height="36dp" | |
7 | + tools:ignore="SmallSp,RtlSymmetry,HardcodedText"> | |
8 | + <View | |
9 | + android:background="#38B3A7" | |
10 | + android:layout_width="match_parent" | |
11 | + android:layout_height="1dp"/> | |
12 | + | |
13 | + <LinearLayout | |
14 | + android:orientation="horizontal" | |
15 | + android:layout_width="match_parent" | |
16 | + android:layout_height="match_parent"> | |
17 | + <TextView | |
18 | + android:id="@+id/tvName" | |
19 | + tools:text="正数与负数" | |
20 | + android:textSize="12sp" | |
21 | + android:textColor="#333" | |
22 | + android:gravity="center_vertical" | |
23 | + android:singleLine="true" | |
24 | + android:paddingStart="6dp" | |
25 | + android:layout_weight="82" | |
26 | + android:layout_width="0dp" | |
27 | + android:layout_height="match_parent"/> | |
28 | + <View | |
29 | + android:background="#38B3A7" | |
30 | + android:layout_width="1dp" | |
31 | + android:layout_height="match_parent"/> | |
32 | + <LinearLayout | |
33 | + android:orientation="horizontal" | |
34 | + android:gravity="center_vertical" | |
35 | + android:paddingStart="4dp" | |
36 | + android:layout_weight="72" | |
37 | + android:layout_width="0dp" | |
38 | + android:layout_height="match_parent"> | |
39 | + <TextView | |
40 | + android:id="@+id/tvBefore" | |
41 | + tools:text="33%" | |
42 | + android:textSize="12sp" | |
43 | + android:textColor="#333" | |
44 | + android:layout_width="wrap_content" | |
45 | + android:layout_height="wrap_content"/> | |
46 | + <Space style="@style/empty_space"/> | |
47 | + <TextView | |
48 | + android:id="@+id/tvBeforeState" | |
49 | + tools:text="掌握薄弱" | |
50 | + android:textSize="8sp" | |
51 | + android:textColor="@color/white" | |
52 | + android:background="@drawable/shape_radius_2" | |
53 | + android:backgroundTint="#EA5127" | |
54 | + android:paddingHorizontal="2dp" | |
55 | + android:singleLine="true" | |
56 | + android:layout_width="wrap_content" | |
57 | + android:layout_height="wrap_content"/> | |
58 | + </LinearLayout> | |
59 | + <View | |
60 | + android:background="#38B3A7" | |
61 | + android:layout_width="1dp" | |
62 | + android:layout_height="match_parent"/> | |
63 | + <LinearLayout | |
64 | + android:orientation="horizontal" | |
65 | + android:gravity="center_vertical" | |
66 | + android:paddingStart="4dp" | |
67 | + android:layout_weight="72" | |
68 | + android:layout_width="0dp" | |
69 | + android:layout_height="match_parent"> | |
70 | + <TextView | |
71 | + android:id="@+id/tvAfter" | |
72 | + tools:text="33%" | |
73 | + android:textSize="12sp" | |
74 | + android:textColor="#333" | |
75 | + android:layout_width="wrap_content" | |
76 | + android:layout_height="wrap_content"/> | |
77 | + <Space style="@style/empty_space"/> | |
78 | + <TextView | |
79 | + android:id="@+id/tvAfterState" | |
80 | + tools:text="掌握薄弱" | |
81 | + android:textSize="8sp" | |
82 | + android:textColor="@color/white" | |
83 | + android:background="@drawable/shape_radius_2" | |
84 | + android:backgroundTint="#EA5127" | |
85 | + android:paddingHorizontal="2dp" | |
86 | + android:singleLine="true" | |
87 | + android:layout_width="wrap_content" | |
88 | + android:layout_height="wrap_content" /> | |
89 | + </LinearLayout> | |
90 | + <View | |
91 | + android:background="#38B3A7" | |
92 | + android:layout_width="1dp" | |
93 | + android:layout_height="match_parent"/> | |
94 | + <LinearLayout | |
95 | + android:orientation="horizontal" | |
96 | + android:gravity="center_vertical" | |
97 | + android:paddingStart="6dp" | |
98 | + android:layout_weight="50" | |
99 | + android:layout_width="0dp" | |
100 | + android:layout_height="match_parent"> | |
101 | + <TextView | |
102 | + android:id="@+id/tvGap" | |
103 | + tools:text="33" | |
104 | + android:textSize="15sp" | |
105 | + android:textColor="#333" | |
106 | + android:textStyle="bold" | |
107 | + android:layout_width="wrap_content" | |
108 | + android:layout_height="wrap_content"/> | |
109 | + <TextView | |
110 | + android:text="%" | |
111 | + android:textSize="9sp" | |
112 | + android:textColor="#333" | |
113 | + android:layout_marginTop="2dp" | |
114 | + android:layout_width="wrap_content" | |
115 | + android:layout_height="wrap_content"/> | |
116 | + <ImageView | |
117 | + android:id="@+id/ivFlag" | |
118 | + android:src="@drawable/png_up" | |
119 | + android:layout_width="10dp" | |
120 | + android:layout_height="10dp"/> | |
121 | + </LinearLayout> | |
122 | + <View | |
123 | + android:background="#38B3A7" | |
124 | + android:layout_width="1dp" | |
125 | + android:layout_height="match_parent"/> | |
126 | + <TextView | |
127 | + android:id="@+id/tvHuyou" | |
128 | + android:text="-" | |
129 | + android:textSize="12sp" | |
130 | + android:textColor="#333" | |
131 | + android:gravity="center" | |
132 | + android:layout_weight="38" | |
133 | + android:layout_width="0dp" | |
134 | + android:layout_height="match_parent"/> | |
135 | + </LinearLayout> | |
136 | +</LinearLayout> | |
0 | 137 | \ No newline at end of file | ... | ... |
build.gradle
libs/common/src/main/java/com/littlejie/circleprogress/CircleProgress.java
... | ... | @@ -0,0 +1,409 @@ |
1 | +package com.littlejie.circleprogress; | |
2 | + | |
3 | +import android.animation.ValueAnimator; | |
4 | +import android.content.Context; | |
5 | +import android.content.res.TypedArray; | |
6 | +import android.graphics.Canvas; | |
7 | +import android.graphics.Color; | |
8 | +import android.graphics.Paint; | |
9 | +import android.graphics.Point; | |
10 | +import android.graphics.RectF; | |
11 | +import android.graphics.SweepGradient; | |
12 | +import android.graphics.Typeface; | |
13 | +import android.text.TextPaint; | |
14 | +import android.util.AttributeSet; | |
15 | +import android.util.Log; | |
16 | +import android.view.View; | |
17 | + | |
18 | +import androidx.annotation.Nullable; | |
19 | + | |
20 | +import com.littlejie.circleprogress.utils.Constant; | |
21 | +import com.littlejie.circleprogress.utils.MiscUtil; | |
22 | +import com.prws.common.R; | |
23 | + | |
24 | +/** | |
25 | + * 圆形进度条,类似 QQ 健康中运动步数的 UI 控件 | |
26 | + * Created by littlejie on 2017/2/21. | |
27 | + */ | |
28 | + | |
29 | +public class CircleProgress extends View { | |
30 | + | |
31 | + private static final String TAG = CircleProgress.class.getSimpleName(); | |
32 | + private Context mContext; | |
33 | + | |
34 | + //默认大小 | |
35 | + private int mDefaultSize; | |
36 | + //是否开启抗锯齿 | |
37 | + private boolean antiAlias; | |
38 | + //绘制提示 | |
39 | + private TextPaint mHintPaint; | |
40 | + private CharSequence mHint; | |
41 | + private int mHintColor; | |
42 | + private float mHintSize; | |
43 | + private float mHintOffset; | |
44 | + | |
45 | + //绘制单位 | |
46 | + private TextPaint mUnitPaint; | |
47 | + private CharSequence mUnit; | |
48 | + private int mUnitColor; | |
49 | + private float mUnitSize; | |
50 | + private float mUnitOffset; | |
51 | + | |
52 | + //绘制数值 | |
53 | + private TextPaint mValuePaint; | |
54 | + private float mValue; | |
55 | + private float mMaxValue; | |
56 | + private float mValueOffset; | |
57 | + private int mPrecision; | |
58 | + private String mPrecisionFormat; | |
59 | + private int mValueColor; | |
60 | + private float mValueSize; | |
61 | + | |
62 | + //绘制圆弧 | |
63 | + private Paint mArcPaint; | |
64 | + private float mArcWidth; | |
65 | + private float mStartAngle, mSweepAngle; | |
66 | + private RectF mRectF; | |
67 | + //渐变的颜色是360度,如果只显示270,那么则会缺失部分颜色 | |
68 | + private SweepGradient mSweepGradient; | |
69 | + private int[] mGradientColors = {Color.GREEN, Color.YELLOW, Color.RED}; | |
70 | + //当前进度,[0.0f,1.0f] | |
71 | + private float mPercent; | |
72 | + //动画时间 | |
73 | + private long mAnimTime; | |
74 | + //属性动画 | |
75 | + private ValueAnimator mAnimator; | |
76 | + | |
77 | + //绘制背景圆弧 | |
78 | + private Paint mBgArcPaint; | |
79 | + private int mBgArcColor; | |
80 | + private float mBgArcWidth; | |
81 | + | |
82 | + //圆心坐标,半径 | |
83 | + private Point mCenterPoint; | |
84 | + private float mRadius; | |
85 | + private float mTextOffsetPercentInRadius; | |
86 | + | |
87 | + public CircleProgress(Context context, @Nullable AttributeSet attrs) { | |
88 | + super(context, attrs); | |
89 | + init(context, attrs); | |
90 | + } | |
91 | + | |
92 | + public CircleProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { | |
93 | + super(context, attrs, defStyleAttr); | |
94 | + init(context, attrs); | |
95 | + } | |
96 | + | |
97 | + public CircleProgress(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { | |
98 | + super(context, attrs, defStyleAttr, defStyleRes); | |
99 | + init(context, attrs); | |
100 | + } | |
101 | + | |
102 | + private void init(Context context, AttributeSet attrs) { | |
103 | + mContext = context; | |
104 | + mDefaultSize = MiscUtil.dipToPx(mContext, Constant.DEFAULT_SIZE); | |
105 | + mAnimator = new ValueAnimator(); | |
106 | + mRectF = new RectF(); | |
107 | + mCenterPoint = new Point(); | |
108 | + initAttrs(attrs); | |
109 | + initPaint(); | |
110 | + setValue(mValue); | |
111 | + } | |
112 | + | |
113 | + private void initAttrs(AttributeSet attrs) { | |
114 | + TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.CircleProgressBar); | |
115 | + | |
116 | + antiAlias = typedArray.getBoolean(R.styleable.CircleProgressBar_antiAlias, Constant.ANTI_ALIAS); | |
117 | + | |
118 | + mHint = typedArray.getString(R.styleable.CircleProgressBar_hint); | |
119 | + mHintColor = typedArray.getColor(R.styleable.CircleProgressBar_hintColor, Color.BLACK); | |
120 | + mHintSize = typedArray.getDimension(R.styleable.CircleProgressBar_hintSize, Constant.DEFAULT_HINT_SIZE); | |
121 | + | |
122 | + mValue = typedArray.getFloat(R.styleable.CircleProgressBar_value, Constant.DEFAULT_VALUE); | |
123 | + mMaxValue = typedArray.getFloat(R.styleable.CircleProgressBar_maxValue, Constant.DEFAULT_MAX_VALUE); | |
124 | + //内容数值精度格式 | |
125 | + mPrecision = typedArray.getInt(R.styleable.CircleProgressBar_precision, 0); | |
126 | + mPrecisionFormat = MiscUtil.getPrecisionFormat(mPrecision); | |
127 | + mValueColor = typedArray.getColor(R.styleable.CircleProgressBar_valueColor, Color.BLACK); | |
128 | + mValueSize = typedArray.getDimension(R.styleable.CircleProgressBar_valueSize, Constant.DEFAULT_VALUE_SIZE); | |
129 | + | |
130 | + mUnit = typedArray.getString(R.styleable.CircleProgressBar_unit); | |
131 | + mUnitColor = typedArray.getColor(R.styleable.CircleProgressBar_unitColor, Color.BLACK); | |
132 | + mUnitSize = typedArray.getDimension(R.styleable.CircleProgressBar_unitSize, Constant.DEFAULT_UNIT_SIZE); | |
133 | + | |
134 | + mArcWidth = typedArray.getDimension(R.styleable.CircleProgressBar_arcWidth, Constant.DEFAULT_ARC_WIDTH); | |
135 | + mStartAngle = typedArray.getFloat(R.styleable.CircleProgressBar_startAngle, Constant.DEFAULT_START_ANGLE); | |
136 | + mSweepAngle = typedArray.getFloat(R.styleable.CircleProgressBar_sweepAngle, Constant.DEFAULT_SWEEP_ANGLE); | |
137 | + | |
138 | + mBgArcColor = typedArray.getColor(R.styleable.CircleProgressBar_bgArcColor, Color.WHITE); | |
139 | + mBgArcWidth = typedArray.getDimension(R.styleable.CircleProgressBar_bgArcWidth, Constant.DEFAULT_ARC_WIDTH); | |
140 | + mTextOffsetPercentInRadius = typedArray.getFloat(R.styleable.CircleProgressBar_textOffsetPercentInRadius, 0.33f); | |
141 | + | |
142 | + //mPercent = typedArray.getFloat(R.styleable.CircleProgressBar_percent, 0); | |
143 | + mAnimTime = typedArray.getInt(R.styleable.CircleProgressBar_animTime, Constant.DEFAULT_ANIM_TIME); | |
144 | + | |
145 | + int arcColor = typedArray.getColor(R.styleable.CircleProgressBar_arcColors, Color.WHITE); | |
146 | + mGradientColors = new int[2]; | |
147 | + mGradientColors[0] = arcColor; | |
148 | + mGradientColors[1] = arcColor; | |
149 | + | |
150 | + typedArray.recycle(); | |
151 | + } | |
152 | + | |
153 | + private void initPaint() { | |
154 | + mHintPaint = new TextPaint(); | |
155 | + // 设置抗锯齿,会消耗较大资源,绘制图形速度会变慢。 | |
156 | + mHintPaint.setAntiAlias(antiAlias); | |
157 | + // 设置绘制文字大小 | |
158 | + mHintPaint.setTextSize(mHintSize); | |
159 | + // 设置画笔颜色 | |
160 | + mHintPaint.setColor(mHintColor); | |
161 | + // 从中间向两边绘制,不需要再次计算文字 | |
162 | + mHintPaint.setTextAlign(Paint.Align.CENTER); | |
163 | + | |
164 | + mValuePaint = new TextPaint(); | |
165 | + mValuePaint.setAntiAlias(antiAlias); | |
166 | + mValuePaint.setTextSize(mValueSize); | |
167 | + mValuePaint.setColor(mValueColor); | |
168 | + // 设置Typeface对象,即字体风格,包括粗体,斜体以及衬线体,非衬线体等 | |
169 | + mValuePaint.setTypeface(Typeface.DEFAULT_BOLD); | |
170 | + mValuePaint.setTextAlign(Paint.Align.CENTER); | |
171 | + | |
172 | + mUnitPaint = new TextPaint(); | |
173 | + mUnitPaint.setAntiAlias(antiAlias); | |
174 | + mUnitPaint.setTextSize(mUnitSize); | |
175 | + mUnitPaint.setColor(mUnitColor); | |
176 | + mUnitPaint.setTextAlign(Paint.Align.CENTER); | |
177 | + | |
178 | + mArcPaint = new Paint(); | |
179 | + mArcPaint.setAntiAlias(antiAlias); | |
180 | + // 设置画笔的样式,为FILL,FILL_OR_STROKE,或STROKE | |
181 | + mArcPaint.setStyle(Paint.Style.STROKE); | |
182 | + // 设置画笔粗细 | |
183 | + mArcPaint.setStrokeWidth(mArcWidth); | |
184 | + // 当画笔样式为STROKE或FILL_OR_STROKE时,设置笔刷的图形样式,如圆形样式 | |
185 | + // Cap.ROUND,或方形样式 Cap.SQUARE | |
186 | + mArcPaint.setStrokeCap(Paint.Cap.ROUND); | |
187 | + | |
188 | + mBgArcPaint = new Paint(); | |
189 | + mBgArcPaint.setAntiAlias(antiAlias); | |
190 | + mBgArcPaint.setColor(mBgArcColor); | |
191 | + mBgArcPaint.setStyle(Paint.Style.STROKE); | |
192 | + mBgArcPaint.setStrokeWidth(mBgArcWidth); | |
193 | + mBgArcPaint.setStrokeCap(Paint.Cap.ROUND); | |
194 | + } | |
195 | + | |
196 | + @Override | |
197 | + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
198 | + super.onMeasure(widthMeasureSpec, heightMeasureSpec); | |
199 | + setMeasuredDimension(MiscUtil.measure(widthMeasureSpec, mDefaultSize), | |
200 | + MiscUtil.measure(heightMeasureSpec, mDefaultSize)); | |
201 | + } | |
202 | + | |
203 | + @Override | |
204 | + protected void onSizeChanged(int w, int h, int oldw, int oldh) { | |
205 | + super.onSizeChanged(w, h, oldw, oldh); | |
206 | + Log.d(TAG, "onSizeChanged: w = " + w + "; h = " + h + "; oldw = " + oldw + "; oldh = " + oldh); | |
207 | + //求圆弧和背景圆弧的最大宽度 | |
208 | + float maxArcWidth = Math.max(mArcWidth, mBgArcWidth); | |
209 | + //求最小值作为实际值 | |
210 | + int minSize = Math.min(w - getPaddingLeft() - getPaddingRight() - 2 * (int) maxArcWidth, | |
211 | + h - getPaddingTop() - getPaddingBottom() - 2 * (int) maxArcWidth); | |
212 | + //减去圆弧的宽度,否则会造成部分圆弧绘制在外围 | |
213 | + mRadius = minSize / 2; | |
214 | + //获取圆的相关参数 | |
215 | + mCenterPoint.x = w / 2; | |
216 | + mCenterPoint.y = h / 2; | |
217 | + //绘制圆弧的边界 | |
218 | + mRectF.left = mCenterPoint.x - mRadius - maxArcWidth / 2; | |
219 | + mRectF.top = mCenterPoint.y - mRadius - maxArcWidth / 2; | |
220 | + mRectF.right = mCenterPoint.x + mRadius + maxArcWidth / 2; | |
221 | + mRectF.bottom = mCenterPoint.y + mRadius + maxArcWidth / 2; | |
222 | + //计算文字绘制时的 baseline | |
223 | + //由于文字的baseline、descent、ascent等属性只与textSize和typeface有关,所以此时可以直接计算 | |
224 | + //若value、hint、unit由同一个画笔绘制或者需要动态设置文字的大小,则需要在每次更新后再次计算 | |
225 | + mValueOffset = mCenterPoint.y + getBaselineOffsetFromY(mValuePaint); | |
226 | + mHintOffset = mCenterPoint.y - mRadius * mTextOffsetPercentInRadius + getBaselineOffsetFromY(mHintPaint); | |
227 | + mUnitOffset = mCenterPoint.y + mRadius * mTextOffsetPercentInRadius + getBaselineOffsetFromY(mUnitPaint); | |
228 | + updateArcPaint(); | |
229 | + Log.d(TAG, "onSizeChanged: 控件大小 = " + "(" + w + ", " + h + ")" | |
230 | + + "圆心坐标 = " + mCenterPoint.toString() | |
231 | + + ";圆半径 = " + mRadius | |
232 | + + ";圆的外接矩形 = " + mRectF.toString()); | |
233 | + } | |
234 | + | |
235 | + private float getBaselineOffsetFromY(Paint paint) { | |
236 | + return MiscUtil.measureTextHeight(paint) / 2; | |
237 | + } | |
238 | + | |
239 | + @Override | |
240 | + protected void onDraw(Canvas canvas) { | |
241 | + super.onDraw(canvas); | |
242 | + drawText(canvas); | |
243 | + drawArc(canvas); | |
244 | + } | |
245 | + | |
246 | + /** | |
247 | + * 绘制内容文字 | |
248 | + * | |
249 | + * @param canvas | |
250 | + */ | |
251 | + private void drawText(Canvas canvas) { | |
252 | + // 计算文字宽度,由于Paint已设置为居中绘制,故此处不需要重新计算 | |
253 | + // float textWidth = mValuePaint.measureText(mValue.toString()); | |
254 | + // float x = mCenterPoint.x - textWidth / 2; | |
255 | + canvas.drawText(String.format(mPrecisionFormat, mValue), mCenterPoint.x, mValueOffset, mValuePaint); | |
256 | + | |
257 | + if (mHint != null) { | |
258 | + canvas.drawText(mHint.toString(), mCenterPoint.x, mHintOffset, mHintPaint); | |
259 | + } | |
260 | + | |
261 | + if (mUnit != null) { | |
262 | + canvas.drawText(mUnit.toString(), mCenterPoint.x, mUnitOffset, mUnitPaint); | |
263 | + } | |
264 | + } | |
265 | + | |
266 | + private void drawArc(Canvas canvas) { | |
267 | + // 绘制背景圆弧 | |
268 | + // 从进度圆弧结束的地方开始重新绘制,优化性能 | |
269 | + canvas.save(); | |
270 | + float currentAngle = mSweepAngle * mPercent; | |
271 | + canvas.rotate(mStartAngle, mCenterPoint.x, mCenterPoint.y); | |
272 | + canvas.drawArc(mRectF, currentAngle, mSweepAngle - currentAngle + 2, false, mBgArcPaint); | |
273 | + // 第一个参数 oval 为 RectF 类型,即圆弧显示区域 | |
274 | + // startAngle 和 sweepAngle 均为 float 类型,分别表示圆弧起始角度和圆弧度数 | |
275 | + // 3点钟方向为0度,顺时针递增 | |
276 | + // 如果 startAngle < 0 或者 > 360,则相当于 startAngle % 360 | |
277 | + // useCenter:如果为True时,在绘制圆弧时将圆心包括在内,通常用来绘制扇形 | |
278 | + canvas.drawArc(mRectF, 2, currentAngle, false, mArcPaint); | |
279 | + canvas.restore(); | |
280 | + } | |
281 | + | |
282 | + /** | |
283 | + * 更新圆弧画笔 | |
284 | + */ | |
285 | + private void updateArcPaint() { | |
286 | + // 设置渐变 | |
287 | + mSweepGradient = new SweepGradient(mCenterPoint.x, mCenterPoint.y, mGradientColors, null); | |
288 | + mArcPaint.setShader(mSweepGradient); | |
289 | + } | |
290 | + | |
291 | + public boolean isAntiAlias() { | |
292 | + return antiAlias; | |
293 | + } | |
294 | + | |
295 | + public CharSequence getHint() { | |
296 | + return mHint; | |
297 | + } | |
298 | + | |
299 | + public void setHint(CharSequence hint) { | |
300 | + mHint = hint; | |
301 | + } | |
302 | + | |
303 | + public CharSequence getUnit() { | |
304 | + return mUnit; | |
305 | + } | |
306 | + | |
307 | + public void setUnit(CharSequence unit) { | |
308 | + mUnit = unit; | |
309 | + } | |
310 | + | |
311 | + public float getValue() { | |
312 | + return mValue; | |
313 | + } | |
314 | + | |
315 | + /** | |
316 | + * 设置当前值 | |
317 | + * | |
318 | + * @param value | |
319 | + */ | |
320 | + public void setValue(float value) { | |
321 | + if (value > mMaxValue) { | |
322 | + value = mMaxValue; | |
323 | + } | |
324 | + float start = mPercent; | |
325 | + float end = value / mMaxValue; | |
326 | + startAnimator(start, end, mAnimTime); | |
327 | + } | |
328 | + | |
329 | + private void startAnimator(float start, float end, long animTime) { | |
330 | + mAnimator = ValueAnimator.ofFloat(start, end); | |
331 | + mAnimator.setDuration(animTime); | |
332 | + mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { | |
333 | + @Override | |
334 | + public void onAnimationUpdate(ValueAnimator animation) { | |
335 | + mPercent = (float) animation.getAnimatedValue(); | |
336 | + mValue = mPercent * mMaxValue; | |
337 | + invalidate(); | |
338 | + } | |
339 | + }); | |
340 | + mAnimator.start(); | |
341 | + } | |
342 | + | |
343 | + /** | |
344 | + * 获取最大值 | |
345 | + * | |
346 | + * @return | |
347 | + */ | |
348 | + public float getMaxValue() { | |
349 | + return mMaxValue; | |
350 | + } | |
351 | + | |
352 | + /** | |
353 | + * 设置最大值 | |
354 | + * | |
355 | + * @param maxValue | |
356 | + */ | |
357 | + public void setMaxValue(float maxValue) { | |
358 | + mMaxValue = maxValue; | |
359 | + } | |
360 | + | |
361 | + /** | |
362 | + * 获取精度 | |
363 | + * | |
364 | + * @return | |
365 | + */ | |
366 | + public int getPrecision() { | |
367 | + return mPrecision; | |
368 | + } | |
369 | + | |
370 | + public void setPrecision(int precision) { | |
371 | + mPrecision = precision; | |
372 | + mPrecisionFormat = MiscUtil.getPrecisionFormat(precision); | |
373 | + } | |
374 | + | |
375 | + public int[] getGradientColors() { | |
376 | + return mGradientColors; | |
377 | + } | |
378 | + | |
379 | + /** | |
380 | + * 设置渐变 | |
381 | + * | |
382 | + * @param gradientColors | |
383 | + */ | |
384 | + public void setGradientColors(int[] gradientColors) { | |
385 | + mGradientColors = gradientColors; | |
386 | + updateArcPaint(); | |
387 | + } | |
388 | + | |
389 | + public long getAnimTime() { | |
390 | + return mAnimTime; | |
391 | + } | |
392 | + | |
393 | + public void setAnimTime(long animTime) { | |
394 | + mAnimTime = animTime; | |
395 | + } | |
396 | + | |
397 | + /** | |
398 | + * 重置 | |
399 | + */ | |
400 | + public void reset() { | |
401 | + startAnimator(mPercent, 0.0f, 1000L); | |
402 | + } | |
403 | + | |
404 | + @Override | |
405 | + protected void onDetachedFromWindow() { | |
406 | + super.onDetachedFromWindow(); | |
407 | + //释放资源 | |
408 | + } | |
409 | +} | ... | ... |
libs/common/src/main/java/com/littlejie/circleprogress/DialProgress.java
... | ... | @@ -0,0 +1,343 @@ |
1 | +package com.littlejie.circleprogress; | |
2 | + | |
3 | +import android.animation.ValueAnimator; | |
4 | +import android.content.Context; | |
5 | +import android.content.res.Resources; | |
6 | +import android.content.res.TypedArray; | |
7 | +import android.graphics.Canvas; | |
8 | +import android.graphics.Color; | |
9 | +import android.graphics.Paint; | |
10 | +import android.graphics.Point; | |
11 | +import android.graphics.RectF; | |
12 | +import android.graphics.SweepGradient; | |
13 | +import android.graphics.Typeface; | |
14 | +import android.text.TextPaint; | |
15 | +import android.util.AttributeSet; | |
16 | +import android.util.Log; | |
17 | +import android.view.View; | |
18 | + | |
19 | +import com.prws.common.R; | |
20 | +import com.littlejie.circleprogress.utils.Constant; | |
21 | +import com.littlejie.circleprogress.utils.MiscUtil; | |
22 | + | |
23 | +/** | |
24 | + * 带有刻度的圆形进度条 | |
25 | + * Created by littlejie on 2017/2/26. | |
26 | + */ | |
27 | + | |
28 | +public class DialProgress extends View { | |
29 | + | |
30 | + private static final String TAG = DialProgress.class.getSimpleName(); | |
31 | + private Context mContext; | |
32 | + | |
33 | + //圆心坐标 | |
34 | + private Point mCenterPoint; | |
35 | + private float mRadius; | |
36 | + private float mTextOffsetPercentInRadius; | |
37 | + | |
38 | + private boolean antiAlias; | |
39 | + //绘制提示 | |
40 | + private TextPaint mHintPaint; | |
41 | + private CharSequence mHint; | |
42 | + private int mHintColor; | |
43 | + private float mHintSize; | |
44 | + private float mHintOffset; | |
45 | + | |
46 | + //绘制数值 | |
47 | + private Paint mValuePaint; | |
48 | + private int mValueColor; | |
49 | + private float mMaxValue; | |
50 | + private float mValue; | |
51 | + private float mValueSize; | |
52 | + private float mValueOffset; | |
53 | + private String mPrecisionFormat; | |
54 | + | |
55 | + //绘制单位 | |
56 | + private Paint mUnitPaint; | |
57 | + private float mUnitSize; | |
58 | + private int mUnitColor; | |
59 | + private float mUnitOffset; | |
60 | + private CharSequence mUnit; | |
61 | + //前景圆弧 | |
62 | + private Paint mArcPaint; | |
63 | + private float mArcWidth; | |
64 | + private int mDialIntervalDegree; | |
65 | + private float mStartAngle, mSweepAngle; | |
66 | + private RectF mRectF; | |
67 | + //渐变 | |
68 | + private int[] mGradientColors = {Color.GREEN, Color.YELLOW, Color.RED}; | |
69 | + //当前进度,[0.0f,1.0f] | |
70 | + private float mPercent; | |
71 | + //动画时间 | |
72 | + private long mAnimTime; | |
73 | + //属性动画 | |
74 | + private ValueAnimator mAnimator; | |
75 | + | |
76 | + //背景圆弧 | |
77 | + private Paint mBgArcPaint; | |
78 | + private int mBgArcColor; | |
79 | + | |
80 | + //刻度线颜色 | |
81 | + private Paint mDialPaint; | |
82 | + private float mDialWidth; | |
83 | + private int mDialColor; | |
84 | + | |
85 | + private int mDefaultSize; | |
86 | + | |
87 | + public DialProgress(Context context, AttributeSet attrs) { | |
88 | + super(context, attrs); | |
89 | + init(context, attrs); | |
90 | + } | |
91 | + | |
92 | + private void init(Context context, AttributeSet attrs) { | |
93 | + mContext = context; | |
94 | + mDefaultSize = MiscUtil.dipToPx(context, Constant.DEFAULT_SIZE); | |
95 | + mRectF = new RectF(); | |
96 | + mCenterPoint = new Point(); | |
97 | + initConfig(context, attrs); | |
98 | + initPaint(); | |
99 | + setValue(mValue); | |
100 | + } | |
101 | + | |
102 | + private void initConfig(Context context, AttributeSet attrs) { | |
103 | + TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.DialProgress); | |
104 | + | |
105 | + antiAlias = typedArray.getBoolean(R.styleable.DialProgress_antiAlias, true); | |
106 | + mMaxValue = typedArray.getFloat(R.styleable.DialProgress_maxValue, Constant.DEFAULT_MAX_VALUE); | |
107 | + mValue = typedArray.getFloat(R.styleable.DialProgress_value, Constant.DEFAULT_VALUE); | |
108 | + mValueSize = typedArray.getDimension(R.styleable.DialProgress_valueSize, Constant.DEFAULT_VALUE_SIZE); | |
109 | + mValueColor = typedArray.getColor(R.styleable.DialProgress_valueColor, Color.BLACK); | |
110 | + mDialIntervalDegree = typedArray.getInt(R.styleable.DialProgress_dialIntervalDegree, 10); | |
111 | + int precision = typedArray.getInt(R.styleable.DialProgress_precision, 0); | |
112 | + mPrecisionFormat = MiscUtil.getPrecisionFormat(precision); | |
113 | + | |
114 | + mUnit = typedArray.getString(R.styleable.DialProgress_unit); | |
115 | + mUnitColor = typedArray.getColor(R.styleable.DialProgress_unitColor, Color.BLACK); | |
116 | + mUnitSize = typedArray.getDimension(R.styleable.DialProgress_unitSize, Constant.DEFAULT_UNIT_SIZE); | |
117 | + | |
118 | + mHint = typedArray.getString(R.styleable.DialProgress_hint); | |
119 | + mHintColor = typedArray.getColor(R.styleable.DialProgress_hintColor, Color.BLACK); | |
120 | + mHintSize = typedArray.getDimension(R.styleable.DialProgress_hintSize, Constant.DEFAULT_HINT_SIZE); | |
121 | + | |
122 | + mArcWidth = typedArray.getDimension(R.styleable.DialProgress_arcWidth, Constant.DEFAULT_ARC_WIDTH); | |
123 | + | |
124 | + mStartAngle = typedArray.getFloat(R.styleable.DialProgress_startAngle, Constant.DEFAULT_START_ANGLE); | |
125 | + mSweepAngle = typedArray.getFloat(R.styleable.DialProgress_sweepAngle, Constant.DEFAULT_SWEEP_ANGLE); | |
126 | + | |
127 | + mAnimTime = typedArray.getInt(R.styleable.DialProgress_animTime, Constant.DEFAULT_ANIM_TIME); | |
128 | + | |
129 | + mBgArcColor = typedArray.getColor(R.styleable.DialProgress_bgArcColor, Color.GRAY); | |
130 | + mDialWidth = typedArray.getDimension(R.styleable.DialProgress_dialWidth, 2); | |
131 | + mDialColor = typedArray.getColor(R.styleable.DialProgress_dialColor, Color.WHITE); | |
132 | + | |
133 | + mTextOffsetPercentInRadius = typedArray.getFloat(R.styleable.DialProgress_textOffsetPercentInRadius, 0.33f); | |
134 | + | |
135 | + int gradientArcColors = typedArray.getResourceId(R.styleable.DialProgress_arcColors, 0); | |
136 | + if (gradientArcColors != 0) { | |
137 | + try { | |
138 | + int[] gradientColors = getResources().getIntArray(gradientArcColors); | |
139 | + if (gradientColors.length == 0) { | |
140 | + int color = getResources().getColor(gradientArcColors); | |
141 | + mGradientColors = new int[2]; | |
142 | + mGradientColors[0] = color; | |
143 | + mGradientColors[1] = color; | |
144 | + } else if (gradientColors.length == 1) { | |
145 | + mGradientColors = new int[2]; | |
146 | + mGradientColors[0] = gradientColors[0]; | |
147 | + mGradientColors[1] = gradientColors[0]; | |
148 | + } else { | |
149 | + mGradientColors = gradientColors; | |
150 | + } | |
151 | + } catch (Resources.NotFoundException e) { | |
152 | + throw new Resources.NotFoundException("the give resource not found."); | |
153 | + } | |
154 | + } | |
155 | + typedArray.recycle(); | |
156 | + } | |
157 | + | |
158 | + private void initPaint() { | |
159 | + mHintPaint = new TextPaint(); | |
160 | + // 设置抗锯齿,会消耗较大资源,绘制图形速度会变慢。 | |
161 | + mHintPaint.setAntiAlias(antiAlias); | |
162 | + // 设置绘制文字大小 | |
163 | + mHintPaint.setTextSize(mHintSize); | |
164 | + // 设置画笔颜色 | |
165 | + mHintPaint.setColor(mHintColor); | |
166 | + // 从中间向两边绘制,不需要再次计算文字 | |
167 | + mHintPaint.setTextAlign(Paint.Align.CENTER); | |
168 | + | |
169 | + mValuePaint = new Paint(); | |
170 | + mValuePaint.setAntiAlias(antiAlias); | |
171 | + mValuePaint.setTextSize(mValueSize); | |
172 | + mValuePaint.setColor(mValueColor); | |
173 | + mValuePaint.setTypeface(Typeface.DEFAULT_BOLD); | |
174 | + mValuePaint.setTextAlign(Paint.Align.CENTER); | |
175 | + | |
176 | + mUnitPaint = new Paint(); | |
177 | + mUnitPaint.setAntiAlias(antiAlias); | |
178 | + mUnitPaint.setTextSize(mUnitSize); | |
179 | + mUnitPaint.setColor(mUnitColor); | |
180 | + mUnitPaint.setTextAlign(Paint.Align.CENTER); | |
181 | + | |
182 | + mArcPaint = new Paint(); | |
183 | + mArcPaint.setAntiAlias(antiAlias); | |
184 | + mArcPaint.setStyle(Paint.Style.STROKE); | |
185 | + mArcPaint.setStrokeWidth(mArcWidth); | |
186 | + mArcPaint.setStrokeCap(Paint.Cap.BUTT); | |
187 | + | |
188 | + mBgArcPaint = new Paint(); | |
189 | + mBgArcPaint.setAntiAlias(antiAlias); | |
190 | + mBgArcPaint.setStyle(Paint.Style.STROKE); | |
191 | + mBgArcPaint.setStrokeWidth(mArcWidth); | |
192 | + mBgArcPaint.setStrokeCap(Paint.Cap.BUTT); | |
193 | + mBgArcPaint.setColor(mBgArcColor); | |
194 | + | |
195 | + mDialPaint = new Paint(); | |
196 | + mDialPaint.setAntiAlias(antiAlias); | |
197 | + mDialPaint.setColor(mDialColor); | |
198 | + mDialPaint.setStrokeWidth(mDialWidth); | |
199 | + } | |
200 | + | |
201 | + /** | |
202 | + * 更新圆弧画笔 | |
203 | + */ | |
204 | + private void updateArcPaint() { | |
205 | + // 设置渐变 | |
206 | + // 渐变的颜色是360度,如果只显示270,那么则会缺失部分颜色 | |
207 | + SweepGradient sweepGradient = new SweepGradient(mCenterPoint.x, mCenterPoint.y, mGradientColors, null); | |
208 | + mArcPaint.setShader(sweepGradient); | |
209 | + } | |
210 | + | |
211 | + @Override | |
212 | + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
213 | + super.onMeasure(widthMeasureSpec, heightMeasureSpec); | |
214 | + setMeasuredDimension(MiscUtil.measure(widthMeasureSpec, mDefaultSize), | |
215 | + MiscUtil.measure(heightMeasureSpec, mDefaultSize)); | |
216 | + } | |
217 | + | |
218 | + @Override | |
219 | + protected void onSizeChanged(int w, int h, int oldw, int oldh) { | |
220 | + super.onSizeChanged(w, h, oldw, oldh); | |
221 | + Log.d(TAG, "onSizeChanged: w = " + w + "; h = " + h + "; oldw = " + oldw + "; oldh = " + oldh); | |
222 | + int minSize = Math.min(getMeasuredWidth() - getPaddingLeft() - getPaddingRight() - 2 * (int) mArcWidth, | |
223 | + getMeasuredHeight() - getPaddingTop() - getPaddingBottom() - 2 * (int) mArcWidth); | |
224 | + mRadius = minSize / 2; | |
225 | + mCenterPoint.x = getMeasuredWidth() / 2; | |
226 | + mCenterPoint.y = getMeasuredHeight() / 2; | |
227 | + //绘制圆弧的边界 | |
228 | + mRectF.left = mCenterPoint.x - mRadius - mArcWidth / 2; | |
229 | + mRectF.top = mCenterPoint.y - mRadius - mArcWidth / 2; | |
230 | + mRectF.right = mCenterPoint.x + mRadius + mArcWidth / 2; | |
231 | + mRectF.bottom = mCenterPoint.y + mRadius + mArcWidth / 2; | |
232 | + | |
233 | + mValueOffset = mCenterPoint.y + getBaselineOffsetFromY(mValuePaint); | |
234 | + mHintOffset = mCenterPoint.y - mRadius * mTextOffsetPercentInRadius + getBaselineOffsetFromY(mHintPaint); | |
235 | + mUnitOffset = mCenterPoint.y + mRadius * mTextOffsetPercentInRadius + getBaselineOffsetFromY(mUnitPaint); | |
236 | + | |
237 | + updateArcPaint(); | |
238 | + Log.d(TAG, "onMeasure: 控件大小 = " + "(" + getMeasuredWidth() + ", " + getMeasuredHeight() + ")" | |
239 | + + ";圆心坐标 = " + mCenterPoint.toString() | |
240 | + + ";圆半径 = " + mRadius | |
241 | + + ";圆的外接矩形 = " + mRectF.toString()); | |
242 | + } | |
243 | + | |
244 | + private float getBaselineOffsetFromY(Paint paint) { | |
245 | + return MiscUtil.measureTextHeight(paint) / 2; | |
246 | + } | |
247 | + | |
248 | + @Override | |
249 | + protected void onDraw(Canvas canvas) { | |
250 | + super.onDraw(canvas); | |
251 | + drawArc(canvas); | |
252 | + drawDial(canvas); | |
253 | + drawText(canvas); | |
254 | + } | |
255 | + | |
256 | + private void drawArc(Canvas canvas) { | |
257 | + // 绘制背景圆弧 | |
258 | + // 从进度圆弧结束的地方开始重新绘制,优化性能 | |
259 | + float currentAngle = mSweepAngle * mPercent; | |
260 | + canvas.save(); | |
261 | + canvas.rotate(mStartAngle, mCenterPoint.x, mCenterPoint.y); | |
262 | + canvas.drawArc(mRectF, currentAngle, mSweepAngle - currentAngle, false, mBgArcPaint); | |
263 | + // 第一个参数 oval 为 RectF 类型,即圆弧显示区域 | |
264 | + // startAngle 和 sweepAngle 均为 float 类型,分别表示圆弧起始角度和圆弧度数 | |
265 | + // 3点钟方向为0度,顺时针递增 | |
266 | + // 如果 startAngle < 0 或者 > 360,则相当于 startAngle % 360 | |
267 | + // useCenter:如果为True时,在绘制圆弧时将圆心包括在内,通常用来绘制扇形 | |
268 | + canvas.drawArc(mRectF, 0, currentAngle, false, mArcPaint); | |
269 | + canvas.restore(); | |
270 | + } | |
271 | + | |
272 | + private void drawDial(Canvas canvas) { | |
273 | + int total = (int) (mSweepAngle / mDialIntervalDegree); | |
274 | + canvas.save(); | |
275 | + canvas.rotate(mStartAngle, mCenterPoint.x, mCenterPoint.y); | |
276 | + for (int i = 0; i <= total; i++) { | |
277 | + canvas.drawLine(mCenterPoint.x + mRadius, mCenterPoint.y, mCenterPoint.x + mRadius + mArcWidth, mCenterPoint.y, mDialPaint); | |
278 | + canvas.rotate(mDialIntervalDegree, mCenterPoint.x, mCenterPoint.y); | |
279 | + } | |
280 | + canvas.restore(); | |
281 | + } | |
282 | + | |
283 | + private void drawText(Canvas canvas) { | |
284 | + canvas.drawText(String.format(mPrecisionFormat, mValue), mCenterPoint.x, mValueOffset, mValuePaint); | |
285 | + | |
286 | + if (mUnit != null) { | |
287 | + canvas.drawText(mUnit.toString(), mCenterPoint.x, mUnitOffset, mUnitPaint); | |
288 | + } | |
289 | + | |
290 | + if (mHint != null) { | |
291 | + canvas.drawText(mHint.toString(), mCenterPoint.x, mHintOffset, mHintPaint); | |
292 | + } | |
293 | + } | |
294 | + | |
295 | + public float getMaxValue() { | |
296 | + return mMaxValue; | |
297 | + } | |
298 | + | |
299 | + public void setMaxValue(float maxValue) { | |
300 | + mMaxValue = maxValue; | |
301 | + } | |
302 | + | |
303 | + /** | |
304 | + * 设置当前值 | |
305 | + * | |
306 | + * @param value | |
307 | + */ | |
308 | + public void setValue(float value) { | |
309 | + if (value > mMaxValue) { | |
310 | + value = mMaxValue; | |
311 | + } | |
312 | + float start = mPercent; | |
313 | + float end = value / mMaxValue; | |
314 | + startAnimator(start, end, mAnimTime); | |
315 | + } | |
316 | + | |
317 | + private void startAnimator(float start, float end, long animTime) { | |
318 | + mAnimator = ValueAnimator.ofFloat(start, end); | |
319 | + mAnimator.setDuration(animTime); | |
320 | + mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { | |
321 | + @Override | |
322 | + public void onAnimationUpdate(ValueAnimator animation) { | |
323 | + mPercent = (float) animation.getAnimatedValue(); | |
324 | + mValue = mPercent * mMaxValue; | |
325 | + invalidate(); | |
326 | + } | |
327 | + }); | |
328 | + mAnimator.start(); | |
329 | + } | |
330 | + | |
331 | + public int[] getGradientColors() { | |
332 | + return mGradientColors; | |
333 | + } | |
334 | + | |
335 | + public void setGradientColors(int[] gradientColors) { | |
336 | + mGradientColors = gradientColors; | |
337 | + updateArcPaint(); | |
338 | + } | |
339 | + | |
340 | + public void reset() { | |
341 | + startAnimator(mPercent, 0.0f, 1000L); | |
342 | + } | |
343 | +} | ... | ... |
libs/common/src/main/java/com/littlejie/circleprogress/WaveProgress.java
... | ... | @@ -0,0 +1,506 @@ |
1 | +package com.littlejie.circleprogress; | |
2 | + | |
3 | +import android.animation.Animator; | |
4 | +import android.animation.ValueAnimator; | |
5 | +import android.annotation.TargetApi; | |
6 | +import android.content.Context; | |
7 | +import android.content.res.TypedArray; | |
8 | +import android.graphics.Canvas; | |
9 | +import android.graphics.Color; | |
10 | +import android.graphics.Paint; | |
11 | +import android.graphics.Path; | |
12 | +import android.graphics.Point; | |
13 | +import android.graphics.RectF; | |
14 | +import android.os.Build; | |
15 | +import android.text.TextPaint; | |
16 | +import android.util.AttributeSet; | |
17 | +import android.util.Log; | |
18 | +import android.view.View; | |
19 | +import android.view.animation.LinearInterpolator; | |
20 | + | |
21 | +import com.prws.common.R; | |
22 | +import com.littlejie.circleprogress.utils.Constant; | |
23 | +import com.littlejie.circleprogress.utils.MiscUtil; | |
24 | + | |
25 | +/** | |
26 | + * 水波进度条 | |
27 | + * Created by littlejie on 2017/2/26. | |
28 | + */ | |
29 | + | |
30 | +public class WaveProgress extends View { | |
31 | + | |
32 | + private static final String TAG = WaveProgress.class.getSimpleName(); | |
33 | + | |
34 | + //浅色波浪方向 | |
35 | + private static final int L2R = 0; | |
36 | + private static final int R2L = 1; | |
37 | + | |
38 | + private int mDefaultSize; | |
39 | + //圆心 | |
40 | + private Point mCenterPoint; | |
41 | + //半径 | |
42 | + private float mRadius; | |
43 | + //圆的外接矩形 | |
44 | + private RectF mRectF; | |
45 | + //深色波浪移动距离 | |
46 | + private float mDarkWaveOffset; | |
47 | + //浅色波浪移动距离 | |
48 | + private float mLightWaveOffset; | |
49 | + //浅色波浪方向 | |
50 | + private boolean isR2L; | |
51 | + //是否锁定波浪不随进度移动 | |
52 | + private boolean lockWave; | |
53 | + | |
54 | + //是否开启抗锯齿 | |
55 | + private boolean antiAlias; | |
56 | + //最大值 | |
57 | + private float mMaxValue; | |
58 | + //当前值 | |
59 | + private float mValue; | |
60 | + //当前进度 | |
61 | + private float mPercent; | |
62 | + | |
63 | + //绘制提示 | |
64 | + private TextPaint mHintPaint; | |
65 | + private CharSequence mHint; | |
66 | + private int mHintColor; | |
67 | + private float mHintSize; | |
68 | + | |
69 | + private Paint mPercentPaint; | |
70 | + private float mValueSize; | |
71 | + private int mValueColor; | |
72 | + | |
73 | + //圆环宽度 | |
74 | + private float mCircleWidth; | |
75 | + //圆环 | |
76 | + private Paint mCirclePaint; | |
77 | + //圆环颜色 | |
78 | + private int mCircleColor; | |
79 | + //背景圆环颜色 | |
80 | + private int mBgCircleColor; | |
81 | + | |
82 | + //水波路径 | |
83 | + private Path mWaveLimitPath; | |
84 | + private Path mWavePath; | |
85 | + //水波高度 | |
86 | + private float mWaveHeight; | |
87 | + //水波数量 | |
88 | + private int mWaveNum; | |
89 | + //深色水波 | |
90 | + private Paint mWavePaint; | |
91 | + //深色水波颜色 | |
92 | + private int mDarkWaveColor; | |
93 | + //浅色水波颜色 | |
94 | + private int mLightWaveColor; | |
95 | + | |
96 | + //深色水波贝塞尔曲线上的起始点、控制点 | |
97 | + private Point[] mDarkPoints; | |
98 | + //浅色水波贝塞尔曲线上的起始点、控制点 | |
99 | + private Point[] mLightPoints; | |
100 | + | |
101 | + //贝塞尔曲线点的总个数 | |
102 | + private int mAllPointCount; | |
103 | + private int mHalfPointCount; | |
104 | + | |
105 | + private ValueAnimator mProgressAnimator; | |
106 | + private long mDarkWaveAnimTime; | |
107 | + private ValueAnimator mDarkWaveAnimator; | |
108 | + private long mLightWaveAnimTime; | |
109 | + private ValueAnimator mLightWaveAnimator; | |
110 | + | |
111 | + public WaveProgress(Context context, AttributeSet attrs) { | |
112 | + super(context, attrs); | |
113 | + init(context, attrs); | |
114 | + } | |
115 | + | |
116 | + private void init(Context context, AttributeSet attrs) { | |
117 | + mDefaultSize = MiscUtil.dipToPx(context, Constant.DEFAULT_SIZE); | |
118 | + mRectF = new RectF(); | |
119 | + mCenterPoint = new Point(); | |
120 | + | |
121 | + initAttrs(context, attrs); | |
122 | + initPaint(); | |
123 | + initPath(); | |
124 | + } | |
125 | + | |
126 | + private void initAttrs(Context context, AttributeSet attrs) { | |
127 | + TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.WaveProgress); | |
128 | + | |
129 | + antiAlias = typedArray.getBoolean(R.styleable.WaveProgress_antiAlias, true); | |
130 | + mDarkWaveAnimTime = typedArray.getInt(R.styleable.WaveProgress_darkWaveAnimTime, Constant.DEFAULT_ANIM_TIME); | |
131 | + mLightWaveAnimTime = typedArray.getInt(R.styleable.WaveProgress_lightWaveAnimTime, Constant.DEFAULT_ANIM_TIME); | |
132 | + mMaxValue = typedArray.getFloat(R.styleable.WaveProgress_maxValue, Constant.DEFAULT_MAX_VALUE); | |
133 | + mValue = typedArray.getFloat(R.styleable.WaveProgress_value, Constant.DEFAULT_VALUE); | |
134 | + mValueSize = typedArray.getDimension(R.styleable.WaveProgress_valueSize, Constant.DEFAULT_VALUE_SIZE); | |
135 | + mValueColor = typedArray.getColor(R.styleable.WaveProgress_valueColor, Color.BLACK); | |
136 | + | |
137 | + mHint = typedArray.getString(R.styleable.WaveProgress_hint); | |
138 | + mHintColor = typedArray.getColor(R.styleable.WaveProgress_hintColor, Color.BLACK); | |
139 | + mHintSize = typedArray.getDimension(R.styleable.WaveProgress_hintSize, Constant.DEFAULT_HINT_SIZE); | |
140 | + | |
141 | + mCircleWidth = typedArray.getDimension(R.styleable.WaveProgress_circleWidth, Constant.DEFAULT_ARC_WIDTH); | |
142 | + mCircleColor = typedArray.getColor(R.styleable.WaveProgress_circleColor, Color.GREEN); | |
143 | + mBgCircleColor = typedArray.getColor(R.styleable.WaveProgress_bgCircleColor, Color.WHITE); | |
144 | + | |
145 | + mWaveHeight = typedArray.getDimension(R.styleable.WaveProgress_waveHeight, Constant.DEFAULT_WAVE_HEIGHT); | |
146 | + mWaveNum = typedArray.getInt(R.styleable.WaveProgress_waveNum, 1); | |
147 | + mDarkWaveColor = typedArray.getColor(R.styleable.WaveProgress_darkWaveColor, | |
148 | + getResources().getColor(android.R.color.holo_blue_dark)); | |
149 | + mLightWaveColor = typedArray.getColor(R.styleable.WaveProgress_lightWaveColor, | |
150 | + getResources().getColor(android.R.color.holo_green_light)); | |
151 | + | |
152 | + isR2L = typedArray.getInt(R.styleable.WaveProgress_lightWaveDirect, R2L) == R2L; | |
153 | + lockWave = typedArray.getBoolean(R.styleable.WaveProgress_lockWave, false); | |
154 | + | |
155 | + typedArray.recycle(); | |
156 | + } | |
157 | + | |
158 | + private void initPaint() { | |
159 | + mHintPaint = new TextPaint(); | |
160 | + // 设置抗锯齿,会消耗较大资源,绘制图形速度会变慢。 | |
161 | + mHintPaint.setAntiAlias(antiAlias); | |
162 | + // 设置绘制文字大小 | |
163 | + mHintPaint.setTextSize(mHintSize); | |
164 | + // 设置画笔颜色 | |
165 | + mHintPaint.setColor(mHintColor); | |
166 | + // 从中间向两边绘制,不需要再次计算文字 | |
167 | + mHintPaint.setTextAlign(Paint.Align.CENTER); | |
168 | + | |
169 | + mCirclePaint = new Paint(); | |
170 | + mCirclePaint.setAntiAlias(antiAlias); | |
171 | + mCirclePaint.setStrokeWidth(mCircleWidth); | |
172 | + mCirclePaint.setStyle(Paint.Style.STROKE); | |
173 | + mCirclePaint.setStrokeCap(Paint.Cap.ROUND); | |
174 | + | |
175 | + mWavePaint = new Paint(); | |
176 | + mWavePaint.setAntiAlias(antiAlias); | |
177 | + mWavePaint.setStyle(Paint.Style.FILL); | |
178 | + | |
179 | + mPercentPaint = new Paint(); | |
180 | + mPercentPaint.setTextAlign(Paint.Align.CENTER); | |
181 | + mPercentPaint.setAntiAlias(antiAlias); | |
182 | + mPercentPaint.setColor(mValueColor); | |
183 | + mPercentPaint.setTextSize(mValueSize); | |
184 | + } | |
185 | + | |
186 | + private void initPath() { | |
187 | + mWaveLimitPath = new Path(); | |
188 | + mWavePath = new Path(); | |
189 | + } | |
190 | + | |
191 | + @Override | |
192 | + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
193 | + super.onMeasure(widthMeasureSpec, heightMeasureSpec); | |
194 | + setMeasuredDimension(MiscUtil.measure(widthMeasureSpec, mDefaultSize), | |
195 | + MiscUtil.measure(heightMeasureSpec, mDefaultSize)); | |
196 | + } | |
197 | + | |
198 | + @Override | |
199 | + protected void onSizeChanged(int w, int h, int oldw, int oldh) { | |
200 | + super.onSizeChanged(w, h, oldw, oldh); | |
201 | + Log.d(TAG, "onSizeChanged: w = " + w + "; h = " + h + "; oldw = " + oldw + "; oldh = " + oldh); | |
202 | + int minSize = Math.min(getMeasuredWidth() - getPaddingLeft() - getPaddingRight() - 2 * (int) mCircleWidth, | |
203 | + getMeasuredHeight() - getPaddingTop() - getPaddingBottom() - 2 * (int) mCircleWidth); | |
204 | + mRadius = minSize / 2; | |
205 | + mCenterPoint.x = getMeasuredWidth() / 2; | |
206 | + mCenterPoint.y = getMeasuredHeight() / 2; | |
207 | + //绘制圆弧的边界 | |
208 | + mRectF.left = mCenterPoint.x - mRadius - mCircleWidth / 2; | |
209 | + mRectF.top = mCenterPoint.y - mRadius - mCircleWidth / 2; | |
210 | + mRectF.right = mCenterPoint.x + mRadius + mCircleWidth / 2; | |
211 | + mRectF.bottom = mCenterPoint.y + mRadius + mCircleWidth / 2; | |
212 | + Log.d(TAG, "onSizeChanged: 控件大小 = " + "(" + getMeasuredWidth() + ", " + getMeasuredHeight() + ")" | |
213 | + + ";圆心坐标 = " + mCenterPoint.toString() | |
214 | + + ";圆半径 = " + mRadius | |
215 | + + ";圆的外接矩形 = " + mRectF.toString()); | |
216 | + initWavePoints(); | |
217 | + //开始动画 | |
218 | + setValue(mValue); | |
219 | + startWaveAnimator(); | |
220 | + } | |
221 | + | |
222 | + private void initWavePoints() { | |
223 | + //当前波浪宽度 | |
224 | + float waveWidth = (mRadius * 2) / mWaveNum; | |
225 | + mAllPointCount = 8 * mWaveNum + 1; | |
226 | + mHalfPointCount = mAllPointCount / 2; | |
227 | + mDarkPoints = getPoint(false, waveWidth); | |
228 | + mLightPoints = getPoint(isR2L, waveWidth); | |
229 | + } | |
230 | + | |
231 | + /** | |
232 | + * 从左往右或者从右往左获取贝塞尔点 | |
233 | + * | |
234 | + * @return | |
235 | + */ | |
236 | + private Point[] getPoint(boolean isR2L, float waveWidth) { | |
237 | + Point[] points = new Point[mAllPointCount]; | |
238 | + //第1个点特殊处理,即数组的中点 | |
239 | + points[mHalfPointCount] = new Point((int) (mCenterPoint.x + (isR2L ? mRadius : -mRadius)), mCenterPoint.y); | |
240 | + //屏幕内的贝塞尔曲线点 | |
241 | + for (int i = mHalfPointCount + 1; i < mAllPointCount; i += 4) { | |
242 | + float width = points[mHalfPointCount].x + waveWidth * (i / 4 - mWaveNum); | |
243 | + points[i] = new Point((int) (waveWidth / 4 + width), (int) (mCenterPoint.y - mWaveHeight)); | |
244 | + points[i + 1] = new Point((int) (waveWidth / 2 + width), mCenterPoint.y); | |
245 | + points[i + 2] = new Point((int) (waveWidth * 3 / 4 + width), (int) (mCenterPoint.y + mWaveHeight)); | |
246 | + points[i + 3] = new Point((int) (waveWidth + width), mCenterPoint.y); | |
247 | + } | |
248 | + //屏幕外的贝塞尔曲线点 | |
249 | + for (int i = 0; i < mHalfPointCount; i++) { | |
250 | + int reverse = mAllPointCount - i - 1; | |
251 | + points[i] = new Point((isR2L ? 2 : 1) * points[mHalfPointCount].x - points[reverse].x, | |
252 | + points[mHalfPointCount].y * 2 - points[reverse].y); | |
253 | + } | |
254 | + //对从右向左的贝塞尔点数组反序,方便后续处理 | |
255 | + return isR2L ? MiscUtil.reverse(points) : points; | |
256 | + } | |
257 | + | |
258 | + @Override | |
259 | + protected void onDraw(Canvas canvas) { | |
260 | + super.onDraw(canvas); | |
261 | + drawCircle(canvas); | |
262 | + drawLightWave(canvas); | |
263 | + drawDarkWave(canvas); | |
264 | + drawProgress(canvas); | |
265 | + } | |
266 | + | |
267 | + /** | |
268 | + * 绘制圆环 | |
269 | + * | |
270 | + * @param canvas | |
271 | + */ | |
272 | + private void drawCircle(Canvas canvas) { | |
273 | + canvas.save(); | |
274 | + canvas.rotate(270, mCenterPoint.x, mCenterPoint.y); | |
275 | + int currentAngle = (int) (360 * mPercent); | |
276 | + //画背景圆环 | |
277 | + mCirclePaint.setColor(mBgCircleColor); | |
278 | + canvas.drawArc(mRectF, currentAngle, 360 - currentAngle, false, mCirclePaint); | |
279 | + //画圆环 | |
280 | + mCirclePaint.setColor(mCircleColor); | |
281 | + canvas.drawArc(mRectF, 0, currentAngle, false, mCirclePaint); | |
282 | + canvas.restore(); | |
283 | + } | |
284 | + | |
285 | + /** | |
286 | + * 绘制深色波浪(贝塞尔曲线) | |
287 | + * | |
288 | + * @param canvas | |
289 | + */ | |
290 | + private void drawDarkWave(Canvas canvas) { | |
291 | + mWavePaint.setColor(mDarkWaveColor); | |
292 | + drawWave(canvas, mWavePaint, mDarkPoints, mDarkWaveOffset); | |
293 | + } | |
294 | + | |
295 | + /** | |
296 | + * 绘制浅色波浪(贝塞尔曲线) | |
297 | + * | |
298 | + * @param canvas | |
299 | + */ | |
300 | + private void drawLightWave(Canvas canvas) { | |
301 | + mWavePaint.setColor(mLightWaveColor); | |
302 | + //从右向左的水波位移应该被减去 | |
303 | + drawWave(canvas, mWavePaint, mLightPoints, isR2L ? -mLightWaveOffset : mLightWaveOffset); | |
304 | + } | |
305 | + | |
306 | + @TargetApi(Build.VERSION_CODES.KITKAT) | |
307 | + private void drawWave(Canvas canvas, Paint paint, Point[] points, float waveOffset) { | |
308 | + mWaveLimitPath.reset(); | |
309 | + mWavePath.reset(); | |
310 | + float height = lockWave ? 0 : mRadius - 2 * mRadius * mPercent; | |
311 | + //moveTo和lineTo绘制出水波区域矩形 | |
312 | + mWavePath.moveTo(points[0].x + waveOffset, points[0].y + height); | |
313 | + | |
314 | + for (int i = 1; i < mAllPointCount; i += 2) { | |
315 | + mWavePath.quadTo(points[i].x + waveOffset, points[i].y + height, | |
316 | + points[i + 1].x + waveOffset, points[i + 1].y + height); | |
317 | + } | |
318 | + //mWavePath.lineTo(points[mAllPointCount - 1].x, points[mAllPointCount - 1].y + height); | |
319 | + //不管如何移动,波浪与圆路径的交集底部永远固定,否则会造成上移的时候底部为空的情况 | |
320 | + mWavePath.lineTo(points[mAllPointCount - 1].x, mCenterPoint.y + mRadius); | |
321 | + mWavePath.lineTo(points[0].x, mCenterPoint.y + mRadius); | |
322 | + mWavePath.close(); | |
323 | + mWaveLimitPath.addCircle(mCenterPoint.x, mCenterPoint.y, mRadius, Path.Direction.CW); | |
324 | + //取该圆与波浪路径的交集,形成波浪在圆内的效果 | |
325 | + mWaveLimitPath.op(mWavePath, Path.Op.INTERSECT); | |
326 | + canvas.drawPath(mWaveLimitPath, paint); | |
327 | + } | |
328 | + | |
329 | + //前一次绘制时的进度 | |
330 | + private float mPrePercent; | |
331 | + //当前进度值 | |
332 | + private String mPercentValue; | |
333 | + | |
334 | + private void drawProgress(Canvas canvas) { | |
335 | + float y = mCenterPoint.y - (mPercentPaint.descent() + mPercentPaint.ascent()) / 2; | |
336 | + if (mPrePercent == 0.0f || Math.abs(mPercent - mPrePercent) >= 0.01f) { | |
337 | + mPercentValue = String.format("%.0f%%", mPercent * 100); | |
338 | + mPrePercent = mPercent; | |
339 | + } | |
340 | + canvas.drawText(mPercentValue, mCenterPoint.x, y, mPercentPaint); | |
341 | + | |
342 | + if (mHint != null) { | |
343 | + float hy = mCenterPoint.y * 2 / 3 - (mHintPaint.descent() + mHintPaint.ascent()) / 2; | |
344 | + canvas.drawText(mHint.toString(), mCenterPoint.x, hy, mHintPaint); | |
345 | + } | |
346 | + } | |
347 | + | |
348 | + public float getMaxValue() { | |
349 | + return mMaxValue; | |
350 | + } | |
351 | + | |
352 | + public void setMaxValue(float maxValue) { | |
353 | + mMaxValue = maxValue; | |
354 | + } | |
355 | + | |
356 | + public float getValue() { | |
357 | + return mValue; | |
358 | + } | |
359 | + | |
360 | + /** | |
361 | + * 设置当前值 | |
362 | + * | |
363 | + * @param value | |
364 | + */ | |
365 | + public void setValue(float value) { | |
366 | + if (value > mMaxValue) { | |
367 | + value = mMaxValue; | |
368 | + } | |
369 | + float start = mPercent; | |
370 | + float end = value / mMaxValue; | |
371 | + Log.d(TAG, "setValue, value = " + value + ";start = " + start + "; end = " + end); | |
372 | + startAnimator(start, end, mDarkWaveAnimTime); | |
373 | + } | |
374 | + | |
375 | + private void startAnimator(final float start, float end, long animTime) { | |
376 | + Log.d(TAG, "startAnimator,value = " + mValue | |
377 | + + ";start = " + start + ";end = " + end + ";time = " + animTime); | |
378 | + //当start=0且end=0时,不需要启动动画 | |
379 | + if (start == 0 && end == 0) { | |
380 | + return; | |
381 | + } | |
382 | + mProgressAnimator = ValueAnimator.ofFloat(start, end); | |
383 | + mProgressAnimator.setDuration(animTime); | |
384 | + mProgressAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { | |
385 | + @Override | |
386 | + public void onAnimationUpdate(ValueAnimator animation) { | |
387 | + mPercent = (float) animation.getAnimatedValue(); | |
388 | + if (mPercent == 0.0f || mPercent == 1.0f) { | |
389 | + stopWaveAnimator(); | |
390 | + } else { | |
391 | + startWaveAnimator(); | |
392 | + } | |
393 | + mValue = mPercent * mMaxValue; | |
394 | + invalidate(); | |
395 | + } | |
396 | + }); | |
397 | + mProgressAnimator.start(); | |
398 | + } | |
399 | + | |
400 | + private void startWaveAnimator() { | |
401 | + startLightWaveAnimator(); | |
402 | + startDarkWaveAnimator(); | |
403 | + } | |
404 | + | |
405 | + private void stopWaveAnimator() { | |
406 | + if (mDarkWaveAnimator != null && mDarkWaveAnimator.isRunning()) { | |
407 | + mDarkWaveAnimator.cancel(); | |
408 | + mDarkWaveAnimator.removeAllUpdateListeners(); | |
409 | + mDarkWaveAnimator = null; | |
410 | + } | |
411 | + if (mLightWaveAnimator != null && mLightWaveAnimator.isRunning()) { | |
412 | + mLightWaveAnimator.cancel(); | |
413 | + mLightWaveAnimator.removeAllUpdateListeners(); | |
414 | + mLightWaveAnimator = null; | |
415 | + } | |
416 | + } | |
417 | + | |
418 | + private void startLightWaveAnimator() { | |
419 | + if (mLightWaveAnimator != null && mLightWaveAnimator.isRunning()) { | |
420 | + return; | |
421 | + } | |
422 | + mLightWaveAnimator = ValueAnimator.ofFloat(0, 2 * mRadius); | |
423 | + mLightWaveAnimator.setDuration(mLightWaveAnimTime); | |
424 | + mLightWaveAnimator.setRepeatCount(ValueAnimator.INFINITE); | |
425 | + mLightWaveAnimator.setInterpolator(new LinearInterpolator()); | |
426 | + mLightWaveAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { | |
427 | + @Override | |
428 | + public void onAnimationUpdate(ValueAnimator animation) { | |
429 | + mLightWaveOffset = (float) animation.getAnimatedValue(); | |
430 | + postInvalidate(); | |
431 | + } | |
432 | + }); | |
433 | + mLightWaveAnimator.addListener(new Animator.AnimatorListener() { | |
434 | + @Override | |
435 | + public void onAnimationStart(Animator animation) { | |
436 | + mLightWaveOffset = 0; | |
437 | + } | |
438 | + | |
439 | + @Override | |
440 | + public void onAnimationEnd(Animator animation) { | |
441 | + | |
442 | + } | |
443 | + | |
444 | + @Override | |
445 | + public void onAnimationCancel(Animator animation) { | |
446 | + | |
447 | + } | |
448 | + | |
449 | + @Override | |
450 | + public void onAnimationRepeat(Animator animation) { | |
451 | + | |
452 | + } | |
453 | + }); | |
454 | + mLightWaveAnimator.start(); | |
455 | + } | |
456 | + | |
457 | + private void startDarkWaveAnimator() { | |
458 | + if (mDarkWaveAnimator != null && mDarkWaveAnimator.isRunning()) { | |
459 | + return; | |
460 | + } | |
461 | + mDarkWaveAnimator = ValueAnimator.ofFloat(0, 2 * mRadius); | |
462 | + mDarkWaveAnimator.setDuration(mDarkWaveAnimTime); | |
463 | + mDarkWaveAnimator.setRepeatCount(ValueAnimator.INFINITE); | |
464 | + mDarkWaveAnimator.setInterpolator(new LinearInterpolator()); | |
465 | + mDarkWaveAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { | |
466 | + @Override | |
467 | + public void onAnimationUpdate(ValueAnimator animation) { | |
468 | + mDarkWaveOffset = (float) animation.getAnimatedValue(); | |
469 | + postInvalidate(); | |
470 | + } | |
471 | + }); | |
472 | + mDarkWaveAnimator.addListener(new Animator.AnimatorListener() { | |
473 | + @Override | |
474 | + public void onAnimationStart(Animator animation) { | |
475 | + mDarkWaveOffset = 0; | |
476 | + } | |
477 | + | |
478 | + @Override | |
479 | + public void onAnimationEnd(Animator animation) { | |
480 | + | |
481 | + } | |
482 | + | |
483 | + @Override | |
484 | + public void onAnimationCancel(Animator animation) { | |
485 | + | |
486 | + } | |
487 | + | |
488 | + @Override | |
489 | + public void onAnimationRepeat(Animator animation) { | |
490 | + | |
491 | + } | |
492 | + }); | |
493 | + mDarkWaveAnimator.start(); | |
494 | + } | |
495 | + | |
496 | + @Override | |
497 | + protected void onDetachedFromWindow() { | |
498 | + super.onDetachedFromWindow(); | |
499 | + stopWaveAnimator(); | |
500 | + if (mProgressAnimator != null && mProgressAnimator.isRunning()) { | |
501 | + mProgressAnimator.cancel(); | |
502 | + mProgressAnimator.removeAllUpdateListeners(); | |
503 | + mProgressAnimator = null; | |
504 | + } | |
505 | + } | |
506 | +} | ... | ... |
libs/common/src/main/java/com/littlejie/circleprogress/utils/Constant.java
... | ... | @@ -0,0 +1,26 @@ |
1 | +package com.littlejie.circleprogress.utils; | |
2 | + | |
3 | +/** | |
4 | + * Created by littlejie on 2017/2/26. | |
5 | + */ | |
6 | +public class Constant { | |
7 | + | |
8 | + public static final boolean ANTI_ALIAS = true; | |
9 | + | |
10 | + public static final int DEFAULT_SIZE = 150; | |
11 | + public static final int DEFAULT_START_ANGLE = 270; | |
12 | + public static final int DEFAULT_SWEEP_ANGLE = 360; | |
13 | + | |
14 | + public static final int DEFAULT_ANIM_TIME = 1000; | |
15 | + | |
16 | + public static final int DEFAULT_MAX_VALUE = 100; | |
17 | + public static final int DEFAULT_VALUE = 50; | |
18 | + | |
19 | + public static final int DEFAULT_HINT_SIZE = 15; | |
20 | + public static final int DEFAULT_UNIT_SIZE = 30; | |
21 | + public static final int DEFAULT_VALUE_SIZE = 15; | |
22 | + | |
23 | + public static final int DEFAULT_ARC_WIDTH = 15; | |
24 | + | |
25 | + public static final int DEFAULT_WAVE_HEIGHT = 40; | |
26 | +} | ... | ... |
libs/common/src/main/java/com/littlejie/circleprogress/utils/MiscUtil.java
... | ... | @@ -0,0 +1,83 @@ |
1 | +package com.littlejie.circleprogress.utils; | |
2 | + | |
3 | +import android.content.Context; | |
4 | +import android.graphics.Paint; | |
5 | +import android.view.View; | |
6 | + | |
7 | +/** | |
8 | + * Created by littlejie on 2017/2/22. | |
9 | + */ | |
10 | + | |
11 | +public class MiscUtil { | |
12 | + | |
13 | + /** | |
14 | + * 测量 View | |
15 | + * | |
16 | + * @param measureSpec | |
17 | + * @param defaultSize View 的默认大小 | |
18 | + * @return | |
19 | + */ | |
20 | + public static int measure(int measureSpec, int defaultSize) { | |
21 | + int result = defaultSize; | |
22 | + int specMode = View.MeasureSpec.getMode(measureSpec); | |
23 | + int specSize = View.MeasureSpec.getSize(measureSpec); | |
24 | + | |
25 | + if (specMode == View.MeasureSpec.EXACTLY) { | |
26 | + result = specSize; | |
27 | + } else if (specMode == View.MeasureSpec.AT_MOST) { | |
28 | + result = Math.min(result, specSize); | |
29 | + } | |
30 | + return result; | |
31 | + } | |
32 | + | |
33 | + /** | |
34 | + * dip 转换成px | |
35 | + * | |
36 | + * @param dip | |
37 | + * @return | |
38 | + */ | |
39 | + public static int dipToPx(Context context, float dip) { | |
40 | + float density = context.getResources().getDisplayMetrics().density; | |
41 | + return (int) (dip * density + 0.5f * (dip >= 0 ? 1 : -1)); | |
42 | + } | |
43 | + | |
44 | + /** | |
45 | + * 获取数值精度格式化字符串 | |
46 | + * | |
47 | + * @param precision | |
48 | + * @return | |
49 | + */ | |
50 | + public static String getPrecisionFormat(int precision) { | |
51 | + return "%." + precision + "f"; | |
52 | + } | |
53 | + | |
54 | + /** | |
55 | + * 反转数组 | |
56 | + * | |
57 | + * @param arrays | |
58 | + * @param <T> | |
59 | + * @return | |
60 | + */ | |
61 | + public static <T> T[] reverse(T[] arrays) { | |
62 | + if (arrays == null) { | |
63 | + return null; | |
64 | + } | |
65 | + int length = arrays.length; | |
66 | + for (int i = 0; i < length / 2; i++) { | |
67 | + T t = arrays[i]; | |
68 | + arrays[i] = arrays[length - i - 1]; | |
69 | + arrays[length - i - 1] = t; | |
70 | + } | |
71 | + return arrays; | |
72 | + } | |
73 | + | |
74 | + /** | |
75 | + * 测量文字高度 | |
76 | + * @param paint | |
77 | + * @return | |
78 | + */ | |
79 | + public static float measureTextHeight(Paint paint) { | |
80 | + Paint.FontMetrics fontMetrics = paint.getFontMetrics(); | |
81 | + return (Math.abs(fontMetrics.ascent) - fontMetrics.descent); | |
82 | + } | |
83 | +} | |
0 | 84 | \ No newline at end of file | ... | ... |
libs/common/src/main/res/values/attrs_circle_progress.xml
... | ... | @@ -0,0 +1,139 @@ |
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<resources> | |
3 | + <!-- 是否开启抗锯齿 --> | |
4 | + <attr name="antiAlias" format="boolean" /> | |
5 | + <!-- 圆弧起始角度,3点钟方向为0,顺时针递增,小于0或大于360进行取余 --> | |
6 | + <attr name="startAngle" format="float" /> | |
7 | + <!-- 圆弧度数 --> | |
8 | + <attr name="sweepAngle" format="float" /> | |
9 | + <!-- 设置动画时间 --> | |
10 | + <attr name="animTime" format="integer" /> | |
11 | + <!-- 绘制内容的数值 --> | |
12 | + <attr name="maxValue" format="float" /> | |
13 | + <attr name="value" format="float" /> | |
14 | + <!-- 绘制内容的单位 --> | |
15 | + <attr name="unit" format="string|reference" /> | |
16 | + <attr name="unitSize" format="dimension" /> | |
17 | + <attr name="unitColor" format="color|reference" /> | |
18 | + <!-- 绘制内容相应的提示语 --> | |
19 | + <attr name="hint" format="string|reference" /> | |
20 | + <attr name="hintSize" format="dimension" /> | |
21 | + <attr name="hintColor" format="color|reference" /> | |
22 | + <!-- 精度,默认为0 --> | |
23 | + <attr name="precision" format="integer" /> | |
24 | + <attr name="valueSize" format="dimension" /> | |
25 | + <attr name="valueColor" format="color|reference" /> | |
26 | + | |
27 | + <!-- 背景圆弧颜色,默认白色 --> | |
28 | + <attr name="bgArcColor" format="color|reference" /> | |
29 | + <!-- 圆弧宽度 --> | |
30 | + <attr name="arcWidth" format="dimension" /> | |
31 | + <!-- 圆弧颜色, --> | |
32 | + <attr name="arcColors" format="color|reference" /> | |
33 | + <!-- 文字的偏移量。相对于圆半径而言,默认三分之一 --> | |
34 | + <attr name="textOffsetPercentInRadius" format="float" /> | |
35 | + | |
36 | + <!-- 圆形进度条 --> | |
37 | + <declare-styleable name="CircleProgressBar"> | |
38 | + <attr name="antiAlias" /> | |
39 | + <attr name="startAngle" /> | |
40 | + <attr name="sweepAngle" /> | |
41 | + <attr name="animTime" /> | |
42 | + <attr name="maxValue" /> | |
43 | + <attr name="value" /> | |
44 | + <attr name="precision" /> | |
45 | + <attr name="valueSize" /> | |
46 | + <attr name="valueColor" /> | |
47 | + <attr name="textOffsetPercentInRadius" /> | |
48 | + <!-- 绘制内容相应的提示语 --> | |
49 | + <attr name="hint" /> | |
50 | + <attr name="hintSize" /> | |
51 | + <attr name="hintColor" /> | |
52 | + <!-- 绘制内容的单位 --> | |
53 | + <attr name="unit" /> | |
54 | + <attr name="unitSize" /> | |
55 | + <attr name="unitColor" /> | |
56 | + <!-- 圆弧宽度 --> | |
57 | + <attr name="arcWidth" /> | |
58 | + <attr name="arcColors" /> | |
59 | + <!-- 背景圆弧颜色 --> | |
60 | + <attr name="bgArcColor" /> | |
61 | + <!-- 背景圆弧宽度 --> | |
62 | + <attr name="bgArcWidth" format="dimension" /> | |
63 | + </declare-styleable> | |
64 | + | |
65 | + <declare-styleable name="DialProgress"> | |
66 | + <attr name="antiAlias" /> | |
67 | + <attr name="startAngle" /> | |
68 | + <attr name="sweepAngle" /> | |
69 | + <attr name="animTime" /> | |
70 | + <attr name="maxValue" /> | |
71 | + <attr name="value" /> | |
72 | + <attr name="precision" /> | |
73 | + <attr name="valueSize" /> | |
74 | + <attr name="valueColor" /> | |
75 | + <attr name="textOffsetPercentInRadius" /> | |
76 | + <!-- 绘制内容的单位 --> | |
77 | + <attr name="unit" /> | |
78 | + <attr name="unitSize" /> | |
79 | + <attr name="unitColor" /> | |
80 | + <!-- 绘制内容相应的提示语 --> | |
81 | + <attr name="hint" /> | |
82 | + <attr name="hintSize" /> | |
83 | + <attr name="hintColor" /> | |
84 | + <!-- 圆弧的宽度 --> | |
85 | + <attr name="arcWidth" /> | |
86 | + <!-- 刻度的宽度 --> | |
87 | + <attr name="dialWidth" format="dimension|reference" /> | |
88 | + <!-- 刻度之间的间隔 --> | |
89 | + <attr name="dialIntervalDegree" format="integer" /> | |
90 | + <!-- 圆弧颜色, --> | |
91 | + <attr name="arcColors" /> | |
92 | + <!-- 背景圆弧线颜色 --> | |
93 | + <attr name="bgArcColor" /> | |
94 | + <!-- 刻度线颜色 --> | |
95 | + <attr name="dialColor" format="color|reference" /> | |
96 | + </declare-styleable> | |
97 | + | |
98 | + <declare-styleable name="WaveProgress"> | |
99 | + <!-- 是否开启抗锯齿 --> | |
100 | + <attr name="antiAlias" /> | |
101 | + <!-- 深色水波动画时间 --> | |
102 | + <attr name="darkWaveAnimTime" format="integer" /> | |
103 | + <!-- 浅色水波动画时间 --> | |
104 | + <attr name="lightWaveAnimTime" format="integer" /> | |
105 | + <!-- 最大值 --> | |
106 | + <attr name="maxValue" /> | |
107 | + <!-- 当前值 --> | |
108 | + <attr name="value" /> | |
109 | + <attr name="valueColor" /> | |
110 | + <attr name="valueSize" /> | |
111 | + <!-- 绘制内容相应的提示语 --> | |
112 | + <attr name="hint" /> | |
113 | + <attr name="hintSize" /> | |
114 | + <attr name="hintColor" /> | |
115 | + <!-- 圆环宽度 --> | |
116 | + <attr name="circleWidth" format="dimension" /> | |
117 | + <!-- 圆环颜色 --> | |
118 | + <attr name="circleColor" format="color|reference" /> | |
119 | + <!-- 背景圆环颜色 --> | |
120 | + <attr name="bgCircleColor" format="color|reference" /> | |
121 | + <!-- 锁定水波不随圆环进度改变,默认锁定在50%处 --> | |
122 | + <attr name="lockWave" format="boolean" /> | |
123 | + <!-- 水波数量 --> | |
124 | + <attr name="waveNum" format="integer" /> | |
125 | + <!-- 水波高度,峰值和谷值之和 --> | |
126 | + <attr name="waveHeight" format="dimension" /> | |
127 | + <!-- 深色水波颜色 --> | |
128 | + <attr name="darkWaveColor" format="color|reference" /> | |
129 | + <!-- 是否显示浅色水波 --> | |
130 | + <attr name="showLightWave" format="boolean" /> | |
131 | + <!-- 浅色水波颜色 --> | |
132 | + <attr name="lightWaveColor" format="color|reference" /> | |
133 | + <!-- 浅色水波的方向 --> | |
134 | + <attr name="lightWaveDirect" format="enum"> | |
135 | + <enum name="L2R" value="0" /> | |
136 | + <enum name="R2L" value="1" /> | |
137 | + </attr> | |
138 | + </declare-styleable> | |
139 | +</resources> | |
0 | 140 | \ No newline at end of file | ... | ... |