Commit c694ab53aacd2776649e37019ef596f067822f87

Authored by shixianjie
1 parent ea57c8d609
Exists in master

周报详情展示

Showing 41 changed files with 4343 additions and 2 deletions   Show diff stats
1 apply plugin: 'com.android.application' 1 apply plugin: 'com.android.application'
2 apply from: '../config.gradle' 2 apply from: '../config.gradle'
3 3
4 4
5 def androidId = rootProject.ext.androidId 5 def androidId = rootProject.ext.androidId
6 def support = rootProject.ext.dependencies 6 def support = rootProject.ext.dependencies
7 def url = rootProject.ext.url 7 def url = rootProject.ext.url
8 8
9 9
10 android { 10 android {
11 signingConfigs { 11 signingConfigs {
12 12
13 config { 13 config {
14 keyAlias 'alias' 14 keyAlias 'alias'
15 keyPassword '123456' 15 keyPassword '123456'
16 storeFile file('key.jks') 16 storeFile file('key.jks')
17 storePassword '123456' 17 storePassword '123456'
18 } 18 }
19 debug { 19 debug {
20 } 20 }
21 } 21 }
22 compileSdk 32 22 compileSdk 32
23 23
24 defaultConfig { 24 defaultConfig {
25 applicationId "com.hjx.parent" 25 applicationId "com.hjx.parent"
26 minSdk 24 26 minSdk 26
27 targetSdk 32 27 targetSdk 32
28 versionCode 1005 28 versionCode 1005
29 versionName "1.0.0.5" 29 versionName "1.0.0.5"
30 30
31 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 31 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
32 } 32 }
33 33
34 android.applicationVariants.all { 34 android.applicationVariants.all {
35 variant -> 35 variant ->
36 variant.outputs.all { 36 variant.outputs.all {
37 //在这里修改apk文件名 37 //在这里修改apk文件名
38 outputFileName = "parent-${variant.name}-v${variant.versionName}.apk" 38 outputFileName = "parent-${variant.name}-v${variant.versionName}.apk"
39 } 39 }
40 } 40 }
41 buildTypes { 41 buildTypes {
42 debug { 42 debug {
43 debuggable true 43 debuggable true
44 minifyEnabled false 44 minifyEnabled false
45 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 45 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
46 signingConfig signingConfigs.config 46 signingConfig signingConfigs.config
47 } 47 }
48 release { 48 release {
49 debuggable true 49 debuggable true
50 minifyEnabled false 50 minifyEnabled false
51 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 51 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
52 signingConfig signingConfigs.config 52 signingConfig signingConfigs.config
53 } 53 }
54 } 54 }
55 lintOptions { 55 lintOptions {
56 checkReleaseBuilds false 56 checkReleaseBuilds false
57 abortOnError false 57 abortOnError false
58 } 58 }
59 buildFeatures { 59 buildFeatures {
60 viewBinding true 60 viewBinding true
61 dataBinding true 61 dataBinding true
62 } 62 }
63 compileOptions { 63 compileOptions {
64 sourceCompatibility JavaVersion.VERSION_1_8 64 sourceCompatibility JavaVersion.VERSION_1_8
65 targetCompatibility JavaVersion.VERSION_1_8 65 targetCompatibility JavaVersion.VERSION_1_8
66 } 66 }
67 } 67 }
68 68
69 dependencies { 69 dependencies {
70 support.each { k, v -> implementation v } 70 support.each { k, v -> implementation v }
71 api project(path: ':libs:common') 71 api project(path: ':libs:common')
72 implementation 'androidx.appcompat:appcompat:1.5.1' 72 implementation 'androidx.appcompat:appcompat:1.5.1'
73 implementation 'com.google.android.material:material:1.6.1' 73 implementation 'com.google.android.material:material:1.6.1'
74 implementation 'androidx.constraintlayout:constraintlayout:2.1.4' 74 implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
75 implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50' 75 implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50'
76 implementation 'com.github.ForgetAll:LoadingDialog:1.1.2' 76 implementation 'com.github.ForgetAll:LoadingDialog:1.1.2'
77 implementation 'com.github.DL-ZhangTeng:ImagePicker:1.5.0' 77 implementation 'com.github.DL-ZhangTeng:ImagePicker:1.5.0'
78 //使用的三方 78 //使用的三方
79 implementation 'com.yalantis:ucrop:2.2.0' 79 implementation 'com.yalantis:ucrop:2.2.0'
80 implementation 'com.github.DL-ZhangTeng:RequestPermission:1.3.0' 80 implementation 'com.github.DL-ZhangTeng:RequestPermission:1.3.0'
81 implementation 'com.github.DL-ZhangTeng:Utils:2.2.0' 81 implementation 'com.github.DL-ZhangTeng:Utils:2.2.0'
82 82
83 // rx 83 // rx
84 implementation("com.trello.rxlifecycle2:rxlifecycle:2.2.2") 84 implementation("com.trello.rxlifecycle2:rxlifecycle:2.2.2")
85 implementation("com.trello.rxlifecycle2:rxlifecycle-android:2.2.2") 85 implementation("com.trello.rxlifecycle2:rxlifecycle-android:2.2.2")
86 86
87 implementation("com.github.PhilJay:MPAndroidChart:v3.1.0") 87 implementation("com.github.PhilJay:MPAndroidChart:v3.1.0")
88 implementation("com.contrarywind:Android-PickerView:4.1.9") 88 implementation("com.contrarywind:Android-PickerView:4.1.9")
89 89
90 implementation 'com.google.android:flexbox:1.0.0' 90 implementation 'com.google.android:flexbox:1.0.0'
91 } 91 }
app/src/main/AndroidManifest.xml
1 <?xml version="1.0" encoding="utf-8"?> 1 <?xml version="1.0" encoding="utf-8"?>
2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:tools="http://schemas.android.com/tools" 3 xmlns:tools="http://schemas.android.com/tools"
4 package="com.hjx.parent"> 4 package="com.hjx.parent">
5 5
6 6
7 <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> 7 <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
8 <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <!-- 允许程序改变网络链接状态 --> 8 <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <!-- 允许程序改变网络链接状态 -->
9 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- 允许程序访问访问WIFI网络状态信息 --> 9 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- 允许程序访问访问WIFI网络状态信息 -->
10 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!-- 允许程序改变WIFI链接状态 --> 10 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!-- 允许程序改变WIFI链接状态 -->
11 <!-- 6.0系统需要添加权限才能获得wifi列表 --> 11 <!-- 6.0系统需要添加权限才能获得wifi列表 -->
12 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 12 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
13 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 13 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
14 <uses-permission android:name="android.permission.INTERNET" /> 14 <uses-permission android:name="android.permission.INTERNET" />
15 <uses-permission android:name="android.permission.RECORD_AUDIO" /> 15 <uses-permission android:name="android.permission.RECORD_AUDIO" />
16 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 16 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
17 17
18 <uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> 18 <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
19 <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 19 <uses-permission android:name="android.permission.READ_PHONE_STATE" />
20 <uses-permission android:name="android.permission.WAKE_LOCK" /> 20 <uses-permission android:name="android.permission.WAKE_LOCK" />
21 <uses-permission android:name="android.permission.CAMERA" /> 21 <uses-permission android:name="android.permission.CAMERA" />
22 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> 22 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
23 <uses-permission android:name="android.permission.VIBRATE" /> 23 <uses-permission android:name="android.permission.VIBRATE" />
24 <uses-permission 24 <uses-permission
25 android:name="android.permission.WRITE_EXTERNAL_STORAGE" 25 android:name="android.permission.WRITE_EXTERNAL_STORAGE"
26 tools:ignore="ScopedStorage" /> 26 tools:ignore="ScopedStorage" />
27 <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> 27 <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
28 <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" /> 28 <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
29 29
30 <uses-permission 30 <uses-permission
31 android:name="android.permission.MANAGE_EXTERNAL_STORAGE" 31 android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
32 tools:ignore="ScopedStorage" /> 32 tools:ignore="ScopedStorage" />
33 33
34 <application 34 <application
35 android:name=".App" 35 android:name=".App"
36 android:allowBackup="true" 36 android:allowBackup="true"
37 android:icon="@mipmap/icon" 37 android:icon="@mipmap/icon"
38 android:label="@string/app_name" 38 android:label="@string/app_name"
39 android:networkSecurityConfig="@xml/network_security_config" 39 android:networkSecurityConfig="@xml/network_security_config"
40 android:supportsRtl="true" 40 android:supportsRtl="true"
41 android:theme="@style/Theme.AppCompat.Light.NoActionBar"> 41 android:theme="@style/Theme.AppCompat.Light.NoActionBar">
42 <activity 42 <activity
43 android:name=".LoginActivity" 43 android:name=".LoginActivity"
44 android:exported="true" 44 android:exported="true"
45 android:screenOrientation="portrait" 45 android:screenOrientation="portrait"
46 android:theme="@style/ThemeSplash"> 46 android:theme="@style/ThemeSplash">
47 <intent-filter> 47 <intent-filter>
48 <action android:name="android.intent.action.MAIN" /> 48 <action android:name="android.intent.action.MAIN" />
49 <category android:name="android.intent.category.LAUNCHER" /> 49 <category android:name="android.intent.category.LAUNCHER" />
50 </intent-filter> 50 </intent-filter>
51 </activity> 51 </activity>
52 <activity 52 <activity
53 android:name=".MainActivity" 53 android:name=".MainActivity"
54 android:launchMode="singleTask" 54 android:launchMode="singleTask"
55 android:screenOrientation="portrait" 55 android:screenOrientation="portrait"
56 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 56 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
57 <activity 57 <activity
58 android:name=".RegisterActivity" 58 android:name=".RegisterActivity"
59 android:screenOrientation="portrait" 59 android:screenOrientation="portrait"
60 android:theme="@style/ThemeSplash" /> 60 android:theme="@style/ThemeSplash" />
61 <activity 61 <activity
62 android:name=".UserActivity" 62 android:name=".UserActivity"
63 android:screenOrientation="portrait" 63 android:screenOrientation="portrait"
64 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 64 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
65 <activity 65 <activity
66 android:name=".YinsiActivity" 66 android:name=".YinsiActivity"
67 android:screenOrientation="portrait" 67 android:screenOrientation="portrait"
68 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 68 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
69 <activity 69 <activity
70 android:name=".QRActivity" 70 android:name=".QRActivity"
71 android:screenOrientation="portrait" 71 android:screenOrientation="portrait"
72 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 72 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
73 <activity 73 <activity
74 android:name=".AddStudentActivity" 74 android:name=".AddStudentActivity"
75 android:screenOrientation="portrait" 75 android:screenOrientation="portrait"
76 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 76 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
77 <activity 77 <activity
78 android:name=".NickActivity" 78 android:name=".NickActivity"
79 android:screenOrientation="portrait" 79 android:screenOrientation="portrait"
80 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 80 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
81 <activity 81 <activity
82 android:name=".SexActivity" 82 android:name=".SexActivity"
83 android:screenOrientation="portrait" 83 android:screenOrientation="portrait"
84 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 84 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
85 <activity 85 <activity
86 android:name=".NianActivity" 86 android:name=".NianActivity"
87 android:screenOrientation="portrait" 87 android:screenOrientation="portrait"
88 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 88 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
89 <activity 89 <activity
90 android:name=".ShenActivity" 90 android:name=".ShenActivity"
91 android:screenOrientation="portrait" 91 android:screenOrientation="portrait"
92 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 92 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
93 <activity 93 <activity
94 android:name=".UserAgreementActivity" 94 android:name=".UserAgreementActivity"
95 android:screenOrientation="portrait" 95 android:screenOrientation="portrait"
96 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 96 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
97 <activity 97 <activity
98 android:name=".AccountActivity" 98 android:name=".AccountActivity"
99 android:screenOrientation="portrait" 99 android:screenOrientation="portrait"
100 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 100 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
101 101
102 <activity 102 <activity
103 android:name=".ChangePwdActivity" 103 android:name=".ChangePwdActivity"
104 android:screenOrientation="portrait" 104 android:screenOrientation="portrait"
105 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 105 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
106 <activity 106 <activity
107 android:name=".EditStudentActivity" 107 android:name=".EditStudentActivity"
108 android:screenOrientation="portrait" 108 android:screenOrientation="portrait"
109 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 109 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
110 <activity 110 <activity
111 android:name=".ChooseActivity" 111 android:name=".ChooseActivity"
112 android:screenOrientation="portrait" 112 android:screenOrientation="portrait"
113 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 113 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
114 <activity 114 <activity
115 android:name=".AddTeacherActivity" 115 android:name=".AddTeacherActivity"
116 android:screenOrientation="portrait" 116 android:screenOrientation="portrait"
117 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 117 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
118 <activity 118 <activity
119 android:name=".ErrorBookActivity" 119 android:name=".ErrorBookActivity"
120 android:screenOrientation="portrait" 120 android:screenOrientation="portrait"
121 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 121 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
122 <activity 122 <activity
123 android:name=".ImageActivity" 123 android:name=".ImageActivity"
124 android:screenOrientation="portrait" 124 android:screenOrientation="portrait"
125 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 125 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
126 <activity 126 <activity
127 android:name=".ImageEditActivity" 127 android:name=".ImageEditActivity"
128 android:screenOrientation="portrait" 128 android:screenOrientation="portrait"
129 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 129 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
130 <activity 130 <activity
131 android:name=".ImageSelectActivity" 131 android:name=".ImageSelectActivity"
132 android:screenOrientation="portrait" 132 android:screenOrientation="portrait"
133 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 133 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
134 <activity 134 <activity
135 android:name=".AddSuccessActivity" 135 android:name=".AddSuccessActivity"
136 android:screenOrientation="portrait" 136 android:screenOrientation="portrait"
137 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 137 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
138 <activity 138 <activity
139 android:name=".ErrorListActivity" 139 android:name=".ErrorListActivity"
140 android:screenOrientation="portrait" 140 android:screenOrientation="portrait"
141 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 141 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
142 <activity 142 <activity
143 android:name=".ErrorDetailActivity" 143 android:name=".ErrorDetailActivity"
144 android:screenOrientation="portrait" 144 android:screenOrientation="portrait"
145 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 145 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
146 <activity 146 <activity
147 android:name=".TeacherChooseActivity" 147 android:name=".TeacherChooseActivity"
148 android:screenOrientation="portrait" 148 android:screenOrientation="portrait"
149 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 149 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
150 <activity 150 <activity
151 android:name=".TeacherMainActivity" 151 android:name=".TeacherMainActivity"
152 android:screenOrientation="portrait" 152 android:screenOrientation="portrait"
153 android:theme="@style/Theme.AppCompat.Light.NoActionBar" /> 153 android:theme="@style/Theme.AppCompat.Light.NoActionBar" />
154 <activity android:name=".StuHomeworkActivity" /> 154 <activity android:name=".StuHomeworkActivity" />
155 <activity android:name=".HomeworkDetailActivity" /> 155 <activity android:name=".HomeworkDetailActivity" />
156 <activity android:name=".HomeworkSelectActivity" /> 156 <activity android:name=".HomeworkSelectActivity" />
157 <activity android:name=".HomeworkFeedbackActivity" /> 157 <activity android:name=".HomeworkFeedbackActivity" />
158 <activity android:name=".HomeworkTopicActivity" /> 158 <activity android:name=".HomeworkTopicActivity" />
159 <activity android:name=".HomeworkShareActivity" /> 159 <activity android:name=".HomeworkShareActivity" />
160 <activity android:name=".HuyouDetailActivity" />
160 161
161 <provider 162 <provider
162 android:name="androidx.core.content.FileProvider" 163 android:name="androidx.core.content.FileProvider"
163 android:authorities="com.hjx.parent.fileprovider" 164 android:authorities="com.hjx.parent.fileprovider"
164 android:exported="false" 165 android:exported="false"
165 android:grantUriPermissions="true" 166 android:grantUriPermissions="true"
166 tools:replace="android:authorities"> 167 tools:replace="android:authorities">
167 <meta-data 168 <meta-data
168 android:name="android.support.FILE_PROVIDER_PATHS" 169 android:name="android.support.FILE_PROVIDER_PATHS"
169 android:resource="@xml/file_provider_paths" 170 android:resource="@xml/file_provider_paths"
170 tools:replace="android:resource" /> 171 tools:replace="android:resource" />
171 </provider> 172 </provider>
172 </application> 173 </application>
173 174
174 </manifest> 175 </manifest>
app/src/main/java/com/hjx/parent/HuyouDetailActivity.java
File was created 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 = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
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 }
422
app/src/main/java/com/hjx/parent/StuHomeworkActivity.java
1 package com.hjx.parent; 1 package com.hjx.parent;
2 2
3 import android.annotation.SuppressLint; 3 import android.annotation.SuppressLint;
4 import android.content.Intent; 4 import android.content.Intent;
5 import android.os.Bundle; 5 import android.os.Bundle;
6 import android.view.Gravity; 6 import android.view.Gravity;
7 import android.view.View; 7 import android.view.View;
8 import android.widget.ImageView; 8 import android.widget.ImageView;
9 import android.widget.LinearLayout; 9 import android.widget.LinearLayout;
10 import android.widget.PopupMenu; 10 import android.widget.PopupMenu;
11 import android.widget.PopupWindow; 11 import android.widget.PopupWindow;
12 import android.widget.TextView; 12 import android.widget.TextView;
13 13
14 import androidx.annotation.NonNull; 14 import androidx.annotation.NonNull;
15 import androidx.annotation.Nullable; 15 import androidx.annotation.Nullable;
16 import androidx.lifecycle.MutableLiveData; 16 import androidx.lifecycle.MutableLiveData;
17 17
18 import com.chad.library.adapter.base.BaseQuickAdapter; 18 import com.chad.library.adapter.base.BaseQuickAdapter;
19 import com.chad.library.adapter.base.BaseViewHolder; 19 import com.chad.library.adapter.base.BaseViewHolder;
20 import com.google.android.material.tabs.TabLayout; 20 import com.google.android.material.tabs.TabLayout;
21 import com.google.gson.Gson; 21 import com.google.gson.Gson;
22 import com.hjx.parent.adapter.HomeworkListAdapter; 22 import com.hjx.parent.adapter.HomeworkListAdapter;
23 import com.hjx.parent.databinding.ActivityStudentHomeworkBinding; 23 import com.hjx.parent.databinding.ActivityStudentHomeworkBinding;
24 import com.hjx.parent.databinding.PopupFilterFeedbackBinding; 24 import com.hjx.parent.databinding.PopupFilterFeedbackBinding;
25 import com.hjx.parent.databinding.PopupFilterGradeBinding; 25 import com.hjx.parent.databinding.PopupFilterGradeBinding;
26 import com.hjx.parent.databinding.PopupFilterSubjectBinding; 26 import com.hjx.parent.databinding.PopupFilterSubjectBinding;
27 import com.hjx.parent.databinding.PopupFilterTermBinding; 27 import com.hjx.parent.databinding.PopupFilterTermBinding;
28 import com.hjx.parent.dialog.MsgConfirmDialog; 28 import com.hjx.parent.dialog.MsgConfirmDialog;
29 import com.hjx.parent.dialog.StageHuyouDialog; 29 import com.hjx.parent.dialog.StageHuyouDialog;
30 import com.hjx.parent.function.Function1; 30 import com.hjx.parent.function.Function1;
31 import com.hjx.parent.rx.BaseRxActivity; 31 import com.hjx.parent.rx.BaseRxActivity;
32 import com.prws.common.bean.ResponseResult; 32 import com.prws.common.bean.ResponseResult;
33 import com.prws.common.bean.Student; 33 import com.prws.common.bean.Student;
34 import com.prws.common.bean.homework.HomeworkList; 34 import com.prws.common.bean.homework.HomeworkList;
35 import com.prws.common.bean.homework.StDetail; 35 import com.prws.common.bean.homework.StDetail;
36 import com.prws.common.net.NetWorks; 36 import com.prws.common.net.NetWorks;
37 import com.prws.common.utils.SharedPreferencesUtil; 37 import com.prws.common.utils.SharedPreferencesUtil;
38 import com.trello.rxlifecycle2.android.RxLifecycleAndroid; 38 import com.trello.rxlifecycle2.android.RxLifecycleAndroid;
39 39
40 import java.text.DecimalFormat; 40 import java.text.DecimalFormat;
41 import java.text.SimpleDateFormat; 41 import java.text.SimpleDateFormat;
42 import java.util.ArrayList; 42 import java.util.ArrayList;
43 import java.util.Calendar; 43 import java.util.Calendar;
44 import java.util.Collections; 44 import java.util.Collections;
45 import java.util.Date; 45 import java.util.Date;
46 import java.util.HashMap; 46 import java.util.HashMap;
47 import java.util.List; 47 import java.util.List;
48 import java.util.Locale; 48 import java.util.Locale;
49 import java.util.Map; 49 import java.util.Map;
50 50
51 import io.reactivex.Observable; 51 import io.reactivex.Observable;
52 import io.reactivex.android.schedulers.AndroidSchedulers; 52 import io.reactivex.android.schedulers.AndroidSchedulers;
53 import io.reactivex.schedulers.Schedulers; 53 import io.reactivex.schedulers.Schedulers;
54 54
55 public class StuHomeworkActivity extends BaseRxActivity<ActivityStudentHomeworkBinding> { 55 public class StuHomeworkActivity extends BaseRxActivity<ActivityStudentHomeworkBinding> {
56 56
57 private final HomeworkListAdapter homeworkAdapter = new HomeworkListAdapter(); 57 private final HomeworkListAdapter homeworkAdapter = new HomeworkListAdapter();
58 58
59 private final List<StDetail> mWeekList = new ArrayList<>(); 59 private final List<StDetail> mWeekList = new ArrayList<>();
60 private final List<StDetail> mStageList = new ArrayList<>(); 60 private final List<StDetail> mStageList = new ArrayList<>();
61 private final HuyouAdapter weekAdapter = new HuyouAdapter(mWeekList); 61 private final HuyouAdapter weekAdapter = new HuyouAdapter(mWeekList);
62 private final HuyouAdapter stageAdapter = new HuyouAdapter(mStageList); 62 private final HuyouAdapter stageAdapter = new HuyouAdapter(mStageList);
63 63
64 PopupWindow subjectFilter, gradeFilter, termFilter, feedbackFilter; 64 PopupWindow subjectFilter, gradeFilter, termFilter, feedbackFilter;
65 MsgConfirmDialog deleteDialog; 65 MsgConfirmDialog deleteDialog;
66 StageHuyouDialog stageHuyouDialog; 66 StageHuyouDialog stageHuyouDialog;
67 State state = new State(); 67 State state = new State();
68 68
69 private void handlerIntent() { 69 private void handlerIntent() {
70 String json = getIntent().getStringExtra("studentJson"); 70 String json = getIntent().getStringExtra("studentJson");
71 if (json == null) json = (String) SharedPreferencesUtil.getData("student", ""); 71 if (json == null) json = (String) SharedPreferencesUtil.getData("student", "");
72 try { state.student = new Gson().fromJson(json, Student.class); } 72 try { state.student = new Gson().fromJson(json, Student.class); }
73 catch (Throwable t) { t.printStackTrace(); } 73 catch (Throwable t) { t.printStackTrace(); }
74 } 74 }
75 75
76 @SuppressLint("SetTextI18n") 76 @SuppressLint("SetTextI18n")
77 @Override 77 @Override
78 public void initView(Bundle savedInstanceState) { 78 public void initView(Bundle savedInstanceState) {
79 handlerIntent(); 79 handlerIntent();
80 if (state.student == null) { 80 if (state.student == null) {
81 finish(); 81 finish();
82 return; 82 return;
83 } 83 }
84 binding.toolbar.setNavigationOnClickListener(v -> onBackPressed()); 84 binding.toolbar.setNavigationOnClickListener(v -> onBackPressed());
85 binding.tvTitle.setText(state.student.stuName + "的全部作业"); 85 binding.tvTitle.setText(state.student.stuName + "的全部作业");
86 setupTab(); 86 setupTab();
87 binding.recyclerView.setAdapter(homeworkAdapter); 87 binding.recyclerView.setAdapter(homeworkAdapter);
88 88
89 binding.ftSubject.setOnClickListener(v -> showSubjectFilter()); 89 binding.ftSubject.setOnClickListener(v -> showSubjectFilter());
90 binding.ftGrade.setOnClickListener(v -> showGradeFilter()); 90 binding.ftGrade.setOnClickListener(v -> showGradeFilter());
91 binding.ftTerm.setOnClickListener(v -> showTermFilter()); 91 binding.ftTerm.setOnClickListener(v -> showTermFilter());
92 binding.ftFeedback.setOnClickListener(v -> showFeedbackFilter()); 92 binding.ftFeedback.setOnClickListener(v -> showFeedbackFilter());
93 homeworkAdapter.deleteCall = data -> { 93 homeworkAdapter.deleteCall = data -> {
94 if (deleteDialog == null) { 94 if (deleteDialog == null) {
95 deleteDialog = new MsgConfirmDialog.Builder(this) 95 deleteDialog = new MsgConfirmDialog.Builder(this)
96 .setMessage("确认要删除吗?一旦删除不可恢复") 96 .setMessage("确认要删除吗?一旦删除不可恢复")
97 .setPositive("暂不删除") 97 .setPositive("暂不删除")
98 .setNegative("确定删除") 98 .setNegative("确定删除")
99 .build(); 99 .build();
100 } 100 }
101 deleteDialog.show(() -> { 101 deleteDialog.show(() -> {
102 deleteHomework(data); 102 deleteHomework(data);
103 return true; 103 return true;
104 }, null); 104 }, null);
105 }; 105 };
106 homeworkAdapter.detailCall = data -> { 106 homeworkAdapter.detailCall = data -> {
107 if (data.getRight() == null) { 107 if (data.getRight() == null) {
108 Intent intent = new Intent(this, HomeworkDetailActivity.class); 108 Intent intent = new Intent(this, HomeworkDetailActivity.class);
109 intent.putExtra("data", data); 109 intent.putExtra("data", data);
110 intent.putExtra("student", state.student); 110 intent.putExtra("student", state.student);
111 startActivity(intent); 111 startActivity(intent);
112 } else { 112 } else {
113 Intent intent = new Intent(this, HomeworkShareActivity.class); 113 Intent intent = new Intent(this, HomeworkShareActivity.class);
114 intent.putExtra("student", state.student); 114 intent.putExtra("student", state.student);
115 intent.putExtra("id", data.getId()); 115 intent.putExtra("id", data.getId());
116 intent.putExtra("grade", data.getGrade()); 116 intent.putExtra("grade", data.getGrade());
117 intent.putExtra("subject", data.getSubject()); 117 intent.putExtra("subject", data.getSubject());
118 startActivity(intent); 118 startActivity(intent);
119 } 119 }
120 }; 120 };
121 121
122 binding.btnChangeStudent.setOnClickListener(v -> { 122 binding.btnChangeStudent.setOnClickListener(v -> {
123 Intent intent = new Intent(this, TeacherChooseActivity.class); 123 Intent intent = new Intent(this, TeacherChooseActivity.class);
124 intent.putExtra("needBack", true); 124 intent.putExtra("needBack", true);
125 startActivityForResult(intent, 0xA01); 125 startActivityForResult(intent, 0xA01);
126 }); 126 });
127 127
128 binding.btnGeneralHuyou.setOnClickListener(v -> generalWeek()); 128 binding.btnGeneralHuyou.setOnClickListener(v -> generalWeek());
129 binding.btnStageHuyou.setOnClickListener(v -> { 129 binding.btnStageHuyou.setOnClickListener(v -> {
130 if (stageHuyouDialog == null) stageHuyouDialog = new StageHuyouDialog(this); 130 if (stageHuyouDialog == null) stageHuyouDialog = new StageHuyouDialog(this);
131 stageHuyouDialog.show(this::generalStage); 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 getWeekHuyou(); 137 getWeekHuyou();
135 getStageHuyou(); 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 @Override 149 @Override
139 protected void onStart() { 150 protected void onStart() {
140 super.onStart(); 151 super.onStart();
141 getHomework(); 152 getHomework();
142 } 153 }
143 154
144 @SuppressLint("SetTextI18n") 155 @SuppressLint("SetTextI18n")
145 @Override 156 @Override
146 protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { 157 protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
147 super.onActivityResult(requestCode, resultCode, data); 158 super.onActivityResult(requestCode, resultCode, data);
148 if (requestCode == 0xA01 && resultCode == RESULT_OK) { 159 if (requestCode == 0xA01 && resultCode == RESULT_OK) {
149 String json = (String) SharedPreferencesUtil.getData("student", ""); 160 String json = (String) SharedPreferencesUtil.getData("student", "");
150 try { 161 try {
151 state.student = new Gson().fromJson(json, Student.class); 162 state.student = new Gson().fromJson(json, Student.class);
152 binding.tvTitle.setText(state.student.stuName + "的全部作业"); 163 binding.tvTitle.setText(state.student.stuName + "的全部作业");
153 getHomework(); 164 getHomework();
154 getWeekHuyou(); 165 getWeekHuyou();
155 getStageHuyou(); 166 getStageHuyou();
156 } 167 }
157 catch (Throwable t) { t.printStackTrace(); } 168 catch (Throwable t) { t.printStackTrace(); }
158 } 169 }
159 } 170 }
160 171
161 private void setupTab() { 172 private void setupTab() {
162 binding.tabLayout.addTab(binding.tabLayout.newTab().setText("每日作业")); 173 binding.tabLayout.addTab(binding.tabLayout.newTab().setText("每日作业"));
163 binding.tabLayout.addTab(binding.tabLayout.newTab().setText("每周总结")); 174 binding.tabLayout.addTab(binding.tabLayout.newTab().setText("每周总结"));
164 binding.tabLayout.addTab(binding.tabLayout.newTab().setText("阶段性总结")); 175 binding.tabLayout.addTab(binding.tabLayout.newTab().setText("阶段性总结"));
165 binding.tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { 176 binding.tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
166 @Override 177 @Override
167 public void onTabSelected(TabLayout.Tab tab) { 178 public void onTabSelected(TabLayout.Tab tab) {
168 binding.filterBar.setVisibility(View.GONE); 179 binding.filterBar.setVisibility(View.GONE);
169 binding.weekBar.setVisibility(View.GONE); 180 binding.weekBar.setVisibility(View.GONE);
170 binding.stageBar.setVisibility(View.GONE); 181 binding.stageBar.setVisibility(View.GONE);
171 if (tab.getPosition() == 0) { //每日 182 if (tab.getPosition() == 0) { //每日
172 binding.filterBar.setVisibility(View.VISIBLE); 183 binding.filterBar.setVisibility(View.VISIBLE);
173 binding.recyclerView.setAdapter(homeworkAdapter); 184 binding.recyclerView.setAdapter(homeworkAdapter);
174 } else if (tab.getPosition() == 1) { //每周 185 } else if (tab.getPosition() == 1) { //每周
175 binding.weekBar.setVisibility(View.VISIBLE); 186 binding.weekBar.setVisibility(View.VISIBLE);
176 binding.recyclerView.setAdapter(weekAdapter); 187 binding.recyclerView.setAdapter(weekAdapter);
177 } else if (tab.getPosition() == 2) { //阶段 188 } else if (tab.getPosition() == 2) { //阶段
178 binding.stageBar.setVisibility(View.VISIBLE); 189 binding.stageBar.setVisibility(View.VISIBLE);
179 binding.recyclerView.setAdapter(stageAdapter); 190 binding.recyclerView.setAdapter(stageAdapter);
180 } 191 }
181 } 192 }
182 @Override 193 @Override
183 public void onTabUnselected(TabLayout.Tab tab) { 194 public void onTabUnselected(TabLayout.Tab tab) {
184 } 195 }
185 @Override 196 @Override
186 public void onTabReselected(TabLayout.Tab tab) { 197 public void onTabReselected(TabLayout.Tab tab) {
187 } 198 }
188 }); 199 });
189 } 200 }
190 201
191 @SuppressLint("CheckResult") 202 @SuppressLint("CheckResult")
192 protected void deleteHomework(HomeworkList data) { 203 protected void deleteHomework(HomeworkList data) {
193 NetWorks.service_url.deleteHomework(NetWorks.getHeader(), data.getId()) 204 NetWorks.service_url.deleteHomework(NetWorks.getHeader(), data.getId())
194 .subscribeOn(Schedulers.io()) 205 .subscribeOn(Schedulers.io())
195 .observeOn(AndroidSchedulers.mainThread()) 206 .observeOn(AndroidSchedulers.mainThread())
196 .compose(RxLifecycleAndroid.bindActivity(getRxLifecycle())) 207 .compose(RxLifecycleAndroid.bindActivity(getRxLifecycle()))
197 .subscribe((response, th) -> { 208 .subscribe((response, th) -> {
198 if (th != null) th.printStackTrace(); 209 if (th != null) th.printStackTrace();
199 if (response != null && response.getSuccess()) { 210 if (response != null && response.getSuccess()) {
200 getHomework(); 211 getHomework();
201 } 212 }
202 }); 213 });
203 214
204 } 215 }
205 216
206 @SuppressLint("CheckResult") 217 @SuppressLint("CheckResult")
207 protected void getHomework() { 218 protected void getHomework() {
208 NetWorks.service_url.getStudentHomework(NetWorks.getHeader(), state.student.stuId) 219 NetWorks.service_url.getStudentHomework(NetWorks.getHeader(), state.student.stuId)
209 .subscribeOn(Schedulers.io()) 220 .subscribeOn(Schedulers.io())
210 .observeOn(AndroidSchedulers.mainThread()) 221 .observeOn(AndroidSchedulers.mainThread())
211 .compose(RxLifecycleAndroid.bindActivity(getRxLifecycle())) 222 .compose(RxLifecycleAndroid.bindActivity(getRxLifecycle()))
212 .toObservable() 223 .toObservable()
213 .flatMap(response -> Observable.fromIterable(response.getData())) 224 .flatMap(response -> Observable.fromIterable(response.getData()))
214 // 过滤 225 // 过滤
215 .filter(data -> { // 学科 226 .filter(data -> { // 学科
216 String subject = state.subject.getValue(); 227 String subject = state.subject.getValue();
217 if (subject == null || subject.isEmpty()) return true; 228 if (subject == null || subject.isEmpty()) return true;
218 else return subject.equals(data.getSubject()); 229 else return subject.equals(data.getSubject());
219 }) 230 })
220 .filter(data -> { // 年级 231 .filter(data -> { // 年级
221 String grade = state.grade.getValue(); 232 String grade = state.grade.getValue();
222 if (grade == null || grade.isEmpty()) return true; 233 if (grade == null || grade.isEmpty()) return true;
223 else return grade.equals(data.getGrade()); 234 else return grade.equals(data.getGrade());
224 }) 235 })
225 .filter(data -> { // 学期 236 .filter(data -> { // 学期
226 String term = state.term.getValue(); 237 String term = state.term.getValue();
227 if (term == null || term.isEmpty()) return true; 238 if (term == null || term.isEmpty()) return true;
228 else return term.equals(data.getTerm()); 239 else return term.equals(data.getTerm());
229 }) 240 })
230 .filter(data -> { // 反馈 241 .filter(data -> { // 反馈
231 Integer feedback = state.feedback.getValue(); 242 Integer feedback = state.feedback.getValue();
232 if (feedback == null || feedback == 0) return true; 243 if (feedback == null || feedback == 0) return true;
233 else return (feedback == 1 && data.getRight() != null) || (feedback == 2 && data.getRight() == null); 244 else return (feedback == 1 && data.getRight() != null) || (feedback == 2 && data.getRight() == null);
234 }) 245 })
235 // 过滤完成, 收集 246 // 过滤完成, 收集
236 .toList() 247 .toList()
237 .subscribe((data, th) -> { 248 .subscribe((data, th) -> {
238 if (th != null) th.printStackTrace(); 249 if (th != null) th.printStackTrace();
239 if (data != null) { 250 if (data != null) {
240 Collections.sort(data); 251 Collections.sort(data);
241 } 252 }
242 homeworkAdapter.setNewData(data); 253 homeworkAdapter.setNewData(data);
243 }); 254 });
244 } 255 }
245 256
246 @SuppressLint({"CheckResult", "NotifyDataSetChanged"}) 257 @SuppressLint({"CheckResult", "NotifyDataSetChanged"})
247 private void getWeekHuyou() { 258 private void getWeekHuyou() {
248 NetWorks.service_url.getHuyouList(NetWorks.getHeader(), state.student.stuId, 0) 259 NetWorks.service_url.getHuyouList(NetWorks.getHeader(), state.student.stuId, 0)
249 .compose(transformSingle()) 260 .compose(transformSingle())
250 .map(ResponseResult::getData) 261 .map(ResponseResult::getData)
251 .subscribe((list, throwable) -> { 262 .subscribe((list, throwable) -> {
252 if (throwable != null) { 263 if (throwable != null) {
253 throwable.printStackTrace(); 264 throwable.printStackTrace();
254 return; 265 return;
255 } 266 }
256 if (list != null) { 267 if (list != null) {
257 mWeekList.clear(); 268 mWeekList.clear();
258 mWeekList.addAll(list); 269 mWeekList.addAll(list);
259 weekAdapter.notifyDataSetChanged(); 270 weekAdapter.notifyDataSetChanged();
260 271
261 boolean exist = false; 272 boolean exist = false;
262 int thisWeek = Calendar.getInstance().get(Calendar.WEEK_OF_YEAR); 273 int thisWeek = Calendar.getInstance().get(Calendar.WEEK_OF_YEAR);
263 for (StDetail bean: mWeekList) { 274 for (StDetail bean: mWeekList) {
264 Calendar other = Calendar.getInstance(); 275 Calendar other = Calendar.getInstance();
265 other.setTime(bean.endTime); 276 other.setTime(bean.endTime);
266 if (other.get(Calendar.WEEK_OF_YEAR) == thisWeek) { 277 if (other.get(Calendar.WEEK_OF_YEAR) == thisWeek) {
267 exist = true; 278 exist = true;
268 break; 279 break;
269 } 280 }
270 } 281 }
271 binding.btnGeneralHuyou.setVisibility(exist ? View.GONE : View.VISIBLE); 282 binding.btnGeneralHuyou.setVisibility(exist ? View.GONE : View.VISIBLE);
272 } 283 }
273 }); 284 });
274 } 285 }
275 286
276 @SuppressLint({"CheckResult", "NotifyDataSetChanged"}) 287 @SuppressLint({"CheckResult", "NotifyDataSetChanged"})
277 private void getStageHuyou() { 288 private void getStageHuyou() {
278 NetWorks.service_url.getHuyouList(NetWorks.getHeader(), state.student.stuId, 1) 289 NetWorks.service_url.getHuyouList(NetWorks.getHeader(), state.student.stuId, 1)
279 .compose(transformSingle()) 290 .compose(transformSingle())
280 .map(ResponseResult::getData) 291 .map(ResponseResult::getData)
281 .subscribe((list, throwable) -> { 292 .subscribe((list, throwable) -> {
282 if (throwable != null) { 293 if (throwable != null) {
283 throwable.printStackTrace(); 294 throwable.printStackTrace();
284 return; 295 return;
285 } 296 }
286 if (list != null) { 297 if (list != null) {
287 mStageList.clear(); 298 mStageList.clear();
288 mStageList.addAll(list); 299 mStageList.addAll(list);
289 stageAdapter.notifyDataSetChanged(); 300 stageAdapter.notifyDataSetChanged();
290 } 301 }
291 }); 302 });
292 } 303 }
293 304
294 @SuppressLint("CheckResult") 305 @SuppressLint("CheckResult")
295 private void generalWeek() { 306 private void generalWeek() {
296 showLoadingDialog("稍等..."); 307 showLoadingDialog("稍等...");
297 NetWorks.service_url.generalHuyou() 308 NetWorks.service_url.generalHuyou()
298 .compose(transformSingle()) 309 .compose(transformSingle())
299 .subscribe((response, throwable) -> { 310 .subscribe((response, throwable) -> {
300 cancelLoadingDialog(); 311 cancelLoadingDialog();
301 if (throwable != null) { 312 if (throwable != null) {
302 loadFail("失败"); 313 loadFail("失败");
303 throwable.printStackTrace(); 314 throwable.printStackTrace();
304 return; 315 return;
305 } 316 }
306 if (response != null && response.getSuccess()) { 317 if (response != null && response.getSuccess()) {
307 binding.btnGeneralHuyou.setVisibility(View.GONE); 318 binding.btnGeneralHuyou.setVisibility(View.GONE);
308 getWeekHuyou(); 319 getWeekHuyou();
309 } 320 }
310 }); 321 });
311 } 322 }
312 323
313 @SuppressLint("CheckResult") 324 @SuppressLint("CheckResult")
314 private void generalStage(Date startDate, Date endDate, String subject) { 325 private void generalStage(Date startDate, Date endDate, String subject) {
315 SimpleDateFormat format = new SimpleDateFormat("yyy-MM-dd HH:mm:ss", Locale.CHINA); 326 SimpleDateFormat format = new SimpleDateFormat("yyy-MM-dd HH:mm:ss", Locale.CHINA);
316 Map<String, Object> body = new HashMap<>(); 327 Map<String, Object> body = new HashMap<>();
317 body.put("stuId", state.student.stuId); 328 body.put("stuId", state.student.stuId);
318 body.put("startTime", format.format(startDate)); 329 body.put("startTime", format.format(startDate));
319 body.put("endTime", format.format(endDate)); 330 body.put("endTime", format.format(endDate));
320 body.put("subject", subject); 331 body.put("subject", subject);
321 showLoadingDialog("稍等..."); 332 showLoadingDialog("稍等...");
322 NetWorks.service_url.generalStageHuyou(NetWorks.getHeader(), body) 333 NetWorks.service_url.generalStageHuyou(NetWorks.getHeader(), body)
323 .subscribeOn(Schedulers.io()) 334 .subscribeOn(Schedulers.io())
324 .observeOn(AndroidSchedulers.mainThread()) 335 .observeOn(AndroidSchedulers.mainThread())
325 .compose(RxLifecycleAndroid.bindActivity(getRxLifecycle())) 336 .compose(RxLifecycleAndroid.bindActivity(getRxLifecycle()))
326 .subscribe((response, throwable) -> { 337 .subscribe((response, throwable) -> {
327 if (throwable != null) { 338 if (throwable != null) {
328 loadFail("失败"); 339 loadFail("失败");
329 throwable.printStackTrace(); 340 throwable.printStackTrace();
330 return; 341 return;
331 } 342 }
332 if (response.getSuccess()) { 343 if (response.getSuccess()) {
333 getStageHuyou(); 344 getStageHuyou();
334 cancelLoadingDialog(); 345 cancelLoadingDialog();
335 } else { 346 } else {
336 loadFail(response.getMsg()); 347 loadFail(response.getMsg());
337 } 348 }
338 }); 349 });
339 } 350 }
340 351
341 private void showSubjectFilter() { 352 private void showSubjectFilter() {
342 if (subjectFilter == null) { 353 if (subjectFilter == null) {
343 PopupFilterSubjectBinding db = PopupFilterSubjectBinding.inflate(getLayoutInflater()); 354 PopupFilterSubjectBinding db = PopupFilterSubjectBinding.inflate(getLayoutInflater());
344 db.setLifecycleOwner(this); 355 db.setLifecycleOwner(this);
345 db.setState(state); 356 db.setState(state);
346 db.bg.setOnClickListener(v -> subjectFilter.dismiss()); 357 db.bg.setOnClickListener(v -> subjectFilter.dismiss());
347 subjectFilter = new PopupWindow(db.getRoot(), LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); 358 subjectFilter = new PopupWindow(db.getRoot(), LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
348 subjectFilter.setOutsideTouchable(true); 359 subjectFilter.setOutsideTouchable(true);
349 subjectFilter.setOnDismissListener(this::getHomework); 360 subjectFilter.setOnDismissListener(this::getHomework);
350 } 361 }
351 subjectFilter.showAsDropDown(binding.anchorView); 362 subjectFilter.showAsDropDown(binding.anchorView);
352 } 363 }
353 364
354 private void showGradeFilter() { 365 private void showGradeFilter() {
355 if (gradeFilter == null) { 366 if (gradeFilter == null) {
356 PopupFilterGradeBinding db = PopupFilterGradeBinding.inflate(getLayoutInflater()); 367 PopupFilterGradeBinding db = PopupFilterGradeBinding.inflate(getLayoutInflater());
357 db.setLifecycleOwner(this); 368 db.setLifecycleOwner(this);
358 db.setState(state); 369 db.setState(state);
359 db.bg.setOnClickListener(v -> gradeFilter.dismiss()); 370 db.bg.setOnClickListener(v -> gradeFilter.dismiss());
360 gradeFilter = new PopupWindow(db.getRoot(), LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); 371 gradeFilter = new PopupWindow(db.getRoot(), LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
361 gradeFilter.setOutsideTouchable(true); 372 gradeFilter.setOutsideTouchable(true);
362 gradeFilter.setOnDismissListener(this::getHomework); 373 gradeFilter.setOnDismissListener(this::getHomework);
363 } 374 }
364 gradeFilter.showAsDropDown(binding.anchorView); 375 gradeFilter.showAsDropDown(binding.anchorView);
365 } 376 }
366 377
367 private void showTermFilter() { 378 private void showTermFilter() {
368 if (termFilter == null) { 379 if (termFilter == null) {
369 PopupFilterTermBinding db = PopupFilterTermBinding.inflate(getLayoutInflater()); 380 PopupFilterTermBinding db = PopupFilterTermBinding.inflate(getLayoutInflater());
370 db.setLifecycleOwner(this); 381 db.setLifecycleOwner(this);
371 db.setState(state); 382 db.setState(state);
372 db.bg.setOnClickListener(v -> termFilter.dismiss()); 383 db.bg.setOnClickListener(v -> termFilter.dismiss());
373 termFilter = new PopupWindow(db.getRoot(), LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); 384 termFilter = new PopupWindow(db.getRoot(), LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
374 termFilter.setOutsideTouchable(true); 385 termFilter.setOutsideTouchable(true);
375 termFilter.setOnDismissListener(this::getHomework); 386 termFilter.setOnDismissListener(this::getHomework);
376 } 387 }
377 termFilter.showAsDropDown(binding.anchorView); 388 termFilter.showAsDropDown(binding.anchorView);
378 } 389 }
379 390
380 private void showFeedbackFilter() { 391 private void showFeedbackFilter() {
381 if (feedbackFilter == null) { 392 if (feedbackFilter == null) {
382 PopupFilterFeedbackBinding db = PopupFilterFeedbackBinding.inflate(getLayoutInflater()); 393 PopupFilterFeedbackBinding db = PopupFilterFeedbackBinding.inflate(getLayoutInflater());
383 db.setLifecycleOwner(this); 394 db.setLifecycleOwner(this);
384 db.setState(state); 395 db.setState(state);
385 db.bg.setOnClickListener(v -> feedbackFilter.dismiss()); 396 db.bg.setOnClickListener(v -> feedbackFilter.dismiss());
386 feedbackFilter = new PopupWindow(db.getRoot(), LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT); 397 feedbackFilter = new PopupWindow(db.getRoot(), LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
387 feedbackFilter.setOutsideTouchable(true); 398 feedbackFilter.setOutsideTouchable(true);
388 feedbackFilter.setOnDismissListener(this::getHomework); 399 feedbackFilter.setOnDismissListener(this::getHomework);
389 } 400 }
390 feedbackFilter.showAsDropDown(binding.anchorView); 401 feedbackFilter.showAsDropDown(binding.anchorView);
391 } 402 }
392 403
393 @Override 404 @Override
394 protected ActivityStudentHomeworkBinding getViewBinding() { 405 protected ActivityStudentHomeworkBinding getViewBinding() {
395 return ActivityStudentHomeworkBinding.inflate(getLayoutInflater()); 406 return ActivityStudentHomeworkBinding.inflate(getLayoutInflater());
396 } 407 }
397 408
398 public static class State { 409 public static class State {
399 public Student student; 410 public Student student;
400 411
401 public MutableLiveData<String> subject = new MutableLiveData<>(""); 412 public MutableLiveData<String> subject = new MutableLiveData<>("");
402 public void setSubject(String value) { 413 public void setSubject(String value) {
403 subject.setValue(value); 414 subject.setValue(value);
404 } 415 }
405 416
406 public MutableLiveData<String> grade = new MutableLiveData<>(""); 417 public MutableLiveData<String> grade = new MutableLiveData<>("");
407 public void setGrade(String value) { 418 public void setGrade(String value) {
408 grade.setValue(value); 419 grade.setValue(value);
409 } 420 }
410 421
411 public MutableLiveData<String> term = new MutableLiveData<>(""); 422 public MutableLiveData<String> term = new MutableLiveData<>("");
412 public void setTerm(String value) { 423 public void setTerm(String value) {
413 term.setValue(value); 424 term.setValue(value);
414 } 425 }
415 426
416 //0:全部, 1: 已反馈, 2:未反馈 427 //0:全部, 1: 已反馈, 2:未反馈
417 public MutableLiveData<Integer> feedback = new MutableLiveData<>(0); 428 public MutableLiveData<Integer> feedback = new MutableLiveData<>(0);
418 public void setFeedback(int value) { 429 public void setFeedback(int value) {
419 feedback.setValue(value); 430 feedback.setValue(value);
420 } 431 }
421 } 432 }
422 433
423 static class HuyouAdapter extends BaseQuickAdapter<StDetail, BaseViewHolder> { 434 static class HuyouAdapter extends BaseQuickAdapter<StDetail, BaseViewHolder> {
424 public Function1<StDetail> deleteCall; 435 public Function1<StDetail> deleteCall;
436 public Function1<StDetail> detailCall;
425 public Student student; 437 public Student student;
426 438
427 public HuyouAdapter(@Nullable List<StDetail> data) { 439 public HuyouAdapter(@Nullable List<StDetail> data) {
428 super(R.layout.item_homework_list, data); 440 super(R.layout.item_homework_list, data);
429 } 441 }
430 442
431 @SuppressLint("SetTextI18n,SimpleDateFormat") 443 @SuppressLint("SetTextI18n,SimpleDateFormat")
432 @Override 444 @Override
433 protected void convert(@NonNull BaseViewHolder holder, StDetail data) { 445 protected void convert(@NonNull BaseViewHolder holder, StDetail data) {
434 holder.setGone(R.id.tvFlag, false); 446 holder.setGone(R.id.tvFlag, false);
435 int subjectImg; 447 int subjectImg;
436 switch (data.homeworkSubject) { 448 switch (data.homeworkSubject) {
437 case "语文": 449 case "语文":
438 subjectImg = R.drawable.ic_chinese; 450 subjectImg = R.drawable.ic_chinese;
439 break; 451 break;
440 case "英语": 452 case "英语":
441 subjectImg = R.drawable.ic_english; 453 subjectImg = R.drawable.ic_english;
442 break; 454 break;
443 case "物理": 455 case "物理":
444 subjectImg = R.drawable.ic_physics; 456 subjectImg = R.drawable.ic_physics;
445 break; 457 break;
446 case "化学": 458 case "化学":
447 subjectImg = R.drawable.ic_chemistry; 459 subjectImg = R.drawable.ic_chemistry;
448 break; 460 break;
449 case "数学": 461 case "数学":
450 default: 462 default:
451 subjectImg = R.drawable.ic_math; 463 subjectImg = R.drawable.ic_math;
452 } 464 }
453 holder.setImageResource(R.id.ivSubject, subjectImg); 465 holder.setImageResource(R.id.ivSubject, subjectImg);
454 Date endDate = new Date(data.endTime.getTime() - 1000); 466 Date endDate = new Date(data.endTime.getTime() - 1000);
455 String startStr = new SimpleDateFormat("yyyy.M.d").format(data.startTime); 467 String startStr = new SimpleDateFormat("yyyy.M.d").format(data.startTime);
456 String endStr = new SimpleDateFormat("-M.d").format(endDate); 468 String endStr = new SimpleDateFormat("-M.d").format(endDate);
457 String typeStr = data.type == 0 ? "作业周总结" : "作业阶段性总结"; 469 String typeStr = data.type == 0 ? "作业周总结" : "作业阶段性总结";
458 String title = startStr + endStr + data.homeworkSubject + typeStr; 470 String title = startStr + endStr + data.homeworkSubject + typeStr;
459 holder.setText(R.id.tvName, title); 471 holder.setText(R.id.tvName, title);
460 holder.setText(R.id.tvGrade, data.grade); 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 private SimpleDateFormat getFormatWithGmt8(String pattern) { 483 private SimpleDateFormat getFormatWithGmt8(String pattern) {
464 SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.CHINA); 484 SimpleDateFormat format = new SimpleDateFormat(pattern, Locale.CHINA);
465 //format.setTimeZone(TimeZone.getTimeZone("GMT+16")); 485 //format.setTimeZone(TimeZone.getTimeZone("GMT+16"));
466 return format; 486 return format;
467 } 487 }
468 } 488 }
469 489
470 } 490 }
471 491
app/src/main/res/drawable/bg_circle.xml
File was created 1 <?xml version="1.0" encoding="utf-8"?>
2 <shape xmlns:android="http://schemas.android.com/apk/res/android">
3 <corners android:radius="888dp"/>
4 </shape>
app/src/main/res/drawable/bg_huyou_a4.xml
File was created 1 <?xml version="1.0" encoding="utf-8"?>
2 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
3
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>
app/src/main/res/drawable/bg_huyou_table_bg.xml
File was created 1 <?xml version="1.0" encoding="utf-8"?>
2 <shape xmlns:android="http://schemas.android.com/apk/res/android">
3
4 <corners android:radius="10dp"/>
5 <stroke android:color="#50CEC2" android:width="1dp"/>
6
7 </shape>
app/src/main/res/drawable/bg_hy_analyse_title.xml
File was created 1 <?xml version="1.0" encoding="utf-8"?>
2 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
3
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>
app/src/main/res/drawable/bg_hy_point_title.xml
File was created 1 <?xml version="1.0" encoding="utf-8"?>
2 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
3
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>
app/src/main/res/drawable/bg_hy_summary_title.xml
File was created 1 <?xml version="1.0" encoding="utf-8"?>
2 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
3
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>
app/src/main/res/drawable/bg_hy_weak_title.xml
File was created 1 <?xml version="1.0" encoding="utf-8"?>
2 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
3
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>
app/src/main/res/drawable/bg_line_chart_fill2.xml
File was created 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>
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
File was created 1 <?xml version="1.0" encoding="utf-8"?>
2 <shape xmlns:android="http://schemas.android.com/apk/res/android">
3 <corners android:radius="2dp"/>
4 </shape>
app/src/main/res/layout/activity_huyou_detail.xml
File was created 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>
app/src/main/res/layout/activity_huyou_detail_a4.xml
File was created 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>
app/src/main/res/layout/item_huyou_point.xml
File was created 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>
1 buildscript { 1 buildscript {
2 2
3 3
4 ext { 4 ext {
5 5
6 6
7 androidId = [ 7 androidId = [
8 compileSdkVersion: 32, 8 compileSdkVersion: 32,
9 minSdkVersion : 24, 9 minSdkVersion : 26,
10 targetSdkVersion : 32, 10 targetSdkVersion : 32,
11 versionCode : 1, 11 versionCode : 1,
12 versionName : "0.0.1" 12 versionName : "0.0.1"
13 13
14 14
15 ] 15 ]
16 16
17 17
18 url = [ 18 url = [
19 server_url : "http://192.168.3.144:8088", //http 请求指令 19 server_url : "http://192.168.3.144:8088", //http 请求指令
20 server_url_online: "https://mgr.hjx.com", //http 请求指令 20 server_url_online: "https://mgr.hjx.com", //http 请求指令
21 ] 21 ]
22 22
23 23
24 dependencies = [ 24 dependencies = [
25 appcompat : 'androidx.appcompat:appcompat:1.0.0', 25 appcompat : 'androidx.appcompat:appcompat:1.0.0',
26 constraint : 'androidx.constraintlayout:constraintlayout:1.1.3', 26 constraint : 'androidx.constraintlayout:constraintlayout:1.1.3',
27 cardview : 'androidx.cardview:cardview:1.0.0', 27 cardview : 'androidx.cardview:cardview:1.0.0',
28 recyclerview : 'androidx.recyclerview:recyclerview:1.0.0', 28 recyclerview : 'androidx.recyclerview:recyclerview:1.0.0',
29 material : 'com.google.android.material:material:1.0.0', 29 material : 'com.google.android.material:material:1.0.0',
30 // 依赖RxAndroid 2X 的依赖库 30 // 依赖RxAndroid 2X 的依赖库
31 // 增加RxJava 2X 的依赖库 31 // 增加RxJava 2X 的依赖库
32 rxandroid : 'io.reactivex.rxjava2:rxandroid:2.0.1', 32 rxandroid : 'io.reactivex.rxjava2:rxandroid:2.0.1',
33 rxjava : 'io.reactivex.rxjava2:rxjava:2.0.7', 33 rxjava : 'io.reactivex.rxjava2:rxjava:2.0.7',
34 34
35 // 以下需要使用Retrofit 35 // 以下需要使用Retrofit
36 //retrofit 36 //retrofit
37 retrofit : 'com.squareup.retrofit2:retrofit:2.1.0', 37 retrofit : 'com.squareup.retrofit2:retrofit:2.1.0',
38 //Gson converter 38 //Gson converter
39 converter : 'com.squareup.retrofit2:converter-gson:2.1.0', 39 converter : 'com.squareup.retrofit2:converter-gson:2.1.0',
40 //RxJava2 Adapter 40 //RxJava2 Adapter
41 retrofit2 : 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0', 41 retrofit2 : 'com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0',
42 //okhttp 42 //okhttp
43 okhttp : 'com.squareup.okhttp3:okhttp:3.8.1', 43 okhttp : 'com.squareup.okhttp3:okhttp:3.8.1',
44 logging : 'com.squareup.okhttp3:logging-interceptor:3.4.1', 44 logging : 'com.squareup.okhttp3:logging-interceptor:3.4.1',
45 utils : 'com.github.wang-developer:AndroidUtilsDemo:1.0.6', 45 utils : 'com.github.wang-developer:AndroidUtilsDemo:1.0.6',
46 commons_lang : 'org.apache.commons:commons-lang3:3.7', 46 commons_lang : 'org.apache.commons:commons-lang3:3.7',
47 commons_compress: 'org.apache.commons:commons-compress:1.19', 47 commons_compress: 'org.apache.commons:commons-compress:1.19',
48 commons_c_lang : 'commons-lang:commons-lang:2.3', 48 commons_c_lang : 'commons-lang:commons-lang:2.3',
49 commons_codec : 'commons-codec:commons-codec:1.7', 49 commons_codec : 'commons-codec:commons-codec:1.7',
50 eventbus : 'org.greenrobot:eventbus:3.2.0', 50 eventbus : 'org.greenrobot:eventbus:3.2.0',
51 eventbus2 : 'org.simple:androideventbus:1.0.5.1', 51 eventbus2 : 'org.simple:androideventbus:1.0.5.1',
52 glide : 'com.github.bumptech.glide:glide:4.6.1', 52 glide : 'com.github.bumptech.glide:glide:4.6.1',
53 permissions : 'com.github.getActivity:XXPermissions:11.6', 53 permissions : 'com.github.getActivity:XXPermissions:11.6',
54 orcode : 'cn.yipianfengye.android:zxing-library:2.2' 54 orcode : 'cn.yipianfengye.android:zxing-library:2.2'
55 // push : 'com.umeng.sdk:push:4.1.0', 55 // push : 'com.umeng.sdk:push:4.1.0',
56 // litepal : 'org.litepal.android:java:3.0.0', 56 // litepal : 'org.litepal.android:java:3.0.0',
57 57
58 58
59 // AlivcFFmpeg : 'com.aliyun.video.android:AlivcFFmpeg:2.0.0', 59 // AlivcFFmpeg : 'com.aliyun.video.android:AlivcFFmpeg:2.0.0',
60 60
61 // 61 //
62 // basequickadapter : 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.34', 62 // basequickadapter : 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.34',
63 // SwipeDelMenuLayout: 'com.github.mcxtzhang:SwipeDelMenuLayout:V1.3.0', 63 // SwipeDelMenuLayout: 'com.github.mcxtzhang:SwipeDelMenuLayout:V1.3.0',
64 // flycoTabLayout : 'com.flyco.tablayout:FlycoTabLayout_Lib:2.1.2@aar' 64 // flycoTabLayout : 'com.flyco.tablayout:FlycoTabLayout_Lib:2.1.2@aar'
65 65
66 66
67 ] 67 ]
68 } 68 }
69 69
70 70
71 repositories { 71 repositories {
72 maven { url 'https://maven.aliyun.com/repository/gradle-plugin' } 72 maven { url 'https://maven.aliyun.com/repository/gradle-plugin' }
73 maven { url 'https://maven.aliyun.com/repository/google' } 73 maven { url 'https://maven.aliyun.com/repository/google' }
74 maven { url 'https://maven.aliyun.com/repository/central' } 74 maven { url 'https://maven.aliyun.com/repository/central' }
75 google() 75 google()
76 maven { url 'https://maven.aliyun.com/repository/jcenter' } 76 maven { url 'https://maven.aliyun.com/repository/jcenter' }
77 } 77 }
78 dependencies { 78 dependencies {
79 classpath 'com.android.tools.build:gradle:4.2.2' 79 classpath 'com.android.tools.build:gradle:4.2.2'
80 classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' 80 classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
81 classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1' 81 classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
82 classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.3' 82 classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.3'
83 classpath "com.alibaba:arouter-register:1.0.2" 83 classpath "com.alibaba:arouter-register:1.0.2"
84 // NOTE: Do not place your application dependencies here; they belong 84 // NOTE: Do not place your application dependencies here; they belong
85 // in the individual module build.gradle files 85 // in the individual module build.gradle files
86 } 86 }
87 87
88 88
89 } 89 }
90 90
91 91
92 allprojects { 92 allprojects {
93 repositories { 93 repositories {
94 maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' } 94 maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' }
95 maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' } 95 maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
96 maven { url 'https://jitpack.io' } 96 maven { url 'https://jitpack.io' }
97 google() 97 google()
98 maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter' } 98 maven { url 'http://maven.aliyun.com/nexus/content/repositories/jcenter' }
99 } 99 }
100 } 100 }
101 task clean(type: Delete) { 101 task clean(type: Delete) {
102 delete rootProject.buildDir 102 delete rootProject.buildDir
103 } 103 }
104 104
libs/common/src/main/java/com/littlejie/circleprogress/CircleProgress.java
File was created 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 }
410
libs/common/src/main/java/com/littlejie/circleprogress/DialProgress.java
File was created 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 }
344
libs/common/src/main/java/com/littlejie/circleprogress/WaveProgress.java
File was created 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 }
507
libs/common/src/main/java/com/littlejie/circleprogress/utils/Constant.java
File was created 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 }
27
libs/common/src/main/java/com/littlejie/circleprogress/utils/MiscUtil.java
File was created 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 }
libs/common/src/main/res/values/attrs_circle_progress.xml
File was created 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>