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